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 :

  1. Se connecter au serveur via nc
  2. Lire chaque ligne reçue
  3. Identifier la question avec une regex
  4. 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

QuestionType
Q1Opération arithmétique (+, -, *, /)
Q2Inversion de chaîne
Q3Hash SHA256
Q4Minimum d'une liste
Q5Filtrer les mots de plus de 5 caractères
Q6XOR décimal
Q7Chiffrement César +3
Q8Poids de Hamming
Q9Conversion décimal → binaire
Q10Formatage adresse MAC

Le flag est retourné par le serveur après la Q10.