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,204 @@
1
+ # CTF Reverse - Anti-Analysis CTF Writeups
2
+
3
+ CTF-specific anti-analysis techniques: signal-handler tricks, instruction-trace inversion, call-less function chaining, parent-patched child binary dumping. For the core anti-analysis taxonomy (Linux/Windows anti-debug, anti-VM, anti-DBI, code integrity, anti-disassembly), see [anti-analysis.md](anti-analysis.md).
4
+
5
+ ## Table of Contents
6
+ - [SIGILL Handler for Execution Mode Switching (Hack.lu 2015)](#sigill-handler-for-execution-mode-switching-hacklu-2015)
7
+ - [SIGFPE Signal Handler Side-Channel via strace Counting (PlaidCTF 2017)](#sigfpe-signal-handler-side-channel-via-strace-counting-plaidctf-2017)
8
+ - [Instruction Trace Inversion with Keystone and Unicorn (MeePwn CTF 2017)](#instruction-trace-inversion-with-keystone-and-unicorn-meepwn-ctf-2017)
9
+ - [Call-less Function Chaining via Stack Frame Manipulation (THC CTF 2018)](#call-less-function-chaining-via-stack-frame-manipulation-thc-ctf-2018)
10
+ - [Parent-Patched Child Binary Dump via strace process_vm_writev (Google CTF Quals 2018)](#parent-patched-child-binary-dump-via-strace-process_vm_writev-google-ctf-quals-2018)
11
+ - [ConfuserEx Dynamic Module Dump via Constructor Breakpoint (Kaspersky 2018)](#confuserex-dynamic-module-dump-via-constructor-breakpoint-kaspersky-2018)
12
+
13
+ ---
14
+
15
+ ## SIGILL Handler for Execution Mode Switching (Hack.lu 2015)
16
+
17
+ Binaries may install SIGILL (illegal instruction) handlers to switch between x86 and x86-64 execution modes or implement custom opcode dispatch:
18
+
19
+ 1. **Signal registration:** `signal(SIGILL, handler)` installs a callback for illegal instruction exceptions
20
+ 2. **Mode switching:** The handler modifies the saved instruction pointer or segment registers to switch between 32-bit and 64-bit code
21
+ 3. **Custom opcodes:** Invalid x86 instructions trigger the handler, which interprets operand bytes as custom VM opcodes
22
+
23
+ ```c
24
+ // Signal handler decodes "illegal" instructions as custom opcodes
25
+ void sigill_handler(int sig, siginfo_t *info, void *ucontext) {
26
+ ucontext_t *ctx = (ucontext_t *)ucontext;
27
+ unsigned char *pc = (unsigned char *)ctx->uc_mcontext.gregs[REG_RIP];
28
+ // Decode custom opcode from bytes at PC
29
+ // Advance PC past the custom instruction
30
+ ctx->uc_mcontext.gregs[REG_RIP] += opcode_length;
31
+ }
32
+ ```
33
+
34
+ **Key insight:** If a binary installs signal handlers for SIGILL/SIGSEGV/SIGTRAP early in execution, suspect custom instruction dispatch. Trace signal deliveries with `strace -e signal` or set GDB to not intercept: `handle SIGILL nostop pass`.
35
+
36
+ ---
37
+
38
+ ## SIGFPE Signal Handler Side-Channel via strace Counting (PlaidCTF 2017)
39
+
40
+ Binary uses SIGFPE signal handlers for control flow, making static analysis unreliable. Brute-force by counting SIGFPE signals via strace — correct input characters produce more signals.
41
+
42
+ ```bash
43
+ # Count SIGFPE signals per input character guess
44
+ for c in {a..z} {A..Z} {0..9}; do
45
+ count=$(echo -n "${c}AAAAAAA" | strace -e signal=SIGFPE ./binary 2>&1 | grep -c SIGFPE)
46
+ echo "$c: $count"
47
+ done
48
+ # Character producing the most SIGFPEs is correct
49
+ # Repeat for each position, extending the known prefix
50
+ ```
51
+
52
+ **Key insight:** Signal handlers (SIGFPE, SIGSEGV, SIGILL) create implicit control flow invisible to static analysis. The number of signals raised correlates with validation progress. Counting signals via `strace -e signal=SIGFPE` turns opaque signal-based validation into a measurable side-channel for character-by-character brute-force.
53
+
54
+ ---
55
+
56
+ ## Instruction Trace Inversion with Keystone and Unicorn (MeePwn CTF 2017)
57
+
58
+ UPX-packed binary applies a sequence of arithmetic-only transforms (sub, add, xor, rol, ror) to the flag. No memory side-effects — purely register arithmetic. IDAPython traces non-jump instructions, the sequence is then inverted to recover the flag.
59
+
60
+ **Inversion rules:**
61
+ - Reverse the instruction sequence (last instruction first)
62
+ - Swap inverse pairs: `add ↔ sub`, `rol ↔ ror`, `xor` is self-inverse
63
+
64
+ ```python
65
+ # IDAPython: collect non-jump instructions in the obfuscated routine
66
+ import idaapi, idc
67
+
68
+ def trace_transforms(start_ea, end_ea):
69
+ instructions = []
70
+ ea = start_ea
71
+ while ea < end_ea:
72
+ mnem = idc.print_insn_mnem(ea)
73
+ if mnem not in ('jmp', 'je', 'jne', 'call', 'ret'):
74
+ instructions.append((ea, mnem, idc.print_operands(ea)))
75
+ ea = idc.next_head(ea)
76
+ return instructions
77
+
78
+ transforms = trace_transforms(0x401000, 0x401200)
79
+
80
+ # Invert: reverse order, swap add/sub and rol/ror
81
+ inverse_map = {'add': 'sub', 'sub': 'add', 'rol': 'ror', 'ror': 'rol', 'xor': 'xor'}
82
+ inverted = [(mnem, op) for (_, mnem, op) in reversed(transforms)]
83
+ inverted = [(inverse_map.get(m, m), op) for m, op in inverted]
84
+ ```
85
+
86
+ ```python
87
+ # Assemble inverted instructions with Keystone, emulate with Unicorn
88
+ from keystone import *
89
+ from unicorn import *
90
+ from unicorn.x86_const import *
91
+
92
+ ks = Ks(KS_ARCH_X86, KS_MODE_64)
93
+ uc = Uc(UC_ARCH_X86, UC_MODE_64)
94
+
95
+ asm_src = '\n'.join(f'{mnem} {op}' for mnem, op in inverted)
96
+ encoding, _ = ks.asm(asm_src)
97
+
98
+ CODE_BASE = 0x400000
99
+ uc.mem_map(CODE_BASE, 0x10000)
100
+ uc.mem_write(CODE_BASE, bytes(encoding))
101
+
102
+ # Set initial register state to the observed output value
103
+ uc.reg_write(UC_X86_REG_RAX, known_output)
104
+ uc.emu_start(CODE_BASE, CODE_BASE + len(encoding))
105
+ flag_bytes = uc.reg_read(UC_X86_REG_RAX).to_bytes(8, 'little')
106
+ ```
107
+
108
+ **PEB anti-debug note:** If the binary reads `PEB.BeingDebugged` and uses it to select between two comparison target values, the traced instructions under IDAPython may use the debug-mode target. Patch `BeingDebugged` to 0 before tracing, or identify both branches and use the non-debug target value.
109
+
110
+ **Key insight:** Arithmetic-only obfuscation (no memory writes) is fully reversible by tracing, inverting the instruction sequence, and swapping inverse operations. PEB anti-debug can silently change comparison targets — always verify which branch is taken.
111
+
112
+ **References:** MeePwn CTF 2017
113
+
114
+ ---
115
+
116
+ ### Call-less Function Chaining via Stack Frame Manipulation (THC CTF 2018)
117
+
118
+ **Pattern:** Binary hides function calls by building a linked list of function pointers on the stack, then modifying saved RBP and return addresses so `leave; ret` instructions chain through the list without any explicit `CALL` instructions. IDA fails to decompile because push/pop are unbalanced and function boundaries cannot be determined.
119
+
120
+ Each function in the chain:
121
+ 1. Pushes operands and the next function's address onto the stack
122
+ 2. Sets saved RBP to point to the next stack frame
123
+ 3. Sets the return address to the next function
124
+ 4. `leave` restores RSP from RBP (moving to next frame), `ret` jumps to the next function
125
+
126
+ ```python
127
+ # Reversed processing chain (each function applied via leave/ret):
128
+ def reverse_processing(byte):
129
+ res = byte | 0x80 # OR 0x80
130
+ res = res ^ 0xCA # XOR 0xCA
131
+ res = (res + 66) & 0xFF # ADD 66
132
+ res = res ^ 0xCA # XOR 0xCA (repeated)
133
+ res = (res + 66) & 0xFF
134
+ res = res ^ 0xCA
135
+ res = (res + 66) & 0xFF
136
+ res = res ^ 0xFE # XOR 0xFE (final)
137
+ return res
138
+ # Apply in reverse order, then reverse the character sequence
139
+ ```
140
+
141
+ **Key insight:** By manipulating saved RBP to point to the next stack frame and saved RIP to the next function, `leave; ret` chains through functions without any `call` instructions. Disassemblers that track call/ret balance fail to identify function boundaries. Patch each function body individually for IDA to handle them.
142
+
143
+ **Detection:** Binary with many small code blocks ending in `leave; ret` but no corresponding `call` instructions. Stack contains interleaved function pointers and data. IDA shows "stack frame is too big" or fails to create functions.
144
+
145
+ **References:** THC CTF 2018
146
+
147
+ ---
148
+
149
+ ### Parent-Patched Child Binary Dump via strace process_vm_writev (Google CTF Quals 2018)
150
+
151
+ **Pattern (Keygenme):** The binary forks. The child is stub code full of `int3` (`0xcc`) traps. The parent uses `ptrace` + `process_vm_writev` to write the real instructions into the child right before each trap fires, then stepping continues. Static analysis of the child sees only junk; dynamic analysis in a single-process debugger misses the parent's writes.
152
+
153
+ **Bypass — let strace do the work:**
154
+ ```bash
155
+ # Record every process_vm_writev the parent performs, including full iov contents.
156
+ strace -f -e trace=process_vm_writev -e write=all -o trace.log ./keygenme
157
+
158
+ # Each entry looks like:
159
+ # process_vm_writev(child_pid, [{iov_base="\x48\x89\xe5...", iov_len=12}], 1,
160
+ # [{iov_base=0x400c80, iov_len=12}], 1, 0) = 12
161
+ ```
162
+
163
+ Parse the log to extract `(remote_addr, bytes)` pairs and emit an IDA `patch_bytes` script:
164
+ ```python
165
+ import re, pathlib
166
+ patches = []
167
+ pattern = re.compile(
168
+ r'process_vm_writev\(\d+, \[{iov_base="([^"]+)", iov_len=(\d+)}\].*?\[{iov_base=(0x[0-9a-f]+)',
169
+ )
170
+ for m in pattern.finditer(pathlib.Path('trace.log').read_text()):
171
+ data = m.group(1).encode('latin1').decode('unicode_escape').encode('latin1')
172
+ addr = int(m.group(3), 16)
173
+ patches.append((addr, data))
174
+
175
+ with open('patch.py', 'w') as fh:
176
+ for addr, data in patches:
177
+ for i, b in enumerate(data):
178
+ fh.write(f'patch_byte({addr + i:#x}, {b:#x})\n')
179
+ ```
180
+
181
+ Load `patch.py` in IDA (File → Script file) to apply every parent-written instruction, turning the trap-riddled child into a fully readable binary. With the patched binary, the crypto routine is a plain loop — black-box the irreversible portion and replace the final `strcmp` with a leak of the expected value.
182
+
183
+ **Key insight:** Any anti-analysis scheme that uses a ptracer to rewrite the tracee's text is transparent to `strace` on the parent. `process_vm_writev` calls carry both the target address and the bytes, so a one-pass strace run is enough to dump the real code. The same trick works for self-modifying packers that use `ptrace(PTRACE_POKEDATA)` or `write()` into `/proc/<pid>/mem`.
184
+
185
+ **References:** Google CTF Quals 2018 — writeup 10330
186
+
187
+ ---
188
+
189
+ ## ConfuserEx Dynamic Module Dump via Constructor Breakpoint (Kaspersky 2018)
190
+
191
+ **Pattern:** ConfuserEx (.NET protector) encrypts method bodies and decrypts them at runtime from a `<Module>` constructor. Break on the constructor in dnSpy, step until the dynamic module is fully built in memory, right-click → **Save Module** to dump the decrypted assembly with tokens intact. Run `de4dot` over the dump to rename obfuscated symbols.
192
+
193
+ ```text
194
+ dnSpy:
195
+ File → Open → target.exe
196
+ Assembly Explorer → <Module> .cctor → F9 (breakpoint)
197
+ F5 to run; wait until loaded
198
+ Right-click assembly → Save Module → out.exe
199
+ $ de4dot out.exe # symbol cleanup
200
+ ```
201
+
202
+ **Key insight:** ConfuserEx protects on-disk code but not the runtime representation. Any time a .NET protector ships a compiled constructor that performs decryption, the dumped post-constructor module is the cleartext binary. Chain with de4dot to undo the follow-up symbol obfuscation.
203
+
204
+ **References:** Kaspersky Industrial CTF 2018 — glardomos, writeup 12325