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.

AspectDetail
PortTCP 110 (plaintext), TCP 995 (TLS-wrapped)
ModelClient downloads mail from server, optionally deletes after
StateStateless - no concept of folders, flags, or shared state across clients
UseSingle-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.

AspectDetail
PortTCP 143 (plaintext), TCP 993 (TLS-wrapped)
ModelServer holds mail; clients view/manipulate via server-side state
StateFolders, message flags (read/unread/flagged), client-side cache invalidation, supports multiple concurrent sessions
UseModern 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)
SettingWhat it enables
auth_debug = yesVerbose auth logging - useful for the admin, useful for you if you can read logs
auth_debug_passwords = yesLogs submitted passwords in plaintext - if you can read logs (e.g. via LFI or RCE elsewhere), you harvest credentials
auth_verbose = yesLogs unsuccessful auth attempts with reason - distinguishes “user doesn’t exist” from “bad password”
auth_verbose_passwords = yesLogs 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 validateTrivially 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.129.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.inlanefreight.htb/organizationName=Inlanefreight/
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.inlanefreight.htb - the internal hostname
Terminal window
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:

Terminal window
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:

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

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

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

To list folders / fetch via IMAP:

Terminal window
curl -k 'imaps://10.129.14.128/INBOX' --user 'user:p4ssw0rd' # folder content
curl -k 'imaps://10.129.14.128/INBOX;UID=5' --user 'user:p4ssw0rd' # message UID 5
curl -k 'imaps://10.129.14.128/INBOX;UID=5;SECTION=TEXT' --user '...' # just the body
Terminal window
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 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 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 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.

CommandPurpose
a1 LOGIN <user> <pass>Authenticate
a1 LIST "" *List all folders/mailboxes
a1 LSUB "" *List subscribed folders (a subset of LIST)
a1 SELECT INBOXChoose a folder for subsequent operations
a1 EXAMINE INBOXRead-only SELECT (won’t mark anything as read)
a1 STATUS INBOX (MESSAGES UNSEEN)Folder stats without selecting
a1 SEARCH ALLGet all message numbers
a1 SEARCH FROM "[email protected]"Search for messages matching criteria
a1 SEARCH SUBJECT "password"Subject-line search
a1 FETCH N ALLGet 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 \SeenMark as read (and other flag manipulations)
a1 COPY N "Archive"Copy to another folder
a1 CLOSEClose current folder (expunges deleted)
a1 LOGOUTEnd session
Terminal window
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 2048
2 4096
3 2048
...
.
RETR 1
+OK 2048 octets
Return-Path: <[email protected]>
Subject: Welcome
...
Hi cry0l1t3, your initial password is hunter2 ...
.
QUIT
+OK Logging out.
CommandPurpose
USER <name>Username
PASS <pass>Password
STATMessage count and total size
LISTList all messages with sizes
LIST NSize of message n
UIDLList with persistent unique IDs (instead of session-local sequence)
RETR NRetrieve message n
DELE NMark message n for deletion (executed on QUIT)
RSETCancel any DELEs in this session
TOP N COUNTHeaders + first N lines of message n
CAPAList server capabilities
STLSStart TLS upgrade (on plaintext port 110)
QUITEnd 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.129.14.128
hydra -L users.txt -P passwords.txt pop3://10.129.14.128
# Or against TLS-wrapped variants
hydra -L users.txt -P passwords.txt imaps://10.129.14.128
hydra -L users.txt -P passwords.txt pop3s://10.129.14.128

Or with Metasploit:

Terminal window
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
> 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
TaskCommand
Service scannmap -sV -sC -p110,143,993,995 <target>
Curl IMAPS logincurl -k 'imaps://<target>' --user 'user:pass'
Curl POP3S logincurl -k 'pop3s://<target>' --user 'user:pass'
Curl fetch foldercurl -k 'imaps://<target>/INBOX' --user 'user:pass'
Curl fetch messagecurl -k 'imaps://<target>/INBOX;UID=5' --user 'user:pass'
Manual IMAPSopenssl s_client -connect <target>:imaps
Manual POP3Sopenssl s_client -connect <target>:pop3s
IMAP logina1 LOGIN <user> <pass>
IMAP list foldersa1 LIST "" *
IMAP select & fetcha1 SELECT INBOX then a1 FETCH 1 BODY[TEXT]
POP3 loginUSER <name> + PASS <pass>
POP3 retrieveRETR N
Hydra IMAPhydra -L users -P pass imap://<target>
Metasploituse auxiliary/scanner/imap/imap_login