Aller au contenu
  1. Posts/

Toulouse Hacking Convention 2024 - writeup du chall de réseau

·1053 mots·5 mins
Lacroix Raphaël (Chepycou)
Auteur
Lacroix Raphaël (Chepycou)
Bonjour, bienvenue sur mon blog. Je suis Raphaël LACROIX, je développe diverses applications pendant mon temps libre, allant du très inutile au parfois utile. Je fais aussi beaucoup de Capture The Flag et de défis de cybersécurité.
Sommaire
write-ups et tools THCon - Cet article fait partie d'une série.
Partie 2: Cet article

Qu’est-ce donc que ceci ?
#

La THCon (Toulouse Hacking convention), est une conférence française de cybersécurité qui réunit amateurs, professionnels et chercheurs chaque année à Toulouse au mois d’avril.

Pour cette édition (2024), j’étais l’un des créateurs de défis et j’ai (co-)créé un défi d’OSINT, quelques défis de stéganographie, et un défi réseau en 4 étapes, que je détaillerai dans le billet de blog suivant.

Note : le CTFd n’est plus en ligne, donc si vous n’avez pas participé, ou si vous ne vous souvenez pas des défis, vous pouvez jeter un coup d’oeil sur https://ctftime.org/event/2269/tasks/ bien que tous les challs ne soient pas listés malheureusement :/

Writeup détaillé
#

Find me if you can
#

Pour cette étape, il suffit d’ouvrir le fichier avec wireshark, et vous trouverez le flag en clair, ainsi que le port auquel se connecter pour l’étape suivante.

alt text

Let us Phone Home
#

Nous nous connectons au port 4242 et envoyons le flag pour se connecter, après quoi nous récupérons le second flag.(Cela peut également être fait avec netcat).

import socket

adresseIP = "20.19.38.158"	
port = 4242

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((adresseIP, port))
print("Connected to the server")
message = "THCON{E.T.-PH0N3-H0M3}"
client.send(message.encode("utf-8"))
received = client.recv(1024).decode()
print(received)

Lors de la connexion, vous serez accueilli par le drapeau et un message vous indiquant que vous pouvez vous connecter au port 2647 en utilisant le nouveau flag comme mot de passe pour obtenir les discussions de l’équipe du méchant (oui, apparemment ils utilisent les satellites piratés comme une alternative à Signal - en beaucoup moins sécurisée).

A disturbance in the Force …
#

Cette étape est un peu plus compliquée. Nous sommes accueillis par deux messages :

D@RK_StEL m'a demandé de vous envoyer la combinaison. Je vous l'enverrai par la méthode habituelle. Il vous suffit de toquer sur le serveur avec la bonne combinaison.
Oui, je suis prêt à recevoir ! Passage en mode furtif.

Ensuite, une conversation tout à fait banale et ennuyeuse (Heureusement qu’il y avait huggingchat pour nous générer quelques dialogues vides) va commencer et tourner en boucle. En voici un extrait :

conversation3 = [
    "Have you watched any good movies or TV shows lately?",
    "Yeah, actually! I just finished watching a really interesting documentary series on Netflix",
    "Oh, which one was it? I'm always looking for something new to watch",
    "It's called 'Explained'. They cover a wide range of topics from politics to science to culture",
    "That sounds fascinating. Thanks for the recommendation!",
    "No problem! By the way, how's your family doing?",
    "They're all good, thanks for asking. My kids keep me busy with their sports activities though!",
    "Ah, I remember those days. My daughter used to play soccer, and my son played basketball",
    "Sounds familiar. Anyway, I heard there's a new restaurant in town. Have you tried it yet?",
    "Not yet, but I've heard great things about it. The menu looks amazing",
    "Same here. I think I might check it out this weekend with some friends",
    "That sounds like fun! Let me know how it goes",
    "Will do. Hey, have you ever traveled to Asia before?",
    "Yes, I went to Japan a few years ago. It was an incredible experience",
    "Really? I’ve never been, but it’s high on my bucket list. Did you visit Tokyo?",
    "Of course! We saw all the famous landmarks like the Tokyo Tower, Shibuya Crossing, and Meiji Shrine",
    "Wow, that must have been awesome. I hope I can plan a trip there someday",
    "You absolutely should! Just save up some money and book a flight when you can",
    "Good advice. Speaking of travel, where would you like to go next if you could choose anywhere?",
    "Hmm...that’s tough. There are still so many places I want to explore. But if I had to pick one place, I’d say New Zealand. I’ve heard the landscapes are breathtakingly beautiful"
]

Il faut tout d’abord récupérer la conversation dans un fichier .pcap.

from scapy.all import *
import socket
import tqdm


adresseIP = "20.19.38.158"	
port = 2647	

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((adresseIP, port))
print("Connected to the server")
message = "THCON{I_H4V3_4_84D_F33L1NG_4B0UT_TH15}"
client.send(message.encode("utf-8"))
received = client.recv(1024).decode()
print(received)


for i in range(10,110,10):
    received = client.recv(1024).decode()
    print(received)
received = client.recv(1024).decode()
print(received)
_, filesize = received.split('-Size:')
filename = os.path.basename("recup.pcap")
filesize = int(filesize)

progress = tqdm.tqdm(range(filesize), f"Receiving {filename}", unit="B", unit_scale=True, unit_divisor=1024)
with open(filename, "wb") as f:
    while True:
        bytes_read = client.recv(1024)
        if not bytes_read:
            break
        f.write(bytes_read)
        progress.update(len(bytes_read))

print("Connexion closed")
client.close()

alt text

Ensuite, nous constatons que le champ ToS du protocole IP contient des valeurs bizarres. Il est censé être constant à une valeur qui indique le type de service (ex : téléphonie, streaming…). Ces valeurs variables sont probablement des données binaires qui peuvent être récupérées.

from scapy.all import *

scapy_cap = rdpcap('path/recup.pcap')

binary_string = ""
i = 0
for packet in scapy_cap:
    if i % 2 == 0:
        a = format(packet.getlayer("IP").tos, '08b')
        binary_string += a
    i += 1

bits = [int(bit) for bit in binary_string]
print(bits)
text = ''.join([chr(int("".join(map(str, bits[i:i+8])), 2)) for i in range(0, len(bits), 8)])
print(text)

Résultat : Port_The_Last_Jedi: 1337, Port_Rogue_One: 52377, Revenge_Of_The_Sith: 6666, Port_A_New_Hope: 1977, Solo: 1138, Phantom_Menace: 9991

Normalement, même si vous n’avez pas vu les films Star Wars (ce que vous devriez objectivement faire, au moins à l’exception de ceux de Disney), vous devriez reconnaître les noms emblématiques de la saga.

En remettant les ports dans l’ordre de sortie des films Star Wars, nous obtenons : 1977 - 9991 - 6666 - 52377 - 1337 - 1138.

[L’ordre de visionnage de Star Wars est un sujet controversé dans la communauté des nerds] (https://screenrant.com/star-wars-correct-watch-order-george-lucas/) (d’une manière parfois encore plus grave que tabs vs space ou vim vs emacs). Si vous voulez mon avis, il était logique de les regarder dans l’ordre de leur sortie à l’époque pour découvrir les rebondissements de l’intrigue. Mais comme de nos jours, tout le monde connaît le rebondissement de l’Empire contre-attaque, je dirais que l’ordre chronologique est supérieur. Quoi qu’il en soit, revenons au défi…

La conversation nous indiquait qu’il faut faire un port knocking :

nc -w 1 20.19.38.158 1977; nc -w 1 20.19.38.158 9991; nc -w 1 20.19.38.158 6666; nc -w 1 20.19.38.158 52377; nc -w 1 20.19.38.158 1337; nc -w 1 20.19.38.158 1138;

Et voilà le flag : THCON{WHY_D0_TH3Y_N3V3R_KN0CK} !

*(N’oubliez pas d’utiliser un VPN pour ceux qui ont une connexion filtrée comme celle de Renater qui hébergeait le CTF présentiel.)

write-ups et tools THCon - Cet article fait partie d'une série.
Partie 2: Cet article