$ cat writeup.md…
$ cat writeup.md…
uiuc2026
Task: An Emacs Lisp jail native-compiles one attacker-supplied form and scans the resulting function for control flow. Solution: Pass a source filename so compiler diagnostics disclose its free-symbol token before validation.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
The sacrifices we make in the name of performance...
The service reads one Emacs Lisp form, native-compiles it, checks the generated machine code, and executes it only if the checker approves. The goal is to recover the flag despite this compilation jail.
The key issue is an API type confusion at the call to native-compile. Its first argument may be either a Lisp function or a source filename, but the challenge passes the parsed user input to it without requiring a function. Supplying the string "/flag.txt" makes Emacs parse the flag file as source and print its token in a compiler warning before the jailer examines the return value.
The important logic in challenge.el is:
(let ((input (read-string "Input: "))) (unless (length< input 4096) (panic "input is too long")) (let ((code (read-from-string input))) (setq code (car code)) ;; Macro restrictions omitted here. (let ((compilation-safety 0) (compiled (native-compile code (make-temp-file "emacsjail2")))) (unless (check compiled) (panic "jailer does not approve of your program")) (message "%s" (funcall compiled)))))
The program assumes code describes a function. That assumption is not enforced: native-compile also accepts a source filename.
The check function only proceeds when its argument satisfies native-comp-function-p. For a normal function, the Zig module locates the generated ELF symbol and rejects Capstone instructions belonging to the CALL or JUMP groups. This machine-code policy is not the boundary exploited here.
The payload is a Lisp string containing the flag-file path:
"/flag.txt"
read-from-string returns that string as code. Consequently, the next operation is equivalent to native-compiling /flag.txt as an Emacs Lisp source file.
...
$ grep --similar