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,421 @@
1
+ # Advanced Reverse Engineering Tools (Part 2)
2
+
3
+ Advanced GDB scripting, Ghidra automation, patching frameworks, and CTF-specific GDB-driven techniques. Continuation of [tools-advanced.md](tools-advanced.md).
4
+
5
+ ## Table of Contents
6
+ - [Advanced GDB Techniques](#advanced-gdb-techniques)
7
+ - [Python Scripting](#python-scripting)
8
+ - [Brute-Force with GDB Script](#brute-force-with-gdb-script)
9
+ - [Conditional Breakpoints](#conditional-breakpoints)
10
+ - [Watchpoints](#watchpoints)
11
+ - [Reverse Debugging (rr)](#reverse-debugging-rr)
12
+ - [GDB Dashboard / GEF / pwndbg](#gdb-dashboard--gef--pwndbg)
13
+ - [Advanced Ghidra Scripting](#advanced-ghidra-scripting)
14
+ - [Patching Strategies](#patching-strategies)
15
+ - [Binary Ninja Patching (Python API)](#binary-ninja-patching-python-api)
16
+ - [LIEF (Library for Instrumenting Executable Formats)](#lief-library-for-instrumenting-executable-formats)
17
+ - [GDB Constraint Extraction with ILP/LP Solver (BackdoorCTF 2017)](#gdb-constraint-extraction-with-ilplp-solver-backdoorctf-2017)
18
+ - [GDB Position-Encoded Input with Zero Flag Monitoring (EKOPARTY 2017)](#gdb-position-encoded-input-with-zero-flag-monitoring-ekoparty-2017)
19
+ - [LD_PRELOAD to Dump Execute-Only Binary (BackdoorCTF 2017)](#ld_preload-to-dump-execute-only-binary-backdoorctf-2017)
20
+ - [PEDA current_inst Bit-by-Bit Flag Scraper (CONFidence CTF 2019 Teaser)](#peda-current_inst-bit-by-bit-flag-scraper-confidence-ctf-2019-teaser)
21
+
22
+ ---
23
+
24
+ ## Advanced GDB Techniques
25
+
26
+ ### Python Scripting
27
+
28
+ ```python
29
+ # ~/.gdbinit or source from GDB
30
+ import gdb
31
+
32
+ class TraceCompare(gdb.Breakpoint):
33
+ """Log all comparison operations."""
34
+ def __init__(self, addr):
35
+ super().__init__(f"*{addr}", gdb.BP_BREAKPOINT)
36
+
37
+ def stop(self):
38
+ frame = gdb.selected_frame()
39
+ rdi = int(frame.read_register("rdi"))
40
+ rsi = int(frame.read_register("rsi"))
41
+ rdx = int(frame.read_register("rdx"))
42
+ # Read compared buffers
43
+ inferior = gdb.selected_inferior()
44
+ buf1 = inferior.read_memory(rdi, rdx).tobytes()
45
+ buf2 = inferior.read_memory(rsi, rdx).tobytes()
46
+ print(f"memcmp({buf1!r}, {buf2!r}, {rdx})")
47
+ return False # Don't stop, just log
48
+
49
+ # Usage in GDB:
50
+ # (gdb) source trace_cmp.py
51
+ # (gdb) python TraceCompare(0x401234)
52
+ ```
53
+
54
+ ### Brute-Force with GDB Script
55
+
56
+ ```python
57
+ # Byte-by-byte brute force via GDB Python API
58
+ import gdb, string
59
+
60
+ def bruteforce_flag(check_addr, success_addr, fail_addr, flag_len):
61
+ flag = []
62
+ for pos in range(flag_len):
63
+ for ch in string.printable:
64
+ candidate = ''.join(flag) + ch + 'A' * (flag_len - pos - 1)
65
+ gdb.execute('start', to_string=True)
66
+ gdb.execute(f'b *{check_addr}', to_string=True)
67
+ # Write candidate to stdin pipe
68
+ # ... (setup input)
69
+ gdb.execute('continue', to_string=True)
70
+ rip = int(gdb.parse_and_eval('$rip'))
71
+ if rip == success_addr:
72
+ flag.append(ch)
73
+ break
74
+ gdb.execute('delete breakpoints', to_string=True)
75
+ return ''.join(flag)
76
+ ```
77
+
78
+ ### Conditional Breakpoints
79
+
80
+ ```bash
81
+ # Break only when register has specific value
82
+ (gdb) b *0x401234 if $rax == 0x41
83
+ (gdb) b *0x401234 if *(char*)$rdi == 'f'
84
+
85
+ # Break on Nth hit
86
+ (gdb) b *0x401234
87
+ (gdb) ignore 1 99 # Skip first 99 hits, break on 100th
88
+
89
+ # Log without stopping
90
+ (gdb) b *0x401234
91
+ (gdb) commands
92
+ > silent
93
+ > printf "rax=%lx rdi=%lx\n", $rax, $rdi
94
+ > continue
95
+ > end
96
+ ```
97
+
98
+ ### Watchpoints
99
+
100
+ ```bash
101
+ # Hardware watchpoint — break when memory changes
102
+ (gdb) watch *(int*)0x601050 # Break on write to address
103
+ (gdb) rwatch *(int*)0x601050 # Break on read
104
+ (gdb) awatch *(int*)0x601050 # Break on read or write
105
+
106
+ # Watch a variable by name (needs debug symbols)
107
+ (gdb) watch flag_buffer[0]
108
+
109
+ # Conditional watchpoint
110
+ (gdb) watch *(int*)0x601050 if *(int*)0x601050 == 0x42
111
+ ```
112
+
113
+ ### Reverse Debugging (rr)
114
+
115
+ ```bash
116
+ # Record execution
117
+ rr record ./binary
118
+ # Replay with reverse execution support
119
+ rr replay
120
+
121
+ # In rr replay (GDB commands plus):
122
+ (gdb) reverse-continue # Run backward to previous breakpoint
123
+ (gdb) reverse-stepi # Step backward one instruction
124
+ (gdb) reverse-next # Reverse next
125
+ (gdb) when # Show current event number
126
+
127
+ # Set checkpoint and return to it
128
+ (gdb) checkpoint
129
+ (gdb) restart 1 # Return to checkpoint 1
130
+ ```
131
+
132
+ **Key use:** When you step past the critical moment, reverse back instead of restarting. Invaluable for anti-debug that corrupts state.
133
+
134
+ ### GDB Dashboard / GEF / pwndbg
135
+
136
+ ```bash
137
+ # pwndbg (most popular for CTF)
138
+ # https://github.com/pwndbg/pwndbg
139
+ git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh
140
+
141
+ # Key pwndbg commands:
142
+ pwndbg> context # Show registers, stack, code, backtrace
143
+ pwndbg> vmmap # Memory map (like /proc/self/maps)
144
+ pwndbg> search -s "flag{" # Search memory for string
145
+ pwndbg> telescope $rsp 20 # Smart stack dump
146
+ pwndbg> cyclic 200 # Generate De Bruijn pattern
147
+ pwndbg> hexdump $rdi 64 # Pretty hex dump
148
+ pwndbg> got # Show GOT entries
149
+ pwndbg> plt # Show PLT entries
150
+
151
+ # GEF (alternative)
152
+ # https://github.com/hugsy/gef
153
+ bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
154
+
155
+ # Key GEF commands:
156
+ gef> xinfo $rdi # Detailed info about address
157
+ gef> checksec # Binary security features
158
+ gef> heap chunks # Heap chunk listing
159
+ gef> pattern create 100 # De Bruijn pattern
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Advanced Ghidra Scripting
165
+
166
+ ```python
167
+ # Ghidra Python (Jython) — run via Script Manager or headless
168
+
169
+ # Batch rename functions matching a pattern
170
+ from ghidra.program.model.symbol import SourceType
171
+ fm = currentProgram.getFunctionManager()
172
+ for func in fm.getFunctions(True):
173
+ if func.getName().startswith("FUN_"):
174
+ # Check if function contains specific instruction pattern
175
+ body = func.getBody()
176
+ inst_iter = currentProgram.getListing().getInstructions(body, True)
177
+ for inst in inst_iter:
178
+ if inst.getMnemonicString() == "CPUID":
179
+ func.setName("anti_vm_check_" + hex(func.getEntryPoint().getOffset()),
180
+ SourceType.USER_DEFINED)
181
+ break
182
+
183
+ # Extract all XOR constants from a function
184
+ def extract_xor_constants(func):
185
+ """Find all XOR operations and their immediate operands."""
186
+ constants = []
187
+ body = func.getBody()
188
+ inst_iter = currentProgram.getListing().getInstructions(body, True)
189
+ for inst in inst_iter:
190
+ if inst.getMnemonicString() == "XOR":
191
+ for i in range(inst.getNumOperands()):
192
+ op = inst.getOpObjects(i)
193
+ if op and hasattr(op[0], 'getValue'):
194
+ constants.append(int(op[0].getValue()))
195
+ return constants
196
+
197
+ # Bulk decompile and search for pattern
198
+ from ghidra.app.decompiler import DecompInterface
199
+ decomp = DecompInterface()
200
+ decomp.openProgram(currentProgram)
201
+
202
+ for func in fm.getFunctions(True):
203
+ result = decomp.decompileFunction(func, 30, monitor)
204
+ if result.depiledFunction():
205
+ code = result.getDecompiledFunction().getC()
206
+ if "strcmp" in code or "memcmp" in code:
207
+ print(f"Comparison in {func.getName()} at {func.getEntryPoint()}")
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Patching Strategies
213
+
214
+ ### Binary Ninja Patching (Python API)
215
+
216
+ ```python
217
+ import binaryninja as bn
218
+
219
+ bv = bn.open_view("binary")
220
+
221
+ # NOP out instruction
222
+ bv.write(0x401234, b"\x90" * 5) # 5-byte NOP
223
+
224
+ # Patch conditional jump (JNZ → JZ)
225
+ bv.write(0x401234, b"\x74") # 0x75 (JNZ) → 0x74 (JZ)
226
+
227
+ # Insert always-true (mov eax, 1; ret)
228
+ bv.write(0x401234, b"\xb8\x01\x00\x00\x00\xc3")
229
+
230
+ bv.save("patched")
231
+ ```
232
+
233
+ ### LIEF (Library for Instrumenting Executable Formats)
234
+
235
+ ```python
236
+ import lief
237
+
238
+ # Parse and modify ELF/PE/Mach-O
239
+ binary = lief.parse("binary")
240
+
241
+ # Add a new section
242
+ section = lief.ELF.Section(".patch")
243
+ section.content = list(b"\xcc" * 0x100)
244
+ section.type = lief.ELF.SECTION_TYPES.PROGBITS
245
+ section.flags = lief.ELF.SECTION_FLAGS.EXECINSTR | lief.ELF.SECTION_FLAGS.ALLOC
246
+ binary.add(section)
247
+
248
+ # Modify entry point
249
+ binary.header.entrypoint = 0x401000
250
+
251
+ # Hook imported function
252
+ binary.patch_pltgot("strcmp", 0x401000)
253
+
254
+ binary.write("patched")
255
+ ```
256
+
257
+ **LIEF advantages:** Cross-format (ELF, PE, Mach-O), Python API, can add sections/segments, modify headers, patch imports.
258
+
259
+ ---
260
+
261
+ ## GDB Constraint Extraction with ILP/LP Solver (BackdoorCTF 2017)
262
+
263
+ When a binary enforces linear arithmetic relationships between input bytes, extract constraints automatically via GDB and solve with an ILP solver.
264
+
265
+ **Technique:** Send position-encoded input (`input[i] = i`) so that when a comparison fires, you know exactly which positions are involved and what their sum/difference must equal. Collect all constraints from logged comparisons, then feed to PuLP or Gurobi.
266
+
267
+ ```python
268
+ from pulp import *
269
+
270
+ n = 32 # flag length
271
+ prob = LpProblem("crackme", LpMinimize)
272
+ x = [LpVariable(f'x{i}', 32, 126, cat='Integer') for i in range(n)]
273
+ prob += 0 # dummy objective
274
+
275
+ # Constraints extracted via GDB automation (input[i]=i, monitor comparisons):
276
+ prob += x[3] + x[7] == 0xAB
277
+ prob += x[1] - x[5] == 0x0C
278
+ # ... add all extracted constraints ...
279
+
280
+ # Constrain to printable ASCII
281
+ for xi in x:
282
+ prob += xi >= 32
283
+ prob += xi <= 126
284
+
285
+ prob.solve(PULP_CBC_CMD(msg=0))
286
+ flag = ''.join(chr(int(value(xi))) for xi in x)
287
+ print("Flag:", flag)
288
+ ```
289
+
290
+ **GDB automation to extract constraints:**
291
+ ```python
292
+ # In GDB Python: set input[i]=i, run, log every CMP instruction result
293
+ import gdb
294
+
295
+ class CmpLogger(gdb.Breakpoint):
296
+ def stop(self):
297
+ frame = gdb.selected_frame()
298
+ # Read compared values, map back to input indices via position encoding
299
+ return False
300
+ ```
301
+
302
+ **Key insight:** When a binary enforces linear arithmetic relationships between input bytes, ILP solvers directly find the satisfying assignment once constraints are extracted via GDB automation.
303
+
304
+ **References:** BackdoorCTF 2017
305
+
306
+ ---
307
+
308
+ ## GDB Position-Encoded Input with Zero Flag Monitoring (EKOPARTY 2017)
309
+
310
+ Send input where `input[i] = i` (position-encoded). Single-step through the binary monitoring the CPU zero flag (ZF). When ZF is set at a comparison involving a specific position's value, the comparison matched — log the expected value for that position.
311
+
312
+ ```python
313
+ import gdb
314
+
315
+ # Script: single-step binary with position-encoded input, watch ZF
316
+ class ZFMonitor(gdb.Breakpoint):
317
+ def stop(self):
318
+ zf = (int(gdb.parse_and_eval('$eflags')) >> 6) & 1
319
+ if zf:
320
+ rip = int(gdb.parse_and_eval('$rip'))
321
+ # Disassemble at rip to find the compared immediate
322
+ disasm = gdb.execute(f'x/1i {rip-5}', to_string=True)
323
+ print(f"ZF set at {rip:#x}: {disasm.strip()}")
324
+ return False
325
+
326
+ # Run once with input b'\x00\x01\x02\x03...\x1f'
327
+ # ZF fires when comparison matches the position's own value -> that IS the key byte
328
+ ```
329
+
330
+ Maps each input byte to its required value in one pass without manual reversing.
331
+
332
+ **Key insight:** Position-encoded input (`input[i]=i`) combined with zero flag monitoring reveals the full key/password in one pass — the zero flag fires when the expected value for position i equals i itself.
333
+
334
+ **References:** EKOPARTY CTF 2017
335
+
336
+ ---
337
+
338
+ ## LD_PRELOAD to Dump Execute-Only Binary (BackdoorCTF 2017)
339
+
340
+ A binary has execute-only permissions (mode `--x`, no read bit). The file cannot be read directly or with standard tools, but the kernel still maps it into memory on execution.
341
+
342
+ LD_PRELOAD a shared library with a constructor that runs inside the process and reads its own memory via `/proc/self/mem`:
343
+
344
+ ```c
345
+ // dump_xo.c — compile: gcc -shared -fPIC -o dump_xo.so dump_xo.c
346
+ #include <stdio.h>
347
+ #include <stdlib.h>
348
+ #include <string.h>
349
+
350
+ __attribute__((constructor)) void dump() {
351
+ FILE *maps = fopen("/proc/self/maps", "r");
352
+ char line[256];
353
+ unsigned long base = 0, end = 0;
354
+
355
+ // Find the execute-only binary's mapping (r-xp or --xp)
356
+ while (fgets(line, sizeof(line), maps)) {
357
+ if (strstr(line, "binary_name")) {
358
+ sscanf(line, "%lx-%lx", &base, &end);
359
+ break;
360
+ }
361
+ }
362
+ fclose(maps);
363
+
364
+ FILE *mem = fopen("/proc/self/mem", "rb");
365
+ fseek(mem, base, SEEK_SET);
366
+ size_t size = end - base;
367
+ void *buf = malloc(size);
368
+ fread(buf, 1, size, mem);
369
+ fclose(mem);
370
+
371
+ FILE *out = fopen("/tmp/dumped_binary", "wb");
372
+ fwrite(buf, 1, size, out);
373
+ fclose(out);
374
+ }
375
+ // Usage: LD_PRELOAD=./dump_xo.so ./binary_xo
376
+ ```
377
+
378
+ **Key insight:** Execute-only prevents file reading but not execution. LD_PRELOAD constructors run inside the process where `/proc/self/mem` provides access to mapped memory regardless of file permissions.
379
+
380
+ **References:** BackdoorCTF 2017
381
+
382
+ ---
383
+
384
+ ## PEDA current_inst Bit-by-Bit Flag Scraper (CONFidence CTF 2019 Teaser)
385
+
386
+ **Pattern (Elementary):** A large obfuscated validator dispatches one `call functionN` per flag bit. Each check reads `flag[offset] >> bit & 1`, calls an opaque `functionN(that_bit)`, and compares the return with a constant. Rather than decompile hundreds of wrapper functions, drive GDB+PEDA to step through the dispatcher and read `edi` (argument) / `eax` (return) directly:
387
+
388
+ ```python
389
+ # peda.current_inst(rip) returns (addr, mnemonic_str); use it as a cheap
390
+ # disassembler to track the shift/add offsets passed to each checker.
391
+ def get_current_inst():
392
+ return peda.current_inst(peda.getreg("rip"))[1]
393
+
394
+ peda.execute('file ./elementary')
395
+ peda.set_breakpoint(0x555555554000 + 0xCEB88)
396
+ peda.execute("run < _input") # _input = 'A' * 103 (length only)
397
+
398
+ flag = ['0'] * 832 # 104 bytes * 8 bits
399
+ while peda.getreg("rip") < 0x555555554000 + 0xD827F:
400
+ offset = bit = 0
401
+ while 'and' != get_current_inst()[:3]:
402
+ cur = get_current_inst()
403
+ if cur == 'mov rax,QWORD PTR [rbp-0x18]':
404
+ offset = 0; bit = 0
405
+ elif cur.startswith('sar'):
406
+ bit = int(cur.split(',')[1], 16) # shift count -> bit index
407
+ elif cur.startswith('add'):
408
+ offset = int(cur.split(',')[1], 16) # byte index in flag
409
+ peda.execute('si')
410
+ while 'call' not in get_current_inst(): peda.execute('si')
411
+ tmp = peda.getreg('edi')
412
+ peda.execute('ni')
413
+ ret = peda.getreg('eax')
414
+ # Oracle: if return == arg the checker voted "bit=0", else "bit=1"
415
+ flag[offset * 8 + bit] = '0' if (ret != 0 and tmp == ret) else '1'
416
+ peda.execute('set $eax=0') # neutralise so loop continues
417
+ ```
418
+
419
+ **Key insight:** Any validator of the form `f_i(bit_i) == const_i` is a black-box oracle — you do not need to understand `f_i`. PEDA's `current_inst()` + `si`/`ni` give a 30-line Python scraper that harvests all bits in one run; parsing the preceding `sar imm` / `add imm` instructions recovers `(byte_offset, bit_index)` without disassembling the validator's arithmetic.
420
+
421
+ **References:** CONFidence CTF 2019 Teaser — Elementary, writeup 13927