hackday-2026
PROGRAMMING - Fasty
2026-01-28medium#programming#python#netcat#automation#parsing
On doit répondre à une série de 10 questions en moins d'une seconde — impossible à faire à la main. On écrit un script Python qui se connecte en netcat, parse chaque question et envoie la bonne réponse automatiquement.
Approche
Les questions sont toujours dans le même ordre, seules les valeurs changent. Il suffit de :
- Se connecter au serveur via
nc - Lire chaque ligne reçue
- Identifier la question avec une regex
- Calculer et envoyer la réponse
Script
import subprocess import threading import queue import re import hashlib def netcat_sender(host, port, input_queue, output_queue): proc = subprocess.Popen( ["nc", host, str(port)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, universal_newlines=True ) def read_output(): buffer = "" while True: line = proc.stdout.readline() if not line: break buffer += line while "\n" in buffer: msg, buffer = buffer.split("\n", 1) output_queue.put(msg.strip()) threading.Thread(target=read_output, daemon=True).start() while True: try: msg = input_queue.get(timeout=1) proc.stdin.write(msg + "\n") proc.stdin.flush() except queue.Empty: if proc.poll() is not None: break proc.terminate() def solve_question(question): question = question.strip() # Q1: Opérations arithmétiques m = re.search(r"Q1: (\d+) \* (\d+)", question) if m: a, b = map(int, m.groups()) return str(a * b) m = re.search(r"Q1: (\d+) \+ (\d+)", question) if m: a, b = map(int, m.groups()) return str(a + b) m = re.search(r"Q1: (\d+) \- (\d+)", question) if m: a, b = map(int, m.groups()) return str(a - b) m = re.search(r"Q1: (\d+) \/ (\d+)", question) if m: a, b = map(int, m.groups()) return str(a / b) # Q2: Reverse string m = re.search(r"Q2: Reverse this string: '([^']+)'", question) if m: return m.group(1)[::-1] # Q3: SHA256 m = re.search(r"Q3: Give the SHA256 hash \(hex\) of '([^']+)'", question) if m: return hashlib.sha256(m.group(1).encode()).hexdigest() # Q4: Minimum m = re.search(r"Q4: Find the smallest number in \[([^\]]+)\]", question) if m: return str(min(map(int, m.group(1).split(", ")))) # Q5: Mots > 5 caractères m = re.search(r"Q5: From \[([^\]]+)\], keep only words > 5 chars", question) if m: words = m.group(1).replace("'", "").split(", ") return ",".join([w for w in words if len(w) > 5]) # Q6: XOR m = re.search(r"Q6: What is (\d+) XOR (\d+) \(decimal\)", question) if m: a, b = map(int, m.groups()) return str(a ^ b) # Q7: Chiffrement César +3 m = re.search(r"Q7: Apply Caesar cipher \(\+3\) to '([^']+)'", question) if m: s = m.group(1) return "".join([chr(((ord(c) - ord('a') + 3) % 26) + ord('a')) for c in s]) # Q8: Poids de Hamming m = re.search(r"Q8: Hamming weight of (\d+)", question) if m: return str(bin(int(m.group(1))).count("1")) # Q9: Conversion binaire m = re.search(r"Q9: Convert (\d+) to binary", question) if m: return bin(int(m.group(1)))[2:] # Q10: Formatage adresse MAC m = re.search(r"Q10: Format '([^']+)' as a MAC address", question) if m: s = m.group(1) return ":".join([s[i:i+2] for i in range(0, len(s), 2)]) return None if __name__ == "__main__": host = "51.210.244.18" port = 8677 input_queue = queue.Queue() output_queue = queue.Queue() nc_thread = threading.Thread( target=netcat_sender, args=(host, port, input_queue, output_queue) ) nc_thread.daemon = True nc_thread.start() while True: try: msg = output_queue.get(timeout=1) print(msg) if "Q" in msg: answer = solve_question(msg) if answer is not None: print(f"Réponse envoyée : {answer}") input_queue.put(answer) except queue.Empty: continue
Questions traitées
| Question | Type |
|---|---|
| Q1 | Opération arithmétique (+, -, *, /) |
| Q2 | Inversion de chaîne |
| Q3 | Hash SHA256 |
| Q4 | Minimum d'une liste |
| Q5 | Filtrer les mots de plus de 5 caractères |
| Q6 | XOR décimal |
| Q7 | Chiffrement César +3 |
| Q8 | Poids de Hamming |
| Q9 | Conversion décimal → binaire |
| Q10 | Formatage adresse MAC |
Le flag est retourné par le serveur après la Q10.