Skip to content

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 scan
nmap -sV -sC -p110,143,993,995 <target>
# 2. Plaintext IMAP login + folder list
curl -k 'imap://<target>' --user 'user:password'
# 3. TLS IMAP / POP3 interaction
openssl s_client -connect <target>:imaps # IMAP-over-TLS, port 993
openssl 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 1

Success indicator: successful login (LOGIN OK for IMAP, +OK for POP3), folder listing returned, mail body content retrieved.

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.

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.

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.

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/passwd and PAM by default; LDAP/SQL/Kerberos optional
  • mail_location controls where mailboxes live on disk (Maildir under /home/<user>/Maildir/ is the typical default)
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).

Terminal window
sudo nmap 10.0.14.128 -sV -p110,143,993,995 -sC
PORT STATE SERVICE VERSION
110/tcp open pop3 Dovecot pop3d
|_pop3-capabilities: AUTH-RESP-CODE SASL STLS TOP UIDL RESP-CODES CAPA PIPELINING
| ssl-cert: Subject: commonName=mail1.example.local/organizationName=Example/
stateOrProvinceName=California/countryName=US
| Not valid before: 2021-09-19T19:44:58
|_Not valid after: 2295-07-04T19:44:58
143/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 IMAP4rev1
993/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 IMAP4rev1
995/tcp open ssl/pop3 Dovecot pop3d

What’s in the output:

  • Dovecot identified on all four ports - known daemon, look up version-specific CVEs
  • AUTH=PLAIN is in the IMAPS capabilities - plain-text auth is permitted on the TLS-wrapped channel (which is fine because TLS protects the wire)
  • LOGINDISABLED on plaintext IMAP - plain LOGIN is rejected on 143 until STARTTLS is performed
  • STLS (the POP3 equivalent of STARTTLS) is advertised on 110
  • Cert subject reveals commonName=mail1.example.local - the internal hostname
Terminal window
curl -k 'imaps://10.0.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:

Terminal window
curl -k 'imaps://10.0.14.128' --user jdoe:1234 -v
* Trying 10.0.14.128:993...
* Connected to 10.0.14.128 (10.0.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=Example; OU=Customer Support;
CN=mail1.example.local; [email protected]
< * OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN]
Example 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:

Terminal window
curl -k 'pop3s://10.0.14.128' --user 'user:p4ssw0rd'

Lists message IDs and sizes. To fetch a specific message:

Terminal window
curl -k 'pop3s://10.0.14.128/1' --user 'user:p4ssw0rd' # message 1

To list folders / fetch via IMAP:

Terminal window
curl -k 'imaps://10.0.14.128/INBOX' --user 'user:p4ssw0rd' # folder content
curl -k 'imaps://10.0.14.128/INBOX;UID=5' --user 'user:p4ssw0rd' # message UID 5
curl -k 'imaps://10.0.14.128/INBOX;UID=5;SECTION=TEXT' --user '...' # just the body
Terminal window
openssl s_client -connect 10.0.14.128:imaps -quiet
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN]
Example IMAP4 v.0.21.4
a1 LOGIN jdoe 1234
a1 OK Logged in
a2 LIST "" *
* LIST (\HasNoChildren) "." Important
* LIST (\HasNoChildren) "." INBOX
a2 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 UID
a3 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}
Subject: Welcome
Date: Wed, 22 Sep 2021 12:00:00 +0200
)
a4 OK Fetch completed.
a5 FETCH 1 BODY[TEXT]
* 1 FETCH (BODY[TEXT] {198}
Hi jdoe,
Welcome to the team. Your initial password is hunter2.
Please change it on first login at https://portal.example.local/
- Admin
)
a5 OK Fetch completed.
a6 LOGOUT
* BYE Logging out
a6 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.

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
Terminal window
openssl s_client -connect 10.0.14.128:pop3s -quiet
+OK Example POP3 Server
USER jdoe
+OK
PASS hunter2
+OK Logged in.
STAT
+OK 12 24576 # 12 messages, total 24576 bytes
LIST
+OK 12 messages:
1 2048
2 4096
3 2048
...
.
RETR 1
+OK 2048 octets
Return-Path: <[email protected]>
Subject: Welcome
...
Hi jdoe, your initial password is hunter2 ...
.
QUIT
+OK Logging out.
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

When you have a username list and want to try common passwords:

Terminal window
hydra -L users.txt -P passwords.txt imap://10.0.14.128
hydra -L users.txt -P passwords.txt pop3://10.0.14.128
# Or against TLS-wrapped variants
hydra -L users.txt -P passwords.txt imaps://10.0.14.128
hydra -L users.txt -P passwords.txt pop3s://10.0.14.128

Or with Metasploit:

Terminal window
msfconsole
> use auxiliary/scanner/imap/imap_login
> set RHOSTS 10.0.14.128
> set USER_FILE users.txt
> set PASS_FILE passwords.txt
> set BLANK_PASSWORDS true
> run

Be 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.

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.

SMTP user enum → IMAP cred-test:

  1. Use SMTP VRFY/RCPT to enumerate valid usernames (see SMTP)
  2. Hydra password-spray those usernames against IMAP
  3. Successful login → read mailbox

Credentialed mailbox access → internal recon:

  1. Login to user’s mailbox
  2. Search for internal links, VPN setup emails, system credentials in old mail
  3. Use found intel to expand the engagement (new hosts, new creds, new apps)

Header analysis → infrastructure map:

  1. Any mail you can read includes Received: chain
  2. Internal hostnames and IPs leak in those chains
  3. Add to target inventory

Mail-content credentials → privilege escalation:

  1. Search inbox for “password”, “credentials”, “login”
  2. Initial-password emails from onboarding flows often contain reusable defaults
  3. Welcome emails from third-party SaaS reveal which platforms the user has accounts on
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