QuickJS-ng DataView refcount UAF to __exit_funcs
| Event Name |
C2C 2026 Quals |
| GitHub URL |
- |
| Challenge Name |
lightspeed |
- Root cause:
js_dataview_constructor stores the backing ArrayBuffer pointer without js_dup(buffer), so the DataView does not own a refcount on the buffer object and can outlive a freed/reclaimed JSArrayBuffer.
- Final exploit chain: reclaim freed
JSArrayBuffer state with a typed-array-backed object, pivot the DataView into arbitrary read/write, leak PIE from js_array_buffer_free, leak libc from malloc@GOT, recover pointer_guard from AT_RANDOM, then overwrite __exit_funcs[0] with mangled system("/app/getflag").
- Environment caveats: the working offsets target Debian glibc
2.41; the exploit is probabilistic and often fails at the Stage 0b detached-check bypass before succeeding on retry.
- Local validation: rebuilt
challenge/Dockerfile with a local placeholder getflag and confirmed python3 solve.py --host 127.0.0.1 --port 5003 --js exploit_aslr_final.js --delay 0.35 --attempts 10 returns FAKE{local_test_flag} from a clean build on March 9, 2026.
- Remote status:
challenges.1pc.tf:29786 timed out on March 9, 2026, but the same payload previously recovered the real challenge flag.
- why it is vulnerable
- exploit payload
- solver
cornelslop kernel RCU double-queue to pipe-page reclaim
| Event Name |
DiceCTF Quals 2026 |
| Source URL |
- |
| Challenge Name |
cornelslop |
- Root cause:
check_entry() keeps a stale xa_load() result across the SHA256 walk, and on mismatch it calls destruct_entry(e) even if xa_erase() already lost the entry. That queues the same rcu_head twice.