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.

18 i386 ELFs9 challengesidentical rank-1next_argv empty1 / 9 hop hits0 model calls
Result

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.

unpatched · cgc_check · 0x08048a00
char string[64];
cgc_receive_delim(0, string, 0x80, '\n');
patched · cgc_check · 0x08048a00
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.

unpatched · cgc_list_unread_messages · 0x0804a7e0
uchar count;
count = '\0';
count = count + '\x01';
patched · cgc_list_unread_messages · 0x0804a7e0
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.

POLLpass / pass

Palindrome for-testing and three basic_messaging release POLLs completed on both variants.

POVunproven core

Official type 1 POVs did not register a core on unpatched under qemu-user. Patched POVs correctly did not core. gdb was absent.

Quick brief~20 s wall

Four parallel briefs, median of three rounds. Sequential sum 54.4 s. Kali Pi 5, r2b 0.1.0, radare2 6.0.5.

Ghidraexplicit decompile

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.

Isolationno egress

linux/amd64, network none, read-only root, tmpfs scratch, uid 65534, capabilities dropped, no-new-privileges.

Builderclang 6.0 i386

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.

Download case JSONRead the repo notes ↗