$ cat writeup.md…
$ cat writeup.md…
UIUCTF 2026
Task: Lua 5.5.0 server accepts length-prefixed binary bytecode with no verification (luai_verifycode is empty). No os/io libs, load/loadfile/dofile removed. Solution: Patch compiled bytecode upvalue indices to create type confusion between LClosure and TString, build arbitrary read/write primitives via fake Proto/TString/UpVal structures, leak PIE base and libc via CClosure function pointer, overwrite fwrite@GOT with system() for RCE.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Elio's script never accounted for untrusted bytecode.
Firefly's Complete Combustion simulator accepts one length-prefixed Lua 5.5.0 binary combat script on each connection. The usual escape hatches are gone, but the bytecode loader still trusts you completely.
ncat --ssl firefly-complete-combustion.chal.uiuc.tf 1337
English summary: A server reads a 4-byte big-endian length followed by a Lua 5.5.0 binary bytecode chunk. It loads it with luaL_loadbufferx(L, chunk, len, "@complete-combustion", "b") (binary-only mode) and executes it. Available libraries: base, coroutine, table, string, math, utf8. The functions dofile, load, and loadfile are removed. The flag is at /flag.txt. The key vulnerability is that Lua 5.5.0's luai_verifycode(L,f) macro is defined as empty — the bytecode loader performs no verification of bytecode integrity.
The server is straightforward:
\x1bLua signature)luaL_loadbufferx in binary-only modelua_pcallLibraries loaded: base, coroutine, table, string, math, utf8. No os, io, debug, or package libraries. The load, loadfile, and dofile globals are explicitly removed, preventing source-code loading.
Lua 5.5.0's bytecode loader (luaU_undump in lundump.c) trusts the bytecode completely. The luai_verifycode(L,f) macro that should validate bytecode integrity is defined as empty (a no-op). This means we can:
luac to get well-formed bytecodeUnderstanding the memory layout is critical for crafting fake objects:
...
$ grep --similar