ctf-agent 1.2.0

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.
Files changed (152) hide show
  1. package/AGENTS.md +131 -0
  2. package/Dockerfile +192 -0
  3. package/README.md +522 -0
  4. package/agents/ctf-analyzer.md +58 -0
  5. package/agents/ctf-controller.md +151 -0
  6. package/agents/ctf-speedrun.md +74 -0
  7. package/bin/ctf-agent.js +119 -0
  8. package/docker-compose.yml +13 -0
  9. package/mcp_config.json +19 -0
  10. package/package.json +44 -0
  11. package/references/ctf-triage-ladder.md +68 -0
  12. package/references/exploit-databases.md +575 -0
  13. package/references/llm-safety-and-policy-compliance.md +173 -0
  14. package/references/multi-agent-orchestration-and-policy-routing.md +278 -0
  15. package/references/security-events-and-intelligence.md +566 -0
  16. package/references/version-matrix.md +59 -0
  17. package/rules/ctf-execution-rules.md +44 -0
  18. package/rules/ctf-safety-framing-rules.md +140 -0
  19. package/rules/flag-validation-rules.md +25 -0
  20. package/scripts/__init__.py +1 -0
  21. package/scripts/ctf-tools.lock +205 -0
  22. package/scripts/ctf_init.py +1026 -0
  23. package/scripts/ctf_update.py +583 -0
  24. package/scripts/ctfd_client.py +81 -0
  25. package/scripts/cve_lookup.py +453 -0
  26. package/scripts/extract_flags.py +155 -0
  27. package/scripts/install_as_agent.py +278 -0
  28. package/scripts/install_ctf_tools.sh +603 -0
  29. package/scripts/parallel_triage.py +395 -0
  30. package/scripts/prompt_policy_sanitizer.py +283 -0
  31. package/scripts/scope_guard.py +444 -0
  32. package/scripts/skill_validator.py +504 -0
  33. package/scripts/workspace_cleaner.py +141 -0
  34. package/skills/ctf-ai-ml/SKILL.md +120 -0
  35. package/skills/ctf-ai-ml/adversarial-ml.md +623 -0
  36. package/skills/ctf-ai-ml/llm-attacks.md +487 -0
  37. package/skills/ctf-ai-ml/model-attacks.md +422 -0
  38. package/skills/ctf-crypto/SKILL.md +320 -0
  39. package/skills/ctf-crypto/advanced-math.md +798 -0
  40. package/skills/ctf-crypto/classic-ciphers.md +651 -0
  41. package/skills/ctf-crypto/ecc-attacks.md +347 -0
  42. package/skills/ctf-crypto/exotic-crypto-2.md +380 -0
  43. package/skills/ctf-crypto/exotic-crypto.md +528 -0
  44. package/skills/ctf-crypto/historical.md +113 -0
  45. package/skills/ctf-crypto/lattice-and-lwe.md +524 -0
  46. package/skills/ctf-crypto/modern-ciphers-2.md +563 -0
  47. package/skills/ctf-crypto/modern-ciphers-3.md +453 -0
  48. package/skills/ctf-crypto/modern-ciphers.md +649 -0
  49. package/skills/ctf-crypto/prng-attacks.md +257 -0
  50. package/skills/ctf-crypto/prng.md +664 -0
  51. package/skills/ctf-crypto/rsa-attacks-2.md +792 -0
  52. package/skills/ctf-crypto/rsa-attacks.md +487 -0
  53. package/skills/ctf-crypto/stream-ciphers.md +390 -0
  54. package/skills/ctf-crypto/zkp-and-advanced.md +456 -0
  55. package/skills/ctf-forensics/3d-printing.md +121 -0
  56. package/skills/ctf-forensics/SKILL.md +379 -0
  57. package/skills/ctf-forensics/disk-advanced.md +497 -0
  58. package/skills/ctf-forensics/disk-and-memory.md +491 -0
  59. package/skills/ctf-forensics/disk-recovery.md +699 -0
  60. package/skills/ctf-forensics/linux-forensics.md +511 -0
  61. package/skills/ctf-forensics/network-advanced.md +583 -0
  62. package/skills/ctf-forensics/network.md +645 -0
  63. package/skills/ctf-forensics/peripheral-capture.md +287 -0
  64. package/skills/ctf-forensics/signals-and-hardware.md +713 -0
  65. package/skills/ctf-forensics/steganography.md +694 -0
  66. package/skills/ctf-forensics/stego-advanced-2.md +475 -0
  67. package/skills/ctf-forensics/stego-advanced.md +481 -0
  68. package/skills/ctf-forensics/stego-image.md +691 -0
  69. package/skills/ctf-forensics/windows.md +625 -0
  70. package/skills/ctf-malware/SKILL.md +181 -0
  71. package/skills/ctf-malware/c2-and-protocols.md +274 -0
  72. package/skills/ctf-malware/pe-and-dotnet.md +108 -0
  73. package/skills/ctf-malware/scripts-and-obfuscation.md +449 -0
  74. package/skills/ctf-misc/SKILL.md +498 -0
  75. package/skills/ctf-misc/bashjails.md +323 -0
  76. package/skills/ctf-misc/ctfd-navigation.md +465 -0
  77. package/skills/ctf-misc/dns.md +255 -0
  78. package/skills/ctf-misc/encodings-advanced.md +504 -0
  79. package/skills/ctf-misc/encodings.md +431 -0
  80. package/skills/ctf-misc/games-and-vms-2.md +254 -0
  81. package/skills/ctf-misc/games-and-vms-3.md +690 -0
  82. package/skills/ctf-misc/games-and-vms-4.md +229 -0
  83. package/skills/ctf-misc/games-and-vms.md +529 -0
  84. package/skills/ctf-misc/linux-privesc.md +333 -0
  85. package/skills/ctf-misc/pyjails.md +671 -0
  86. package/skills/ctf-misc/rf-sdr.md +91 -0
  87. package/skills/ctf-osint/SKILL.md +198 -0
  88. package/skills/ctf-osint/geolocation-and-media.md +464 -0
  89. package/skills/ctf-osint/social-media.md +312 -0
  90. package/skills/ctf-osint/web-and-dns.md +341 -0
  91. package/skills/ctf-pwn/SKILL.md +214 -0
  92. package/skills/ctf-pwn/advanced-exploits-2.md +579 -0
  93. package/skills/ctf-pwn/advanced-exploits-3.md +598 -0
  94. package/skills/ctf-pwn/advanced-exploits-4.md +590 -0
  95. package/skills/ctf-pwn/advanced-exploits-5.md +119 -0
  96. package/skills/ctf-pwn/advanced-exploits.md +773 -0
  97. package/skills/ctf-pwn/advanced.md +326 -0
  98. package/skills/ctf-pwn/field-notes.md +245 -0
  99. package/skills/ctf-pwn/format-string.md +694 -0
  100. package/skills/ctf-pwn/heap-fsop.md +285 -0
  101. package/skills/ctf-pwn/heap-techniques-2.md +333 -0
  102. package/skills/ctf-pwn/heap-techniques.md +513 -0
  103. package/skills/ctf-pwn/kernel-bypass.md +421 -0
  104. package/skills/ctf-pwn/kernel-techniques.md +366 -0
  105. package/skills/ctf-pwn/kernel.md +636 -0
  106. package/skills/ctf-pwn/overflow-basics.md +611 -0
  107. package/skills/ctf-pwn/rop-advanced.md +725 -0
  108. package/skills/ctf-pwn/rop-and-shellcode.md +659 -0
  109. package/skills/ctf-pwn/sandbox-escape.md +313 -0
  110. package/skills/ctf-reverse/SKILL.md +163 -0
  111. package/skills/ctf-reverse/anti-analysis-ctf.md +204 -0
  112. package/skills/ctf-reverse/anti-analysis.md +693 -0
  113. package/skills/ctf-reverse/field-notes.md +376 -0
  114. package/skills/ctf-reverse/languages-compiled.md +666 -0
  115. package/skills/ctf-reverse/languages-platforms.md +592 -0
  116. package/skills/ctf-reverse/languages.md +553 -0
  117. package/skills/ctf-reverse/patterns-ctf-2.md +397 -0
  118. package/skills/ctf-reverse/patterns-ctf-3.md +797 -0
  119. package/skills/ctf-reverse/patterns-ctf.md +670 -0
  120. package/skills/ctf-reverse/patterns-runtime.md +274 -0
  121. package/skills/ctf-reverse/patterns.md +572 -0
  122. package/skills/ctf-reverse/platforms-hardware.md +387 -0
  123. package/skills/ctf-reverse/platforms.md +664 -0
  124. package/skills/ctf-reverse/tools-advanced-2.md +421 -0
  125. package/skills/ctf-reverse/tools-advanced.md +407 -0
  126. package/skills/ctf-reverse/tools-dynamic.md +679 -0
  127. package/skills/ctf-reverse/tools-emulation.md +319 -0
  128. package/skills/ctf-reverse/tools.md +573 -0
  129. package/skills/ctf-web/SKILL.md +153 -0
  130. package/skills/ctf-web/auth-and-access-2.md +82 -0
  131. package/skills/ctf-web/auth-and-access.md +783 -0
  132. package/skills/ctf-web/auth-infra.md +321 -0
  133. package/skills/ctf-web/auth-jwt.md +186 -0
  134. package/skills/ctf-web/client-side-advanced.md +739 -0
  135. package/skills/ctf-web/client-side.md +529 -0
  136. package/skills/ctf-web/cves.md +373 -0
  137. package/skills/ctf-web/field-notes.md +482 -0
  138. package/skills/ctf-web/node-and-prototype.md +200 -0
  139. package/skills/ctf-web/server-side-2.md +337 -0
  140. package/skills/ctf-web/server-side-advanced-2.md +559 -0
  141. package/skills/ctf-web/server-side-advanced-3.md +125 -0
  142. package/skills/ctf-web/server-side-advanced-4.md +480 -0
  143. package/skills/ctf-web/server-side-advanced.md +378 -0
  144. package/skills/ctf-web/server-side-deser.md +443 -0
  145. package/skills/ctf-web/server-side-exec-2.md +799 -0
  146. package/skills/ctf-web/server-side-exec.md +457 -0
  147. package/skills/ctf-web/server-side.md +629 -0
  148. package/skills/ctf-web/sql-injection.md +790 -0
  149. package/skills/ctf-web/web3.md +374 -0
  150. package/skills/ctf-writeup/SKILL.md +90 -0
  151. package/skills/solve-challenge/SKILL.md +269 -0
  152. package/skills.json +16 -0
@@ -0,0 +1,645 @@
1
+ # CTF Forensics - Network
2
+
3
+ ## Table of Contents
4
+ - [tcpdump Quick Reference](#tcpdump-quick-reference)
5
+ - [TLS/SSL Decryption via Keylog File](#tlsssl-decryption-via-keylog-file)
6
+ - [Wireshark Basics](#wireshark-basics)
7
+ - [Port Scan Analysis](#port-scan-analysis)
8
+ - [Gateway/Device via MAC OUI](#gatewaydevice-via-mac-oui)
9
+ - [WordPress Reconnaissance](#wordpress-reconnaissance)
10
+ - [Post-Exploitation Traffic](#post-exploitation-traffic)
11
+ - [Credential Extraction](#credential-extraction)
12
+ - [SMB3 Encrypted Traffic](#smb3-encrypted-traffic)
13
+ - [5G/NR Protocol Analysis](#5gnr-protocol-analysis)
14
+ - [Email Headers](#email-headers)
15
+ - [USB HID Stenography/Chord PCAP (UTCTF 2024)](#usb-hid-stenographychord-pcap-utctf-2024)
16
+ - [BCD Encoding in UDP (VuwCTF 2025)](#bcd-encoding-in-udp-vuwctf-2025)
17
+ - [HTTP File Upload Exfiltration in PCAP (MetaCTF 2026)](#http-file-upload-exfiltration-in-pcap-metactf-2026)
18
+ - [TLS Master Key Extraction from Coredump (PlaidCTF 2014)](#tls-master-key-extraction-from-coredump-plaidctf-2014)
19
+ - [Split Archive Reassembly from HTTP Transfers (ASIS CTF Finals 2013)](#split-archive-reassembly-from-http-transfers-asis-ctf-finals-2013)
20
+ - [WPA/WEP WiFi Decryption from PCAP (DefCamp CTF 2016)](#wpawep-wifi-decryption-from-pcap-defcamp-ctf-2016)
21
+ - [Corrupted PCAP Repair with pcapfix (CSAW CTF 2016)](#corrupted-pcap-repair-with-pcapfix-csaw-ctf-2016)
22
+ - [SAP Dialog Protocol Decryption from PCAP (GreHack CTF 2016)](#sap-dialog-protocol-decryption-from-pcap-grehack-ctf-2016)
23
+ - [DNS Exfiltration Oracle via Binary Response Probing (ASIS CTF Finals 2017)](#dns-exfiltration-oracle-via-binary-response-probing-asis-ctf-finals-2017)
24
+ - [ICMP Echo Payload Length as Covert Channel (TokyoWesterns CTF 4th 2018)](#icmp-echo-payload-length-as-covert-channel-tokyowesterns-ctf-4th-2018)
25
+
26
+ ---
27
+
28
+ ## tcpdump Quick Reference
29
+
30
+ Command-line packet capture tool for quick network forensics triage.
31
+
32
+ ```bash
33
+ # Basic capture on interface
34
+ sudo tcpdump -i eth0
35
+
36
+ # Capture to file
37
+ sudo tcpdump -i eth0 -w capture.pcap
38
+
39
+ # Filter by source IP
40
+ sudo tcpdump -i eth0 src 192.168.1.100
41
+
42
+ # Filter by destination port
43
+ sudo tcpdump -i eth0 dst port 80
44
+
45
+ # Combined filter with file output
46
+ sudo tcpdump -i eth0 -w packets.pcap 'src 172.22.206.250 and port 443'
47
+
48
+ # Read from file with verbose output
49
+ tcpdump -r capture.pcap -v
50
+
51
+ # Show packet contents in ASCII
52
+ tcpdump -r capture.pcap -A
53
+
54
+ # Show hex + ASCII dump
55
+ tcpdump -r capture.pcap -X
56
+
57
+ # Count total packets
58
+ tcpdump -r capture.pcap -q | wc -l
59
+ ```
60
+
61
+ **Common filters:**
62
+ | Filter | Description |
63
+ |--------|-------------|
64
+ | `host 10.0.0.1` | Traffic to/from IP |
65
+ | `net 192.168.1.0/24` | Entire subnet |
66
+ | `port 80` | HTTP traffic |
67
+ | `tcp` / `udp` / `icmp` | Protocol filter |
68
+ | `src host X and dst port Y` | Combined |
69
+
70
+ **Key insight:** Use tcpdump for quick command-line triage when Wireshark is unavailable. Pipe to `strings` or `grep` for fast flag hunting: `tcpdump -r capture.pcap -A | grep -i flag`.
71
+
72
+ ---
73
+
74
+ ## TLS/SSL Decryption via Keylog File
75
+
76
+ To decrypt TLS traffic in Wireshark, provide either the pre-master secret or a keylog file.
77
+
78
+ **Method 1 — SSLKEYLOGFILE (client-side key logging):**
79
+
80
+ If the challenge provides a keylog file (or you can set `SSLKEYLOGFILE`):
81
+ ```bash
82
+ # Set environment variable before running the client
83
+ export SSLKEYLOGFILE=/tmp/sslkeys.log
84
+ curl https://target/secret
85
+
86
+ # Import into Wireshark:
87
+ # Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log filename → /tmp/sslkeys.log
88
+ ```
89
+
90
+ **Keylog file format (NSS Key Log Format):**
91
+ ```text
92
+ CLIENT_RANDOM <32_bytes_client_random_hex> <48_bytes_master_secret_hex>
93
+ ```
94
+
95
+ **Method 2 — RSA private key (if server key is known):**
96
+
97
+ **Note:** Only works with RSA key exchange. Sessions using forward secrecy (ECDHE/DHE cipher suites) cannot be decrypted with the server's private key — use Method 1 instead. CTF challenges with weak RSA keys typically use RSA key exchange.
98
+
99
+ ```bash
100
+ # Wireshark: Edit → Preferences → Protocols → TLS → RSA keys list
101
+ # IP: 127.0.0.1, Port: 443, Protocol: http, Key File: server.key
102
+
103
+ # Or via tshark:
104
+ tshark -r capture.pcap -o "tls.keys_list:127.0.0.1,443,http,server.key" -Y http
105
+ ```
106
+
107
+ **Method 3 — Weak RSA key factoring (see also linux-forensics.md):**
108
+ ```bash
109
+ # Extract certificate from PCAP
110
+ tshark -r capture.pcap -Y "tls.handshake.type==11" -T fields -e tls.handshake.certificate | head -1
111
+
112
+ # Factor weak modulus, generate private key with rsatool
113
+ python rsatool.py -p <p> -q <q> -e 65537 -o server.key
114
+
115
+ # Import key into Wireshark
116
+ ```
117
+
118
+ **SSL handshake components needed for decryption:**
119
+ 1. `client_random` — sent in ClientHello
120
+ 2. `server_random` — sent in ServerHello
121
+ 3. Pre-master secret (PMS) — encrypted in ClientKeyExchange with server's RSA public key
122
+
123
+ **Key insight:** Look for keylog files (`.log`, `sslkeys.txt`) in challenge artifacts. If the challenge gives you a private key, use it directly. For weak RSA keys in certificates, factor the modulus to derive the private key.
124
+
125
+ ---
126
+
127
+ ## Wireshark Basics
128
+
129
+ ```bash
130
+ # Filters
131
+ http.request.method == "POST"
132
+ tcp.stream eq 5
133
+ frame contains "flag"
134
+
135
+ # Export files
136
+ File → Export Objects → HTTP
137
+
138
+ # tshark
139
+ tshark -r capture.pcap -Y "http" -T fields -e http.file_data
140
+ tshark -r capture.pcap --export-objects http,/tmp/http_objects
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Port Scan Analysis
146
+
147
+ ```bash
148
+ # IP conversation statistics
149
+ tshark -r capture.pcap -q -z conv,ip
150
+
151
+ # Find open ports (SYN-ACK responses)
152
+ tshark -r capture.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==1" \
153
+ -T fields -e ip.src -e tcp.srcport | sort -u
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Gateway/Device via MAC OUI
159
+
160
+ ```bash
161
+ # Extract MAC addresses
162
+ tshark -r capture.pcap -Y "arp" -T fields \
163
+ -e arp.src.hw_mac -e arp.src.proto_ipv4 | sort -u
164
+
165
+ # Vendor lookup
166
+ curl -s "https://macvendors.com/query/88:bd:09"
167
+ ```
168
+
169
+ ---
170
+
171
+ ## WordPress Reconnaissance
172
+
173
+ **Identify WPScan:**
174
+ ```bash
175
+ tshark -r capture.pcap -Y "http.user_agent contains \"WPScan\"" | head -1
176
+ ```
177
+
178
+ **WordPress version:**
179
+ ```bash
180
+ cat /tmp/http_objects/feed* | grep -i generator
181
+ ```
182
+
183
+ **Plugins:**
184
+ ```bash
185
+ tshark -r capture.pcap \
186
+ -Y "http.response.code == 200 && http.request.uri contains \"wp-content/plugins\"" \
187
+ -T fields -e http.request.uri | sort -u
188
+ ```
189
+
190
+ **Usernames (REST API):**
191
+ ```bash
192
+ cat /tmp/http_objects/*per_page* | jq '.[].name'
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Post-Exploitation Traffic
198
+
199
+ **Step 1: TCP conversations**
200
+ ```bash
201
+ tshark -r capture.pcap -q -z conv,tcp
202
+ ```
203
+
204
+ **Step 2: Established connections (SYN-ACK)**
205
+ ```bash
206
+ tshark -r capture.pcap -Y "tcp.flags.syn == 1 and tcp.flags.ack == 1" \
207
+ -T fields -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport | sort -u
208
+ ```
209
+
210
+ **Step 3: Follow TCP stream**
211
+ ```bash
212
+ tshark -r capture.pcap -q -z "follow,tcp,ascii,<stream_number>"
213
+ ```
214
+
215
+ **Reverse shell indicators:**
216
+ - `bash: cannot set terminal process group`
217
+ - `bash: no job control in this shell`
218
+ - Shell prompts like `www-data@hostname:/path$`
219
+
220
+ ---
221
+
222
+ ## Credential Extraction
223
+
224
+ **High-value files:**
225
+ | Application | File | Format |
226
+ |-------------|------|--------|
227
+ | WordPress | `wp-config.php` | `define('DB_PASSWORD', '...')` |
228
+ | Laravel | `.env` | `DB_PASSWORD=` |
229
+ | MySQL | `/etc/mysql/debian.cnf` | `password = ` |
230
+
231
+ ```bash
232
+ # Search shell stream for credentials
233
+ tshark -r capture.pcap -q -z "follow,tcp,ascii,<stream>" | grep -i "password"
234
+ ```
235
+
236
+ ---
237
+
238
+ ## SMB3 Encrypted Traffic
239
+
240
+ **Step 1: Extract NTLMv2 hash**
241
+ ```bash
242
+ tshark -r capture.pcap -Y "ntlmssp.messagetype == 0x00000003" -T fields \
243
+ -e ntlmssp.ntlmv2_response.ntproofstr \
244
+ -e ntlmssp.auth.username
245
+ ```
246
+
247
+ **Step 2: Crack with hashcat**
248
+ ```bash
249
+ hashcat -m 5600 ntlmv2_hash.txt wordlist.txt
250
+ ```
251
+
252
+ **Step 3: Derive SMB 3.1.1 session keys (Python)**
253
+ ```python
254
+ from Cryptodome.Cipher import AES, ARC4
255
+ from Cryptodome.Hash import MD4
256
+ import hmac, hashlib
257
+
258
+ def SP800_108_Counter_KDF(Ki, Label, Context, L):
259
+ n = (L // 256) + 1
260
+ result = b''
261
+ for i in range(1, n + 1):
262
+ data = i.to_bytes(4, 'big') + Label + b'\x00' + Context + L.to_bytes(4, 'big')
263
+ result += hmac.new(Ki, data, hashlib.sha256).digest()
264
+ return result[:L // 8]
265
+
266
+ # Compute session key
267
+ nt_hash = MD4.new(password.encode('utf-16le')).digest()
268
+ response_key = hmac.new(nt_hash, (user.upper() + domain.upper()).encode('utf-16le'), hashlib.md5).digest()
269
+ key_exchange_key = hmac.new(response_key, ntproofstr, hashlib.md5).digest()
270
+ session_key = ARC4.new(key_exchange_key).encrypt(encrypted_session_key)
271
+
272
+ # Derive encryption keys
273
+ c2s_key = SP800_108_Counter_KDF(session_key, b"SMBC2SCipherKey\x00", preauth_hash, 128)
274
+ s2c_key = SP800_108_Counter_KDF(session_key, b"SMBS2CCipherKey\x00", preauth_hash, 128)
275
+ ```
276
+
277
+ **Step 4: Decrypt (AES-128-GCM)**
278
+ ```python
279
+ def decrypt_smb311(transform_data, key):
280
+ signature = transform_data[4:20]
281
+ nonce = transform_data[20:32]
282
+ aad = transform_data[20:52]
283
+ encrypted = transform_data[52:]
284
+
285
+ cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
286
+ cipher.update(aad)
287
+ return cipher.decrypt_and_verify(encrypted, signature)
288
+ ```
289
+
290
+ ---
291
+
292
+ ## 5G/NR Protocol Analysis
293
+
294
+ **Wireshark setup:**
295
+ - Enable: NAS-5GS, RLC-NR, PDCP-NR, MAC-NR
296
+
297
+ **SMS in 5G (3GPP TS 23.040):**
298
+
299
+ | IEI | Format |
300
+ |-----|--------|
301
+ | 0x0c | iMelody (ringtone) |
302
+ | 0x0e | Large Animation (16×16) |
303
+ | 0x18 | WVG (vector graphics) |
304
+
305
+ **iMelody to Morse:**
306
+ - Notes like `c4c4c4r2` encode dots/dashes
307
+
308
+ ---
309
+
310
+ ## Email Headers
311
+
312
+ - Check routing information
313
+ - Look for encoded attachments (base64)
314
+ - MIME boundaries may hide data
315
+
316
+ ---
317
+
318
+ ## USB HID Stenography/Chord PCAP (UTCTF 2024)
319
+
320
+ **Pattern (Gibberish):** USB keyboard PCAP with simultaneous multi-key presses = stenography chording.
321
+
322
+ **Detection:** Multiple simultaneous USB HID keys (6+ at once) in interrupt transfers. Not regular typing.
323
+
324
+ **Decoding workflow:**
325
+ 1. Extract HID reports from PCAP
326
+ 2. Detect simultaneous key states (multiple keycodes in same report)
327
+ 3. Map chords to Plover stenography dictionary
328
+ 4. Install Plover, use its dictionary for translation
329
+
330
+ ```bash
331
+ # Extract USB HID data
332
+ tshark -r capture.pcap -Y "usb.transfer_type == 1" -T fields -e usb.capdata
333
+ ```
334
+
335
+ ---
336
+
337
+ ## BCD Encoding in UDP (VuwCTF 2025)
338
+
339
+ **Pattern (1.5x-engineer):** "1.5x" hints at the encoding ratio.
340
+
341
+ **BCD (Binary-Coded Decimal):** Each nibble (4 bits) encodes one decimal digit (0-9). Two digits per byte vs one ASCII digit per byte → BCD is 2x denser than ASCII decimal. The "1.5x" name refers to the challenge-specific framing: 3 BCD bytes encode 6 digits which represent 2 ASCII bytes (3:2 ratio).
342
+
343
+ **Decoding:**
344
+ ```python
345
+ def bcd_decode(data):
346
+ result = ''
347
+ for byte in data:
348
+ high = (byte >> 4) & 0x0F
349
+ low = byte & 0x0F
350
+ result += f'{high}{low}'
351
+ return result
352
+
353
+ # UDP sessions differentiated by first byte
354
+ # Session 1 = BCD-encoded ASCII metadata with flag
355
+ # Session 2 = encrypted DOCX
356
+ ```
357
+
358
+ **Lesson:** Challenge name often hints at encoding ratio or technique.
359
+
360
+ ---
361
+
362
+ ## HTTP File Upload Exfiltration in PCAP (MetaCTF 2026)
363
+
364
+ **Pattern (Dead Drop):** Small PCAP with TCP streams containing HTTP traffic. Exfiltrated data uploaded as a file via multipart form POST.
365
+
366
+ **Quick triage:**
367
+ ```bash
368
+ # Count packets and protocols
369
+ tshark -r capture.pcap -q -z io,phs
370
+
371
+ # List HTTP requests
372
+ tshark -r capture.pcap -Y "http.request" -T fields -e http.request.method -e http.request.uri -e http.host
373
+
374
+ # Export all HTTP objects (files transferred)
375
+ tshark -r capture.pcap --export-objects http,/tmp/http_objects
376
+ ls -la /tmp/http_objects/
377
+
378
+ # Follow specific TCP streams
379
+ tshark -r capture.pcap -q -z "follow,tcp,ascii,0"
380
+ tshark -r capture.pcap -q -z "follow,tcp,ascii,1"
381
+ ```
382
+
383
+ **Extraction workflow:**
384
+ 1. Export HTTP objects — uploaded files are extracted automatically
385
+ 2. Check for multipart form-data POST requests (file uploads)
386
+ 3. Look for unusual User-Agent strings (e.g., `DeadDropBot/1.0`) indicating automated exfiltration
387
+ 4. Extracted files may be images (PNG/JPEG) with flag text rendered visually — open and inspect
388
+
389
+ **Key indicators of exfiltration:**
390
+ - POST to `/upload` endpoints
391
+ - Non-standard User-Agent strings
392
+ - Small number of packets but containing file transfers
393
+ - "Dead drop" pattern: attacker uploads file to web server for later retrieval
394
+
395
+ **Lesson:** Always start with `--export-objects` to extract transferred files before deep packet analysis. The flag is often in the exfiltrated file itself.
396
+
397
+ ---
398
+
399
+ ## TLS Master Key Extraction from Coredump (PlaidCTF 2014)
400
+
401
+ **Pattern:** Given a PCAP with HTTPS traffic and a coredump from the server/client process, extract the TLS master key from OpenSSL's in-memory session structure to decrypt the traffic.
402
+
403
+ **Extraction workflow:**
404
+
405
+ 1. Find the TLS Session ID from the handshake in Wireshark (visible in plaintext in the ClientHello/ServerHello)
406
+ 2. Search the coredump for the session ID bytes:
407
+ ```bash
408
+ # Search for session ID in coredump
409
+ grep -c '\x19\xAB\x5E\xDC\x02\xF0\x97\xD5' corefile
410
+ hexdump -C corefile | grep --before=5 '19 ab 5e dc'
411
+ ```
412
+
413
+ 3. In OpenSSL's `ssl_session_st`, `master_key[48]` is stored immediately before `session_id[32]`. Read the 48 bytes before the session ID match.
414
+
415
+ 4. Create a Wireshark pre-master-secret log file:
416
+ ```text
417
+ RSA Session-ID:<hex_session_id> Master-Key:<hex_master_key>
418
+ ```
419
+
420
+ 5. Load in Wireshark: Edit → Preferences → Protocols → TLS → (Pre-)Master-Secret log filename
421
+
422
+ **Key insight:** OpenSSL stores `master_key[48]` directly before `session_id[32]` in `ssl_session_st`. Search the coredump for the session ID (from the TLS handshake), then read the 48 bytes before it. This works with coredumps, memory dumps, and Volatility memory extractions.
423
+
424
+ ---
425
+
426
+ ## Split Archive Reassembly from HTTP Transfers (ASIS CTF Finals 2013)
427
+
428
+ **Pattern:** PCAP contains multiple HTTP file transfers with MD5-hash filenames, all the same size except one smaller file. Files are fragments of a split archive (e.g., 7z) that must be reassembled in order. A separate TCP stream contains a chat conversation with the archive password.
429
+
430
+ **Identification:**
431
+ - Multiple HTTP-transferred files with uniform size (e.g., 61440 bytes) and one smaller trailing fragment
432
+ - First file has an archive magic number (e.g., `7z` header `37 7A BC AF 27 1C`)
433
+ - Cover traffic and multiple ports used to obscure the transfers
434
+ - Apache directory listing in PCAP provides file modification timestamps
435
+
436
+ **Reassembly workflow:**
437
+
438
+ 1. Extract all HTTP objects and identify fragments:
439
+ ```bash
440
+ # Export HTTP objects
441
+ tshark -r capture.pcap --export-objects http,/tmp/http_objects
442
+ ls -la /tmp/http_objects/
443
+
444
+ # Check first file for archive magic number
445
+ xxd /tmp/http_objects/d33cf9e6230f3b8e5a0c91a0514ab476 | head -1
446
+ # 00000000: 377a bcaf 271c ... → 7z archive header
447
+ ```
448
+
449
+ 2. Determine fragment order from Apache directory listing timestamps in PCAP:
450
+ ```bash
451
+ # Extract the directory listing page
452
+ tshark -r capture.pcap -Y "http.response and http.content_type contains html" \
453
+ -T fields -e http.file_data | head -1
454
+ # Parse modification timestamps from the HTML table, sort chronologically
455
+ ```
456
+
457
+ 3. Concatenate fragments in timestamp order:
458
+ ```bash
459
+ # Order files by modification timestamp (earliest first, smallest file last)
460
+ cat d33cf9e6230f3b8e5a0c91a0514ab476 \
461
+ 57f18f111f47eb9f7b5cdf5bd45144b0 \
462
+ 1e13be50f05092e2a4e79b321c8450d4 \
463
+ ... \
464
+ c68cc0718b8b85e62c8a671f7c81e80a > archive.7z
465
+ ```
466
+
467
+ 4. Extract password from TCP conversation stream:
468
+ ```bash
469
+ # Follow TCP streams to find chat with key exchange
470
+ tshark -r capture.pcap -q -z "follow,tcp,ascii,0"
471
+ # Look for "secret key" / "part N" messages, concatenate all parts
472
+ ```
473
+
474
+ 5. Decompress with recovered password:
475
+ ```bash
476
+ 7z x archive.7z -p"M)m5s6S^[>@#Q3+10PD.KE#cyPsvqH"
477
+ ```
478
+
479
+ **Key insight:** When PCAP contains many same-sized file transfers, suspect a split archive. The fragment order is not the download order — look for an Apache/nginx directory listing page in the PCAP whose modification timestamps provide the correct reassembly sequence. The smallest file is the trailing fragment.
480
+
481
+ ---
482
+
483
+ ## WPA/WEP WiFi Decryption from PCAP (DefCamp CTF 2016)
484
+
485
+ Captured WiFi traffic in pcapng format can be decrypted if the WEP/WPA key is recovered through brute force or is known.
486
+
487
+ ```bash
488
+ # Step 1: Identify encrypted WiFi networks in capture
489
+ aircrack-ng capture.pcapng
490
+
491
+ # Step 2: Crack WEP key (PTW attack or brute force)
492
+ aircrack-ng -a 1 capture.pcapng # PTW attack (fast)
493
+ aircrack-ng -a 1 -w wordlist.txt capture.pcapng # dictionary attack
494
+
495
+ # Step 3: Crack WPA/WPA2 key
496
+ aircrack-ng -a 2 -w rockyou.txt capture.pcapng
497
+
498
+ # Step 4: Decrypt traffic with recovered key
499
+ airdecap-ng -w "recovered_key" capture.pcapng # WEP
500
+ airdecap-ng -p "passphrase" -e "SSID" capture.pcapng # WPA
501
+
502
+ # Step 5: Analyze decrypted traffic
503
+ # Output: capture-dec.pcapng (decrypted packets)
504
+ wireshark capture-dec.pcapng
505
+
506
+ # Alternative: decrypt directly in Wireshark
507
+ # Edit > Preferences > Protocols > IEEE 802.11
508
+ # Add decryption key (WEP/WPA-PWD/WPA-PSK)
509
+
510
+ # Look for: HTTP traffic, IPP (printing), FTP, unencrypted protocols
511
+ # Multiple password changes may require multiple decryption passes
512
+ ```
513
+
514
+ **Key insight:** WiFi CTF challenges often have multiple encryption key changes throughout the capture. Decrypt, look for hints to the next password in the decrypted traffic, then decrypt the next segment. Check Internet Printing Protocol (IPP) streams for job-name fields containing flags.
515
+
516
+ ---
517
+
518
+ ## Corrupted PCAP Repair with pcapfix (CSAW CTF 2016)
519
+
520
+ Corrupted packet capture files can be repaired to make them openable in Wireshark.
521
+
522
+ ```bash
523
+ # Install pcapfix
524
+ # apt install pcapfix (or brew install pcapfix)
525
+
526
+ # Repair corrupted pcap/pcapng file
527
+ pcapfix -d corrupted.pcap # basic repair with verbose output
528
+ pcapfix -d corrupted.pcapng # also handles pcapng format
529
+
530
+ # Output: fixed_corrupted.pcap (repaired file)
531
+
532
+ # Common corruption types pcapfix handles:
533
+ # - Broken file header (magic bytes)
534
+ # - Truncated packets
535
+ # - Invalid packet lengths
536
+ # - Missing packet headers
537
+ # - Wrong byte order
538
+ # - Damaged section headers (pcapng)
539
+
540
+ # If pcapfix fails, try manual repair:
541
+ python3 -c "
542
+ import struct
543
+ with open('corrupted.pcap', 'rb') as f:
544
+ data = bytearray(f.read())
545
+
546
+ # Fix pcap magic bytes (0xa1b2c3d4 for microsecond, 0xa1b23c4d for nanosecond)
547
+ data[0:4] = struct.pack('<I', 0xa1b2c3d4)
548
+
549
+ # Fix version (2.4)
550
+ data[4:6] = struct.pack('<H', 2)
551
+ data[6:8] = struct.pack('<H', 4)
552
+
553
+ with open('fixed.pcap', 'wb') as f:
554
+ f.write(data)
555
+ "
556
+
557
+ # Then open in Wireshark
558
+ wireshark fixed_corrupted.pcap
559
+ ```
560
+
561
+ **Key insight:** Damaged PCAPs are common in forensics CTF challenges. Always try `pcapfix` first -- it handles most corruption automatically. For manual repair, the pcap header is 24 bytes: magic(4) + version(4) + timezone(4) + sigfigs(4) + snaplen(4) + linktype(4).
562
+
563
+ ---
564
+
565
+ ## SAP Dialog Protocol Decryption from PCAP (GreHack CTF 2016)
566
+
567
+ SAP Dialog frames in network captures can be decrypted using Cain and Abel on Windows.
568
+
569
+ ```bash
570
+ # SAP Dialog protocol uses weak obfuscation (not true encryption)
571
+ # Step 1: Open PCAP in Wireshark to identify SAP traffic
572
+ # Filter: sap or tcp.port == 3200
573
+
574
+ # Step 2: Use Cain and Abel (Windows tool) for decryption
575
+ # - Import PCAP into Cain's Sniffer tab
576
+ # - Select SAP Dialog entries
577
+ # - Right-click > View to decrypt frames
578
+ # - Search with Ctrl+F for keywords (flag, key, password)
579
+
580
+ # Alternative: Use SAP Dissector plugin for Wireshark
581
+ # - Install: apt install wireshark-plugin-sap (if available)
582
+ # - Or: https://github.com/SecureAuthCorp/SAP-Dissection-plug-in-for-Wireshark
583
+
584
+ # Manual approach using pysap:
585
+ # pip install pysap
586
+ from pysap import SAPDiag
587
+ # Parse SAP Dialog packets from PCAP
588
+ ```
589
+
590
+ **Key insight:** SAP Dialog protocol's "encryption" is simple obfuscation easily reversed. Cain and Abel (Windows) has built-in SAP Dialog decryption. For Linux, use pysap or SAP Wireshark dissector plugins.
591
+
592
+ ---
593
+
594
+ ---
595
+
596
+ ## DNS Exfiltration Oracle via Binary Response Probing (ASIS CTF Finals 2017)
597
+
598
+ DNS queries to subdomains with binary string prefixes act as an oracle: the server returns NOERROR when the prefix matches the flag bits, NXDOMAIN otherwise. Build the binary string incrementally — add one bit at a time and test which value yields NOERROR — to reconstruct the flag bit by bit.
599
+
600
+ ```python
601
+ import dns.resolver
602
+
603
+ flag_bits = ""
604
+ flag_len = 40 # adjust based on expected flag length in chars
605
+
606
+ for i in range(flag_len * 8):
607
+ for bit in ['0', '1']:
608
+ try:
609
+ dns.resolver.resolve(f"{flag_bits}{bit}.target.com", 'A')
610
+ flag_bits += bit
611
+ break
612
+ except dns.resolver.NXDOMAIN:
613
+ continue
614
+
615
+ # Convert bit string to ASCII
616
+ flag = ''.join(chr(int(flag_bits[i:i+8], 2)) for i in range(0, len(flag_bits), 8))
617
+ print(flag)
618
+ ```
619
+
620
+ **Key insight:** DNS NOERROR vs NXDOMAIN acts as a binary oracle leaking one bit per query — applicable to any DNS-based covert channel. Each query tests whether a candidate prefix is correct, allowing O(n) reconstruction where n is the number of bits in the flag.
621
+
622
+ ---
623
+
624
+ ## ICMP Echo Payload Length as Covert Channel (TokyoWesterns CTF 4th 2018)
625
+
626
+ **Pattern:** A PCAP contains a sequence of ICMP echo-request packets. The payload bytes look random, but the *length* of each payload is a printable ASCII character — the sender uses `ping -s <len>` per character to smuggle the flag past any content-level IDS. Content inspection reveals nothing; only the per-packet length field carries the data.
627
+
628
+ **Extraction:**
629
+ ```python
630
+ from scapy.all import rdpcap, ICMP
631
+
632
+ pkts = rdpcap('capture.pcap')
633
+ flag = ''.join(
634
+ chr(len(p[ICMP].payload))
635
+ for p in pkts
636
+ if ICMP in p and p[ICMP].type == 8 # echo-request
637
+ )
638
+ print(flag)
639
+ ```
640
+
641
+ **Key insight:** Any metadata field a sender can influence (packet length, TTL, IPID, TCP window size, DNS QNAME length, HTTP request ordering) is a potential covert channel. Before analyzing payload contents, plot per-packet metadata distributions — a histogram that hits only printable-ASCII-range values is a giveaway. Combine with `tshark -T fields -e icmp.data_len` for rapid extraction from large PCAPs.
642
+
643
+ **References:** TokyoWesterns CTF 4th 2018 — writeup 10866
644
+
645
+ See also: [network-advanced.md](network-advanced.md) for advanced network forensics techniques (packet interval timing encoding, USB HID mouse/pen drawing recovery, NTLMv2 hash cracking, TCP flag covert channels, DNS steganography, multi-layer PCAP with XOR, Brotli decompression bomb seam analysis, SMB RID recycling, Timeroasting MS-SNTP).