# Spacemark

**Catégorie:** Cryptanalyse - **Difficulté:** Moyen

{% file src="/files/c4DaQJ4zsjBmHRxwmPFf" %}

**Description:**

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

Solution:

Voici le script pour répondre correctement aux attentes du système tournant derrière la connexion nc :&#x20;

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re, socket, zlib, json, sys, textwrap

HOST, PORT = "challenges.404ctf.fr", 31207
SIZE, BLOCKS = 4096, 128                        # paramètres fixes

def recv_until(sock: socket.socket, sentinel: bytes = b'>>>') -> bytes:
    data = b""
    while sentinel not in data:
        part = sock.recv(4096)
        if not part:
            break
        data += part
    return data

def extract_hex_banner(text: str) -> str:
    """Concatène toutes les lignes composées uniquement d'hexadécimal (≥32 c.)."""
    hex_lines = [l.strip() for l in text.splitlines()
                 if len(l.strip()) >= 32 and re.fullmatch(r"[0-9a-f]+", l.strip())]
    if not hex_lines:
        raise ValueError("Aucun fragment hex trouvé.")
    hx = "".join(hex_lines)
    if len(hx) % 2:                        # robustesse
        hx = hx[:-1]
    return hx

def first_pass_estimate(bits):
    """Reconstruit les 128 bits par le comptage des uns."""
    return ''.join(
        '1' if sum(bits[i*SIZE:(i+1)*SIZE]) != SIZE//2 else '0'
        for i in range(BLOCKS)
    )

def attempt_once(answer: str) -> str:
    """Ouvre une connexion, renvoie `answer`, retourne la réponse complète."""
    with socket.create_connection((HOST, PORT)) as s:
        banner = recv_until(s)             # bannière + hex + prompt
        s.sendall((answer + '\n').encode())
        return banner.decode(errors="ignore") + s.recv(4096).decode(errors="ignore")

def solve_spacemark():
    # --- 1ʳᵉ connexion : récupération du watermark compressé ---
    with socket.create_connection((HOST, PORT)) as s:
        raw = recv_until(s)                # jusqu’au prompt
        text = raw.decode(errors="ignore").lower()
        hex_clean = extract_hex_banner(text)
        bits_json = zlib.decompress(bytes.fromhex(hex_clean))
        bits = json.loads(bits_json.decode())
        if len(bits) != BLOCKS*SIZE:
            print("Watermark inattendu :", len(bits))
            sys.exit(1)

        # --- estimation puis envoi ---
        guess = first_pass_estimate(bits)
        s.sendall((guess + '\n').encode())
        reply = s.recv(4096).decode(errors="ignore")

    # --- analyse de la réponse ---
    if "Congratz" in reply:
        print(reply)                       # flag déjà obtenu
        return

    # Sinon, le serveur imprime : "Nope...\n<watermark>"
    m = re.search(r'\b[01]{128}\b', reply)
    if not m:
        print("Échec mais watermark non trouvé :\n", reply)
        sys.exit(1)

    real_mark = m.group(0)
    # --- 2ᵉ connexion, envoi de la vraie chaîne ---
    final_reply = attempt_once(real_mark)
    print(final_reply)

if __name__ == "__main__":
    solve_spacemark()
```

Le script tourne quelques secondes et nous retourne la réponse directement dans le terminal :&#x20;

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

<details>

<summary>🚩FLAG</summary>

`404CTF{LGC_4r3_no_G0od}`

</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/cryptanalyse/spacemark.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.
