Recorded run · DARPA CGC · i386
The brief stayed at main. Address hops hit one planted site in nine.
Quick briefs ranked only entry:main. handoff.next_argv was empty on this set. Function VAs live on handoff.regions[].addr. An explicit r2b decompile BIN ADDR, then at most two named callee hops, reached Palindrome's planted function once. That hop experiment is not the current auto-queue.
Every quick brief ranked only entry:main. Current next_argv does not queue r2b decompile; empty is valid here. Hops from the ranked region address decompiled cgc_check on Palindrome (64-byte buffer, receive 0x80 vs 0x40). The same hop budget missed cgc_list_unread_messages on basic_messaging and missed six other frozen challenges. A source-named decompile of that unread counter is not this loop.
01 · THE BRIEF STOPS AT MAIN
No libc pivot, so no pair split.
All four binaries are 32-bit x86 ELFs with debug info. radare2 counts 28 functions in Palindrome and 101 in basic_messaging. Five imports, none of them the usual dangerous libc names. Rules review keeps entry:main as needs_confirmation / lead. Ranks 3 and 5 are empty.
Palindrome entry:main
Palindrome_patched entry:main
basic_messaging entry:main
basic_messaging_patched entry:main
verify was not forced. There is no relevant external import sink. These services import libcgc, not system/popen/exec*, so current next_argv is empty. Function VAs live on handoff.regions[].addr.
01b · PROTOCOL
Brief, then the ranked address. Decompile is explicit.
Current product path: read the brief, take the region address, optionally run r2b decompile BIN ADDR. next_argv may queue verify --import system|popen|exec*, extract/brief on wrappers, or records show when saved. It does not auto-queue decompile.
r2b brief Palindrome --quick --no-save --json
# handoff.next_argv: []
# handoff.regions[].addr → main @ 0x08048880
r2b decompile Palindrome 0x08048880 --json # explicit, not auto-queued
The 1 / 9 site-hit figure is a recorded hop experiment from that ranked address, then at most two extra named callees. It is not the current auto-queue.
01c · FROZEN SAMPLE, BLIND HOPS
Palindrome is the easy sample. The stride is not.
Selection was frozen before the run: Palindrome, basic_messaging, then every 28th name in linux-working.txt from line 8. Historical hop protocol: brief, decompile the ranked address, at most two extra named callees. No README at runtime. That experiment is labeled here so it is not mistaken for auto-queued next_argv.
challenge planted site hop experiment
Palindrome cgc_check CWE-121 site: 0x80 vs 0x40
basic_messaging list_unread_messages CWE-190 miss (handle_menu)
ASL6parse print_oid CWE-125 miss (memset/exit)
CNMP insert_joke format string name as callee only
FISHYXML parse_xml_cards miss (play_game)
Matchmaker magic_onmatch CWE-201 miss (dfa_init)
Overflow_Parking malloc CWE-190 miss (list_init)
root64_and_parcour page_root64 CWE-121 miss (malloc)
stream_vm2 process_sys CWE-129 miss (read_header)
Site decompiled: 1 / 9. Name visible as a callee: 2 / 9. The hop budget followed first callees, including libc helpers such as memset and strlen.
02 · SNIPPET
Twelve lines of prologue. The full pdf names the helper.
--quick snippets are r2 pdf after af. That listing is function-aware; it does not tear a c7 invalid opcode. Palindrome's full pdf @ main already prints call dbg.cgc_check. The 12-line capsule is still the prologue and may not include that call.
12-line capsule @ entry:main full pdf @ main after af
frame setup / prologue ...
call dbg.cgc_check
r2 already names the helper from pdf @ main. The briefing capsule is a 12-line cut of that listing, not a decompile, and not a CWE label.
03 · PALINDROME
The buffer is 64 bytes. Only the receive length changes.
char string[64];
cgc_receive_delim(0, string, 0x80, '\n');
char string[64];
cgc_receive_delim(0, string, 0x40, '\n');
radare2 shows the same cut at 0x08048a41: mov ecx, 0x80 versus mov ecx, 0x40. DWARF names the function cgc_check. CWE-121 is the planted class. Reaching this site required an explicit decompile of ranked main, then one callee hop. Current next_argv does not queue that decompile.
04 · BASIC_MESSAGING
The counter widens from a byte to a dword.
uchar count;
count = '\0';
count = count + '\x01';
uint count;
count = 0;
count = count + 1;
The unread-message count is the size input for the display buffer. A wrap above 255 is the planted CWE-190. The hop from ranked main stopped at cgc_handle_menu. Reaching this function required a source-supplied name, which is not the advertised loop.
05 · LABELED SOURCES
The names and bounds already existed. The CRS scores did not make this look easy.
Palindrome is official sample CADET_00001. The author README is CWE-121: 64-byte stack, read up to 128. angr publishes it as a crash-finding tutorial (unconstrained EIP, plus the ^ easter egg). KLEE on the Linux port reports the overflow at service.c:65 almost immediately. Those tools generate crashing input. r2b reached the same bound in cgc_check and did not emit a crash.
basic_messaging is CQE qualifier CROMU_00001. The MIT LL archive names list_unread_messages(), an 8-bit wrap above 255, and a crash in strlen. CQE scores maxed at 1.85 / 4 (CodeJitsu). ForAllSecure scored 0.58. Shellphish and Trail of Bits scored 0; Trail of Bits still proved a reference POV. The official POV creates userone and usertwo, then sends 256+ messages to the other user. Self-send is not enough. The hop experiment did not reach that function. A source-named decompile of the byte-versus-dword count is a different pass.
level Palindrome basic_messaging r2b
CWE 121 190 → 131 → 120 after decompile
PATCHED ifdef sizeof(string) vs 128 uint vs uchar count same sites
DWARF cgc_check @ 0x08048a00 list_unread @ 0x0804a7e0 yes
instruction mov ecx, 0x80 vs 0x40 byte vs dword count yes
POLL race / racecar protocol only pass
POV type1, 147-byte write 2 users, 256+ cross-sends core unproven
angr/KLEE unconstrained EIP (no tutorial) no crash input
CQE score n/a (sample) max 1.85/4 not a CRS
DECREE sample addresses (angr's easter egg at 0x804833E) do not match this cb-multios Linux build. Compare labels and patch semantics, not raw DECREE VAs.
06 · RUNTIME AND TIMING
POLLs passed. Type 1 POVs did not prove a core here.
Palindrome for-testing and three basic_messaging release POLLs completed on both variants.
Official type 1 POVs did not register a core on unpatched under qemu-user. Patched POVs correctly did not core. gdb was absent.
Four parallel briefs, median of three rounds. Sequential sum 54.4 s. Kali Pi 5, r2b 0.1.0, radare2 6.0.5.
r2b decompile returned empty C until ~ expansion and a Ghidra-legal project dir (~/r2b/ghidra-projects). analyzeHeadless rejects .local path elements. That command is still opt-in.
linux/amd64, network none, read-only root, tmpfs scratch, uid 65534, capabilities dropped, no-new-privileges.
ubuntu:18.04 image sha256:560a44be…4245e6aa. Default 32-bit x86 flags kept.
THE HONEST CLAIM
r2b did not discover the CWE. Hops from ranked main reached Palindrome and missed the rest of the stride.
On Palindrome, r2 pdf @ main after af already names cgc_check. The 12-line briefing snippet is still the prologue. Current next_argv is empty here; it does not decompile main. The 1 / 9 hop result is a recorded experiment from handoff.regions[].addr, not auto-queued Ghidra. That glue is real and narrow. It is not a CRS, and it is not a reason to lead with two hand-picked binaries.