IMAP & POP3
Where SMTP sends mail, IMAP and POP3 retrieve it. Both are user-authenticated mailbox-access protocols. POP3 is simple - fetch and (usually) delete. IMAP is richer - supports server-side folders, search, and concurrent client access. Both default to plaintext, both have TLS variants. The operator-relevant work: cred-test against valid usernames, list/read mailboxes when you have creds, check for anonymous-binding misconfigs.
# 1. Service scannmap -sV -sC -p110,143,993,995 <target>
# 2. Plaintext IMAP login + folder listcurl -k 'imap://<target>' --user 'user:password'
# 3. TLS IMAP / POP3 interactionopenssl s_client -connect <target>:imaps # IMAP-over-TLS, port 993openssl s_client -connect <target>:pop3s # POP3-over-TLS, port 995
# 4. Manually fetch via IMAP> a1 LOGIN user password> a2 LIST "" *> a3 SELECT INBOX> a4 FETCH 1 BODY[TEXT]
# 5. Manually fetch via POP3> USER user> PASS password> LIST> RETR 1Success indicator: successful login (LOGIN OK for IMAP, +OK for POP3), folder listing returned, mail body content retrieved.
Protocol overview
Section titled “Protocol overview”POP3 (Post Office Protocol v3)
Section titled “POP3 (Post Office Protocol v3)”| Aspect | Detail |
|---|---|
| Port | TCP 110 (plaintext), TCP 995 (TLS-wrapped) |
| Model | Client downloads mail from server, optionally deletes after |
| State | Stateless - no concept of folders, flags, or shared state across clients |
| Use | Single-device personal mail (declining; mostly seen in legacy setups) |
POP3 is intentionally minimal. The protocol has about a dozen commands and assumes one client owns the mailbox.
IMAP (Internet Message Access Protocol)
Section titled “IMAP (Internet Message Access Protocol)”| Aspect | Detail |
|---|---|
| Port | TCP 143 (plaintext), TCP 993 (TLS-wrapped) |
| Model | Server holds mail; clients view/manipulate via server-side state |
| State | Folders, message flags (read/unread/flagged), client-side cache invalidation, supports multiple concurrent sessions |
| Use | Modern multi-device mail clients, webmail backends |
IMAP commands are prefixed with a tag (a client-chosen string) so the client can match responses to commands in a pipelined session. By convention the tag is a1, a2, … or A001, A002, … - it doesn’t matter what string you use, the server just echoes it back.
Encryption
Section titled “Encryption”Both protocols can be wrapped in TLS:
- POP3S on port 995 - TLS-from-start
- IMAPS on port 993 - TLS-from-start
- STARTTLS on the plaintext ports (110/143) - upgrade an existing connection
Modern Dovecot and similar daemons commonly require STARTTLS before allowing LOGIN even on the plaintext port, to prevent credential exposure.
Default configuration - Dovecot
Section titled “Default configuration - Dovecot”Dovecot is the most common Linux IMAP/POP3 daemon. Configuration is sprawling - many files under /etc/dovecot/conf.d/. The full settings are documented in the Dovecot core settings and service configuration pages.
Operator-relevant defaults:
- Plaintext authentication usually disabled (must STARTTLS first)
- Login on TLS ports always allowed
- Authentication backed by
/etc/passwdand PAM by default; LDAP/SQL/Kerberos optional mail_locationcontrols where mailboxes live on disk (Maildir under/home/<user>/Maildir/is the typical default)
Dangerous settings
Section titled “Dangerous settings”| Setting | What it enables |
|---|---|
auth_debug = yes | Verbose auth logging - useful for the admin, useful for you if you can read logs |
auth_debug_passwords = yes | Logs submitted passwords in plaintext - if you can read logs (e.g. via LFI or RCE elsewhere), you harvest credentials |
auth_verbose = yes | Logs unsuccessful auth attempts with reason - distinguishes “user doesn’t exist” from “bad password” |
auth_verbose_passwords = yes | Logs auth passwords (possibly truncated) |
auth_anonymous_username = <user> | Maps the SASL ANONYMOUS mechanism to a real user account - anonymous binding = login as that user |
| Plaintext login allowed (no STARTTLS requirement) | Credentials cross the wire in plaintext, sniffable from anywhere on-path |
| Self-signed cert + clients that don’t validate | Trivially MITM-able |
The two big findings are auth_debug_passwords = yes (creates a credential log you can harvest if you have file-read on the server) and auth_anonymous_username (turns SASL ANONYMOUS into login-as-something).
Footprinting commands
Section titled “Footprinting commands”Service scan
Section titled “Service scan”sudo nmap 10.129.14.128 -sV -p110,143,993,995 -sCPORT STATE SERVICE VERSION110/tcp open pop3 Dovecot pop3d|_pop3-capabilities: AUTH-RESP-CODE SASL STLS TOP UIDL RESP-CODES CAPA PIPELINING| ssl-cert: Subject: commonName=mail1.inlanefreight.htb/organizationName=Inlanefreight/ stateOrProvinceName=California/countryName=US| Not valid before: 2021-09-19T19:44:58|_Not valid after: 2295-07-04T19:44:58143/tcp open imap Dovecot imapd|_imap-capabilities: more have post-login STARTTLS Pre-login LITERAL+ LOGIN-REFERRALS OK LOGINDISABLEDA0001 SASL-IR ENABLE listed IDLE ID IMAP4rev1993/tcp open ssl/imap Dovecot imapd|_imap-capabilities: more have post-login OK LITERAL+ LOGIN-REFERRALS Pre-login AUTH=PLAINA0001 SASL-IR ENABLE listed IDLE ID IMAP4rev1995/tcp open ssl/pop3 Dovecot pop3dWhat’s in the output:
- Dovecot identified on all four ports - known daemon, look up version-specific CVEs
AUTH=PLAINis in the IMAPS capabilities - plain-text auth is permitted on the TLS-wrapped channel (which is fine because TLS protects the wire)LOGINDISABLEDon plaintext IMAP - plainLOGINis rejected on 143 until STARTTLS is performedSTLS(the POP3 equivalent of STARTTLS) is advertised on 110- Cert subject reveals
commonName=mail1.inlanefreight.htb- the internal hostname
Credentialed login with curl
Section titled “Credentialed login with curl”curl -k 'imaps://10.129.14.128' --user user:p4ssw0rd-k accepts self-signed certs. If the creds work, you get a folder listing:
* LIST (\HasNoChildren) "." Important* LIST (\HasNoChildren) "." INBOX--verbose shows the protocol exchange:
curl -k 'imaps://10.129.14.128' --user cry0l1t3:1234 -v* Trying 10.129.14.128:993...* Connected to 10.129.14.128 (10.129.14.128) port 993 (#0)* TLSv1.3 (OUT), TLS handshake, Client hello (1):...* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384* Server certificate:* subject: C=US; ST=California; L=Sacramento; O=Inlanefreight; OU=Customer Support; CN=mail1.inlanefreight.htb; [email protected]< * OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN] HTB-Academy IMAP4 v.0.21.4> A001 CAPABILITY< * CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN< A001 OK Pre-login capabilities listed, post-login capabilities have more.> A002 AUTHENTICATE PLAIN AGNyeTBsMXQzADEyMzQ=< * CAPABILITY ... LITERAL+ NOTIFY SPECIAL-USE< A002 OK Logged in> A003 LIST "" *< * LIST (\HasNoChildren) "." Important< * LIST (\HasNoChildren) "." INBOX< A003 OK List completed (0.001 + 0.000 secs).The verbose output gives you:
- TLS version and cipher (useful intel for compliance reporting and downgrade attacks)
- Pre-login capabilities (what’s available without auth)
- Post-login capabilities (often more features - SORT, THREAD, MOVE, BINARY, etc.)
- The base64-encoded credential exchange (decode it to confirm credentials made it through unmodified)
For POP3:
curl -k 'pop3s://10.129.14.128' --user 'user:p4ssw0rd'Lists message IDs and sizes. To fetch a specific message:
curl -k 'pop3s://10.129.14.128/1' --user 'user:p4ssw0rd' # message 1To list folders / fetch via IMAP:
curl -k 'imaps://10.129.14.128/INBOX' --user 'user:p4ssw0rd' # folder contentcurl -k 'imaps://10.129.14.128/INBOX;UID=5' --user 'user:p4ssw0rd' # message UID 5curl -k 'imaps://10.129.14.128/INBOX;UID=5;SECTION=TEXT' --user '...' # just the bodyManual IMAP via openssl
Section titled “Manual IMAP via openssl”openssl s_client -connect 10.129.14.128:imaps -quiet* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN] HTB-Academy IMAP4 v.0.21.4
a1 LOGIN cry0l1t3 1234a1 OK Logged in
a2 LIST "" ** LIST (\HasNoChildren) "." Important* LIST (\HasNoChildren) "." INBOXa2 OK List completed (0.001 + 0.000 secs).
a3 SELECT INBOX* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.* 12 EXISTS* 0 RECENT* OK [UIDVALIDITY 1632081604] UIDs valid* OK [UIDNEXT 13] Predicted next UIDa3 OK [READ-WRITE] Select completed (0.001 + 0.000 secs).
a4 FETCH 1 BODY[HEADER.FIELDS (FROM TO SUBJECT DATE)]* 1 FETCH (BODY[HEADER.FIELDS (FROM TO SUBJECT DATE)] {142}From: <[email protected]>To: <[email protected]>Subject: WelcomeDate: Wed, 22 Sep 2021 12:00:00 +0200
)a4 OK Fetch completed.
a5 FETCH 1 BODY[TEXT]* 1 FETCH (BODY[TEXT] {198}Hi cry0l1t3,Welcome to the team. Your initial password is hunter2.Please change it on first login at https://portal.inlanefreight.htb/
- Admin)a5 OK Fetch completed.
a6 LOGOUT* BYE Logging outa6 OK Logout completed.That last fetch - hunter2 as an initial password - is the kind of mail-content finding that makes IMAP enumeration worthwhile. Welcome emails, password reset confirmations, internal portal links, vendor invoices with embedded contracts - once you have credentials, mailbox content is high-density intel.
IMAP command quick reference
Section titled “IMAP command quick reference”| Command | Purpose |
|---|---|
a1 LOGIN <user> <pass> | Authenticate |
a1 LIST "" * | List all folders/mailboxes |
a1 LSUB "" * | List subscribed folders (a subset of LIST) |
a1 SELECT INBOX | Choose a folder for subsequent operations |
a1 EXAMINE INBOX | Read-only SELECT (won’t mark anything as read) |
a1 STATUS INBOX (MESSAGES UNSEEN) | Folder stats without selecting |
a1 SEARCH ALL | Get all message numbers |
a1 SEARCH FROM "[email protected]" | Search for messages matching criteria |
a1 SEARCH SUBJECT "password" | Subject-line search |
a1 FETCH N ALL | Get headers + flags for message N |
a1 FETCH N BODY[] | Full message |
a1 FETCH N BODY[HEADER] | Just headers |
a1 FETCH N BODY[TEXT] | Just body |
a1 FETCH 1:* (FLAGS BODY[HEADER.FIELDS (SUBJECT FROM)]) | All messages, just subject/from |
a1 STORE N +FLAGS \Seen | Mark as read (and other flag manipulations) |
a1 COPY N "Archive" | Copy to another folder |
a1 CLOSE | Close current folder (expunges deleted) |
a1 LOGOUT | End session |
Manual POP3 via openssl
Section titled “Manual POP3 via openssl”openssl s_client -connect 10.129.14.128:pop3s -quiet+OK HTB-Academy POP3 Server
USER cry0l1t3+OK
PASS hunter2+OK Logged in.
STAT+OK 12 24576 # 12 messages, total 24576 bytes
LIST+OK 12 messages:1 20482 40963 2048....
RETR 1+OK 2048 octetsReturn-Path: <[email protected]>From: <[email protected]>To: <[email protected]>Subject: Welcome...
Hi cry0l1t3, your initial password is hunter2 ....
QUIT+OK Logging out.POP3 command quick reference
Section titled “POP3 command quick reference”| Command | Purpose |
|---|---|
USER <name> | Username |
PASS <pass> | Password |
STAT | Message count and total size |
LIST | List all messages with sizes |
LIST N | Size of message n |
UIDL | List with persistent unique IDs (instead of session-local sequence) |
RETR N | Retrieve message n |
DELE N | Mark message n for deletion (executed on QUIT) |
RSET | Cancel any DELEs in this session |
TOP N COUNT | Headers + first N lines of message n |
CAPA | List server capabilities |
STLS | Start TLS upgrade (on plaintext port 110) |
QUIT | End session, commit DELEs |
Brute-force / credential testing
Section titled “Brute-force / credential testing”When you have a username list and want to try common passwords:
hydra -L users.txt -P passwords.txt imap://10.129.14.128hydra -L users.txt -P passwords.txt pop3://10.129.14.128
# Or against TLS-wrapped variantshydra -L users.txt -P passwords.txt imaps://10.129.14.128hydra -L users.txt -P passwords.txt pop3s://10.129.14.128Or with Metasploit:
msfconsole> use auxiliary/scanner/imap/imap_login> set RHOSTS 10.129.14.128> set USER_FILE users.txt> set PASS_FILE passwords.txt> set BLANK_PASSWORDS true> runBe aware: many mail servers throttle aggressively on auth failures. Some integrate with fail2ban or similar. Track latency - sudden 5-10x slowdown often means you’ve been rate-limited.
Looking for AUTH ANONYMOUS
Section titled “Looking for AUTH ANONYMOUS”a1 AUTHENTICATE ANONYMOUS+[base64-encoded empty or arbitrary string here]If the server has SASL ANONYMOUS enabled with auth_anonymous_username mapped to a real account, you log in as that account without creds. Test by:
a1 CAPABILITY< * CAPABILITY ... AUTH=PLAIN AUTH=LOGIN AUTH=ANONYMOUS ...If AUTH=ANONYMOUS appears in the capabilities list, give it a try.
Common chained workflows
Section titled “Common chained workflows”SMTP user enum → IMAP cred-test:
- Use SMTP VRFY/RCPT to enumerate valid usernames (see SMTP)
- Hydra password-spray those usernames against IMAP
- Successful login → read mailbox
Credentialed mailbox access → internal recon:
- Login to user’s mailbox
- Search for internal links, VPN setup emails, system credentials in old mail
- Use found intel to expand the engagement (new hosts, new creds, new apps)
Header analysis → infrastructure map:
- Any mail you can read includes
Received:chain - Internal hostnames and IPs leak in those chains
- Add to target inventory
Mail-content credentials → privilege escalation:
- Search inbox for “password”, “credentials”, “login”
- Initial-password emails from onboarding flows often contain reusable defaults
- Welcome emails from third-party SaaS reveal which platforms the user has accounts on
Quick reference
Section titled “Quick reference”| Task | Command |
|---|---|
| Service scan | nmap -sV -sC -p110,143,993,995 <target> |
| Curl IMAPS login | curl -k 'imaps://<target>' --user 'user:pass' |
| Curl POP3S login | curl -k 'pop3s://<target>' --user 'user:pass' |
| Curl fetch folder | curl -k 'imaps://<target>/INBOX' --user 'user:pass' |
| Curl fetch message | curl -k 'imaps://<target>/INBOX;UID=5' --user 'user:pass' |
| Manual IMAPS | openssl s_client -connect <target>:imaps |
| Manual POP3S | openssl s_client -connect <target>:pop3s |
| IMAP login | a1 LOGIN <user> <pass> |
| IMAP list folders | a1 LIST "" * |
| IMAP select & fetch | a1 SELECT INBOX then a1 FETCH 1 BODY[TEXT] |
| POP3 login | USER <name> + PASS <pass> |
| POP3 retrieve | RETR N |
| Hydra IMAP | hydra -L users -P pass imap://<target> |
| Metasploit | use auxiliary/scanner/imap/imap_login |