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.
- package/AGENTS.md +131 -0
- package/Dockerfile +192 -0
- package/README.md +522 -0
- package/agents/ctf-analyzer.md +58 -0
- package/agents/ctf-controller.md +151 -0
- package/agents/ctf-speedrun.md +74 -0
- package/bin/ctf-agent.js +119 -0
- package/docker-compose.yml +13 -0
- package/mcp_config.json +19 -0
- package/package.json +44 -0
- package/references/ctf-triage-ladder.md +68 -0
- package/references/exploit-databases.md +575 -0
- package/references/llm-safety-and-policy-compliance.md +173 -0
- package/references/multi-agent-orchestration-and-policy-routing.md +278 -0
- package/references/security-events-and-intelligence.md +566 -0
- package/references/version-matrix.md +59 -0
- package/rules/ctf-execution-rules.md +44 -0
- package/rules/ctf-safety-framing-rules.md +140 -0
- package/rules/flag-validation-rules.md +25 -0
- package/scripts/__init__.py +1 -0
- package/scripts/ctf-tools.lock +205 -0
- package/scripts/ctf_init.py +1026 -0
- package/scripts/ctf_update.py +583 -0
- package/scripts/ctfd_client.py +81 -0
- package/scripts/cve_lookup.py +453 -0
- package/scripts/extract_flags.py +155 -0
- package/scripts/install_as_agent.py +278 -0
- package/scripts/install_ctf_tools.sh +603 -0
- package/scripts/parallel_triage.py +395 -0
- package/scripts/prompt_policy_sanitizer.py +283 -0
- package/scripts/scope_guard.py +444 -0
- package/scripts/skill_validator.py +504 -0
- package/scripts/workspace_cleaner.py +141 -0
- package/skills/ctf-ai-ml/SKILL.md +120 -0
- package/skills/ctf-ai-ml/adversarial-ml.md +623 -0
- package/skills/ctf-ai-ml/llm-attacks.md +487 -0
- package/skills/ctf-ai-ml/model-attacks.md +422 -0
- package/skills/ctf-crypto/SKILL.md +320 -0
- package/skills/ctf-crypto/advanced-math.md +798 -0
- package/skills/ctf-crypto/classic-ciphers.md +651 -0
- package/skills/ctf-crypto/ecc-attacks.md +347 -0
- package/skills/ctf-crypto/exotic-crypto-2.md +380 -0
- package/skills/ctf-crypto/exotic-crypto.md +528 -0
- package/skills/ctf-crypto/historical.md +113 -0
- package/skills/ctf-crypto/lattice-and-lwe.md +524 -0
- package/skills/ctf-crypto/modern-ciphers-2.md +563 -0
- package/skills/ctf-crypto/modern-ciphers-3.md +453 -0
- package/skills/ctf-crypto/modern-ciphers.md +649 -0
- package/skills/ctf-crypto/prng-attacks.md +257 -0
- package/skills/ctf-crypto/prng.md +664 -0
- package/skills/ctf-crypto/rsa-attacks-2.md +792 -0
- package/skills/ctf-crypto/rsa-attacks.md +487 -0
- package/skills/ctf-crypto/stream-ciphers.md +390 -0
- package/skills/ctf-crypto/zkp-and-advanced.md +456 -0
- package/skills/ctf-forensics/3d-printing.md +121 -0
- package/skills/ctf-forensics/SKILL.md +379 -0
- package/skills/ctf-forensics/disk-advanced.md +497 -0
- package/skills/ctf-forensics/disk-and-memory.md +491 -0
- package/skills/ctf-forensics/disk-recovery.md +699 -0
- package/skills/ctf-forensics/linux-forensics.md +511 -0
- package/skills/ctf-forensics/network-advanced.md +583 -0
- package/skills/ctf-forensics/network.md +645 -0
- package/skills/ctf-forensics/peripheral-capture.md +287 -0
- package/skills/ctf-forensics/signals-and-hardware.md +713 -0
- package/skills/ctf-forensics/steganography.md +694 -0
- package/skills/ctf-forensics/stego-advanced-2.md +475 -0
- package/skills/ctf-forensics/stego-advanced.md +481 -0
- package/skills/ctf-forensics/stego-image.md +691 -0
- package/skills/ctf-forensics/windows.md +625 -0
- package/skills/ctf-malware/SKILL.md +181 -0
- package/skills/ctf-malware/c2-and-protocols.md +274 -0
- package/skills/ctf-malware/pe-and-dotnet.md +108 -0
- package/skills/ctf-malware/scripts-and-obfuscation.md +449 -0
- package/skills/ctf-misc/SKILL.md +498 -0
- package/skills/ctf-misc/bashjails.md +323 -0
- package/skills/ctf-misc/ctfd-navigation.md +465 -0
- package/skills/ctf-misc/dns.md +255 -0
- package/skills/ctf-misc/encodings-advanced.md +504 -0
- package/skills/ctf-misc/encodings.md +431 -0
- package/skills/ctf-misc/games-and-vms-2.md +254 -0
- package/skills/ctf-misc/games-and-vms-3.md +690 -0
- package/skills/ctf-misc/games-and-vms-4.md +229 -0
- package/skills/ctf-misc/games-and-vms.md +529 -0
- package/skills/ctf-misc/linux-privesc.md +333 -0
- package/skills/ctf-misc/pyjails.md +671 -0
- package/skills/ctf-misc/rf-sdr.md +91 -0
- package/skills/ctf-osint/SKILL.md +198 -0
- package/skills/ctf-osint/geolocation-and-media.md +464 -0
- package/skills/ctf-osint/social-media.md +312 -0
- package/skills/ctf-osint/web-and-dns.md +341 -0
- package/skills/ctf-pwn/SKILL.md +214 -0
- package/skills/ctf-pwn/advanced-exploits-2.md +579 -0
- package/skills/ctf-pwn/advanced-exploits-3.md +598 -0
- package/skills/ctf-pwn/advanced-exploits-4.md +590 -0
- package/skills/ctf-pwn/advanced-exploits-5.md +119 -0
- package/skills/ctf-pwn/advanced-exploits.md +773 -0
- package/skills/ctf-pwn/advanced.md +326 -0
- package/skills/ctf-pwn/field-notes.md +245 -0
- package/skills/ctf-pwn/format-string.md +694 -0
- package/skills/ctf-pwn/heap-fsop.md +285 -0
- package/skills/ctf-pwn/heap-techniques-2.md +333 -0
- package/skills/ctf-pwn/heap-techniques.md +513 -0
- package/skills/ctf-pwn/kernel-bypass.md +421 -0
- package/skills/ctf-pwn/kernel-techniques.md +366 -0
- package/skills/ctf-pwn/kernel.md +636 -0
- package/skills/ctf-pwn/overflow-basics.md +611 -0
- package/skills/ctf-pwn/rop-advanced.md +725 -0
- package/skills/ctf-pwn/rop-and-shellcode.md +659 -0
- package/skills/ctf-pwn/sandbox-escape.md +313 -0
- package/skills/ctf-reverse/SKILL.md +163 -0
- package/skills/ctf-reverse/anti-analysis-ctf.md +204 -0
- package/skills/ctf-reverse/anti-analysis.md +693 -0
- package/skills/ctf-reverse/field-notes.md +376 -0
- package/skills/ctf-reverse/languages-compiled.md +666 -0
- package/skills/ctf-reverse/languages-platforms.md +592 -0
- package/skills/ctf-reverse/languages.md +553 -0
- package/skills/ctf-reverse/patterns-ctf-2.md +397 -0
- package/skills/ctf-reverse/patterns-ctf-3.md +797 -0
- package/skills/ctf-reverse/patterns-ctf.md +670 -0
- package/skills/ctf-reverse/patterns-runtime.md +274 -0
- package/skills/ctf-reverse/patterns.md +572 -0
- package/skills/ctf-reverse/platforms-hardware.md +387 -0
- package/skills/ctf-reverse/platforms.md +664 -0
- package/skills/ctf-reverse/tools-advanced-2.md +421 -0
- package/skills/ctf-reverse/tools-advanced.md +407 -0
- package/skills/ctf-reverse/tools-dynamic.md +679 -0
- package/skills/ctf-reverse/tools-emulation.md +319 -0
- package/skills/ctf-reverse/tools.md +573 -0
- package/skills/ctf-web/SKILL.md +153 -0
- package/skills/ctf-web/auth-and-access-2.md +82 -0
- package/skills/ctf-web/auth-and-access.md +783 -0
- package/skills/ctf-web/auth-infra.md +321 -0
- package/skills/ctf-web/auth-jwt.md +186 -0
- package/skills/ctf-web/client-side-advanced.md +739 -0
- package/skills/ctf-web/client-side.md +529 -0
- package/skills/ctf-web/cves.md +373 -0
- package/skills/ctf-web/field-notes.md +482 -0
- package/skills/ctf-web/node-and-prototype.md +200 -0
- package/skills/ctf-web/server-side-2.md +337 -0
- package/skills/ctf-web/server-side-advanced-2.md +559 -0
- package/skills/ctf-web/server-side-advanced-3.md +125 -0
- package/skills/ctf-web/server-side-advanced-4.md +480 -0
- package/skills/ctf-web/server-side-advanced.md +378 -0
- package/skills/ctf-web/server-side-deser.md +443 -0
- package/skills/ctf-web/server-side-exec-2.md +799 -0
- package/skills/ctf-web/server-side-exec.md +457 -0
- package/skills/ctf-web/server-side.md +629 -0
- package/skills/ctf-web/sql-injection.md +790 -0
- package/skills/ctf-web/web3.md +374 -0
- package/skills/ctf-writeup/SKILL.md +90 -0
- package/skills/solve-challenge/SKILL.md +269 -0
- package/skills.json +16 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# CTF Misc - Games, VMs & Constraint Solving (Part 4)
|
|
2
|
+
|
|
3
|
+
Additional CTF-era challenges extracted from 2018+ writeups. For earlier parts, see [games-and-vms.md](games-and-vms.md), [games-and-vms-2.md](games-and-vms-2.md), and [games-and-vms-3.md](games-and-vms-3.md).
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [XSLT as Turing-Complete VM for Binary Search (35C3 2018)](#xslt-as-turing-complete-vm-for-binary-search-35c3-2018)
|
|
7
|
+
- [JavaScript MAX_SAFE_INTEGER Successor Equality (35C3 2018)](#javascript-max_safe_integer-successor-equality-35c3-2018)
|
|
8
|
+
- [Binary Search Oracle in Comparison-Only DSL (35C3 2018)](#binary-search-oracle-in-comparison-only-dsl-35c3-2018)
|
|
9
|
+
- [Blind SQLi via Script-Engine Timeout Error (35C3 2018)](#blind-sqli-via-script-engine-timeout-error-35c3-2018)
|
|
10
|
+
- [OEIS Sequence Lookup Automation for Recurrence Puzzles (X-MAS CTF 2018)](#oeis-sequence-lookup-automation-for-recurrence-puzzles-x-mas-ctf-2018)
|
|
11
|
+
- [QR Code Reassembly from Format-String Structural Constraints (Square CTF 2018)](#qr-code-reassembly-from-format-string-structural-constraints-square-ctf-2018)
|
|
12
|
+
- [Matrix Exponentiation for Fibonacci-Like Recurrence (Pwn2Win 2018)](#matrix-exponentiation-for-fibonacci-like-recurrence-pwn2win-2018)
|
|
13
|
+
- [Tribonacci Recurrence for Frog Jump Counting (FireShell 2019)](#tribonacci-recurrence-for-frog-jump-counting-fireshell-2019)
|
|
14
|
+
- [Selenium + Tesseract for Dynamic Font CAPTCHA (Square CTF 2018)](#selenium--tesseract-for-dynamic-font-captcha-square-ctf-2018)
|
|
15
|
+
- [Brainfuck Decodes Piet Image URL — Multi-Layer Polyglot (RITSEC 2018)](#brainfuck-decodes-piet-image-url--multi-layer-polyglot-ritsec-2018)
|
|
16
|
+
- [Bytebeat Synth Code Recognition for Hidden Audio (RITSEC 2018)](#bytebeat-synth-code-recognition-for-hidden-audio-ritsec-2018)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## XSLT as Turing-Complete VM for Binary Search (35C3 2018)
|
|
21
|
+
|
|
22
|
+
**Pattern:** Challenge only executes XSLT templates. `<xsl:choose>`, `<xsl:call-template>` with recursion, and `<xsl:variable>` form a full Turing-complete runtime with a stack. Encode a binary-search oracle: `<drinks>` elements hold the stack, `<plate>` elements are instructions, `<course>` blocks act as labels.
|
|
23
|
+
|
|
24
|
+
```xml
|
|
25
|
+
<xsl:template name="step">
|
|
26
|
+
<xsl:param name="lo"/><xsl:param name="hi"/>
|
|
27
|
+
<xsl:variable name="mid" select="($lo + $hi) div 2"/>
|
|
28
|
+
<xsl:choose>
|
|
29
|
+
<xsl:when test="$target = $mid">...found...</xsl:when>
|
|
30
|
+
<xsl:when test="$target < $mid">
|
|
31
|
+
<xsl:call-template name="step">
|
|
32
|
+
<xsl:with-param name="lo" select="$lo"/>
|
|
33
|
+
<xsl:with-param name="hi" select="$mid"/>
|
|
34
|
+
</xsl:call-template>
|
|
35
|
+
</xsl:when>
|
|
36
|
+
...
|
|
37
|
+
</xsl:choose>
|
|
38
|
+
</xsl:template>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Key insight:** Any "pure template" language with named recursion and conditionals is a VM. Build a primitive (binary search, bit extraction, state accumulator) out of its native constructs before trying to escape the sandbox.
|
|
42
|
+
|
|
43
|
+
**References:** 35C3 CTF 2018 — Juggle, writeup 12803
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## JavaScript MAX_SAFE_INTEGER Successor Equality (35C3 2018)
|
|
48
|
+
|
|
49
|
+
**Pattern:** Challenge asserts `x !== x + 1`. For `x = Number.MAX_SAFE_INTEGER + 1 === 9007199254740992`, IEEE 754 rounding makes `x + 1 === x` true, so the assertion passes and the check is bypassed.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
let x = 9007199254740992; // 2^53
|
|
53
|
+
console.log(x === x + 1); // true
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Key insight:** Any numeric invariant that compares `n` to `n + 1` fails at the float boundary. Test with `2^53`, `Infinity`, `NaN`, and `-0 === 0` combinations when a JS check looks like it's making assumptions about arithmetic.
|
|
57
|
+
|
|
58
|
+
**References:** 35C3 CTF 2018 — Number Error, writeup 12828
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Binary Search Oracle in Comparison-Only DSL (35C3 2018)
|
|
63
|
+
|
|
64
|
+
**Pattern:** Challenge DSL only exposes comparisons against a secret value. Convert it into a full oracle by subtracting decreasing powers of two (`2^30, 2^29, ..., 2^0`) from an initial guess, adding whenever the comparison reports "less than" and subtracting when "greater than".
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
guess = 0
|
|
68
|
+
for shift in range(30, -1, -1):
|
|
69
|
+
guess += 1 << shift
|
|
70
|
+
if oracle(guess) > 0: # guess too high
|
|
71
|
+
guess -= 1 << shift
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Key insight:** Any boolean comparator gives you binary search in `O(log N)` queries. The same trick collapses any comparison-based leak — regex match, timing channel, HTTP status code — into the full value.
|
|
75
|
+
|
|
76
|
+
**References:** 35C3 CTF 2018 — Juggle, writeup 12803
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Blind SQLi via Script-Engine Timeout Error (35C3 2018)
|
|
81
|
+
|
|
82
|
+
**Pattern:** Server evaluates `eval` of a user-supplied snippet with a tight timeout. Wrap the payload in `if charAt(FLAG, pos) == '?' then pause(10000) end` — correct characters hang until the timeout triggers an error; wrong characters return instantly. Treat the timeout as a truthy bit.
|
|
83
|
+
|
|
84
|
+
```lua
|
|
85
|
+
-- blind timing oracle in Lua eval sandbox
|
|
86
|
+
for c in printable do
|
|
87
|
+
send(("if charAt(FLAG, %d) == '%s' then pause(10000) end"):format(i, c))
|
|
88
|
+
if response_time > 5 then flag = flag .. c; break end
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Key insight:** Script-eval services with timeouts are stateful oracles: any long-running expression leaks a boolean via the wall-clock difference between timeout and instant return.
|
|
93
|
+
|
|
94
|
+
**References:** 35C3 CTF 2018 — dev/null, writeups 12830, 12871
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## OEIS Sequence Lookup Automation for Recurrence Puzzles (X-MAS CTF 2018)
|
|
99
|
+
|
|
100
|
+
**Pattern:** Server asks for the next term in a mathematical sequence. Automate the lookup: query https://oeis.org/search?q=1,1,2,5,14, parse the first result with pyquery, extract the `Next term`, send it back. Wrap around a MD5 captcha brute force for PoW-protected services.
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import requests
|
|
104
|
+
from pyquery import PyQuery as pq
|
|
105
|
+
r = requests.get('https://oeis.org/search', params={'q': ','.join(map(str, seq))})
|
|
106
|
+
doc = pq(r.text)
|
|
107
|
+
next_term = doc('pre').eq(1).text().split(',')[len(seq)]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Key insight:** Any integer-sequence puzzle is solved in one HTTP request via OEIS. The hard part is the wrapper (captcha, PoW, socket framing) — automate that once and the math stops being the bottleneck.
|
|
111
|
+
|
|
112
|
+
**References:** X-MAS CTF 2018 — A Weird List of Sequences, writeup 12683
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## QR Code Reassembly from Format-String Structural Constraints (Square CTF 2018)
|
|
117
|
+
|
|
118
|
+
**Pattern:** Challenge ships shredded 1-pixel columns of a QR code. Instead of brute-forcing `21!` permutations, anchor on QR invariants: the three finder patterns, the timing pattern between them, the fixed dark module, and the 15-bit format string at column 8 has only 32 valid values (EC level × mask pattern). Filter slices by structural constraints, then permute only the remaining few.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
wanted_formats = load_32_valid_qr_formats()
|
|
122
|
+
for col in slices:
|
|
123
|
+
if col[:7] in wanted_formats_column_8:
|
|
124
|
+
candidate_cols.append(col)
|
|
125
|
+
for perm in itertools.permutations(candidate_cols):
|
|
126
|
+
if decode_qr(np.stack(perm)):
|
|
127
|
+
return perm
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Key insight:** Format-specific constraints collapse permutation spaces. QR Version 1 has only 32 possible format strings; anchor on them to prune before brute-forcing.
|
|
131
|
+
|
|
132
|
+
**References:** Square CTF 2018 — C3: Shredded, writeup 12331
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Matrix Exponentiation for Fibonacci-Like Recurrence (Pwn2Win 2018)
|
|
137
|
+
|
|
138
|
+
**Pattern:** Challenge asks for the `N`-th term of a recurrence `a_{n+1} = f(a_n, a_{n-1})` with `N` up to `10^12`. Naive iteration is impossible. Write the update as a 2×2 matrix product `[a_{n+1}; a_n] = M * [a_n; a_{n-1}]` and compute `M^N` in `O(log N)` with binary exponentiation.
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
MOD = 10**9 + 7
|
|
142
|
+
def matmult(a, b):
|
|
143
|
+
return ((a[0]*b[0] + a[1]*b[2]) % MOD, (a[0]*b[1] + a[1]*b[3]) % MOD,
|
|
144
|
+
(a[2]*b[0] + a[3]*b[2]) % MOD, (a[2]*b[1] + a[3]*b[3]) % MOD)
|
|
145
|
+
def matpow(M, n):
|
|
146
|
+
R = (1,0,0,1)
|
|
147
|
+
while n:
|
|
148
|
+
if n & 1: R = matmult(R, M)
|
|
149
|
+
M = matmult(M, M); n >>= 1
|
|
150
|
+
return R
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Key insight:** Any linear recurrence over a ring is reducible to matrix exponentiation. Use it whenever the challenge exposes a giant `N` for a classical-looking sequence — Fibonacci, Tribonacci, Lucas, linear Pisano, RNG counters.
|
|
154
|
+
|
|
155
|
+
**References:** Pwn2Win CTF 2018 — Too Slow, writeup 12501
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Tribonacci Recurrence for Frog Jump Counting (FireShell 2019)
|
|
160
|
+
|
|
161
|
+
**Pattern:** A proof-of-work handshake asks how many ways a frog can reach step `N` if it can jump 1, 2, or 3 steps. That is `f(N) = f(N-1) + f(N-2) + f(N-3)` — the Tribonacci sequence. Precompute modulo the server's modulus; for large `N`, combine with matrix exponentiation above.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
def tribonacci(N, MOD=13371337):
|
|
165
|
+
a, b, c = 0, 0, 1
|
|
166
|
+
for _ in range(N):
|
|
167
|
+
a, b, c = b, c, (a + b + c) % MOD
|
|
168
|
+
return c
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Key insight:** "Number of ways to climb N stairs with step sizes {1..k}" is always a linear recurrence. Memoize up to the server's max `N`, cache across requests, and keep the tribonacci identity in mind when the challenge text mentions "frog".
|
|
172
|
+
|
|
173
|
+
**References:** FireShell CTF 2019 — Frogs, writeup 12961
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Selenium + Tesseract for Dynamic Font CAPTCHA (Square CTF 2018)
|
|
178
|
+
|
|
179
|
+
**Pattern:** A CAPTCHA generates math expressions with a random glyph font and rerenders every 5 seconds. Full-window screenshots via Selenium feed Tesseract OCR; clean up Tesseract's common confusions (`x`→`*`, `{`→`(`) before `eval()`.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from selenium import webdriver
|
|
183
|
+
from PIL import Image
|
|
184
|
+
import pytesseract, io
|
|
185
|
+
d = webdriver.Chrome()
|
|
186
|
+
d.get(URL); d.execute_script("document.body.style.zoom='450%'")
|
|
187
|
+
img = Image.open(io.BytesIO(d.get_screenshot_as_png()))
|
|
188
|
+
expr = pytesseract.image_to_string(img).replace('x','*').replace('{','(').replace('}',')')
|
|
189
|
+
d.execute_script(f"document.getElementsByName('answer')[0].value={eval(expr)}")
|
|
190
|
+
d.find_element_by_tag_name('form').submit()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Key insight:** Dynamic CAPTCHAs are often too short-lived for manual solves but trivial for a 1-second Selenium + Tesseract loop. When OCR alone fails, pair it with a cmap reference library (see ctf-osint/web-and-dns.md).
|
|
194
|
+
|
|
195
|
+
**References:** Square CTF 2018 — C8, writeups 12160, 12178
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Brainfuck Decodes Piet Image URL — Multi-Layer Polyglot (RITSEC 2018)
|
|
200
|
+
|
|
201
|
+
**Pattern:** Recognise the three most common esolangs stacked together: Brainfuck source outputs a YouTube URL, the video's thumbnail border is a Piet program whose execution prints the flag. Use `bf` → `yt-dlp` → strip border pixels → `npiet` pipeline.
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
bf puzzle.bf # prints youtube.com/watch?v=XXXX
|
|
205
|
+
yt-dlp -x --write-thumbnail "$URL" # grabs JPG thumbnail
|
|
206
|
+
python crop_border.py thumb.jpg > piet.png
|
|
207
|
+
npiet piet.png # prints the flag
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Key insight:** Multi-layer esolangs are recognisable by eye: Brainfuck is `+-<>.,[]`, Piet is colored block grids, Whitespace is invisible. If a challenge description mentions multiple "weird" formats, pipeline the decoders in order.
|
|
211
|
+
|
|
212
|
+
**References:** RITSEC CTF 2018 — writeup 12224
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Bytebeat Synth Code Recognition for Hidden Audio (RITSEC 2018)
|
|
217
|
+
|
|
218
|
+
**Pattern:** A short C-like one-liner is bytebeat — a generative music format where `t` is a monotonic sample counter. Paste into an online interpreter (http://wry.me/bytebeat/) to hear it; the resulting tune is a recognizable song whose title is the flag.
|
|
219
|
+
|
|
220
|
+
```c
|
|
221
|
+
/* Bytebeat example: output byte = low 8 bits of this expression */
|
|
222
|
+
(t * ((t >> 12 | t >> 8) & 63 & t >> 4))
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Key insight:** Recognise bytebeat by (a) a `t` variable, (b) bitshifts mixed with modulo, (c) output of size 8-bit unsigned integer. `%`, `|`, `&`, `^`, `>>`, `<<` on `t` are the bytebeat signature. No decoding needed — just play it.
|
|
226
|
+
|
|
227
|
+
**References:** RITSEC CTF 2018 — writeups 12261, 12268
|
|
228
|
+
|
|
229
|
+
---
|