[THCON2023][Write Up – Misc] Drone and Secret Message

 

Enoncé

While travelling to a conference in Paris, Herlock Sholmès sees a troubled police inspector. After asking him what was his problem, the inspector tells Herclock that he is trying to understand how two spies communicate with each other.

Once every week both spies get on the Eiffel tower, but never get in speaking distance of each other. Generally one of them flies a drone for around twenty minutes, sometimes both of them do it. When questionned about it, they told it was for taking pictures, and provided the pictures in question when asked. Of course, nothing helpful came from these.

The inspector hands Sholmès a file containing the last flight path of the drone.

The flag of this challenge is THCon23{SECRETMESSAGE}, where SECRETMESSAGE is the message sent in that interaction, written in all caps without spaces.

Résolution

On nous donne un fichier de la forme suivante :

2023/03/02-11:19:43 48°51’32.25″N 2°17’42.66″E 1002ft
2023/03/02-11:19:46 48°51’32.45″N 2°17’42.97″E 999ft
2023/03/02-11:19:49 48°51’32.57″N 2°17’43.38″E 1001ft
2023/03/02-11:19:52 48°51’32.57″N 2°17’43.82″E 1000ft
2023/03/02-11:19:55 48°51’32.45″N 2°17’44.23″E 1003ft
2023/03/02-11:19:58 48°51’32.25″N 2°17’44.54″E 995ft
2023/03/02-11:20:01 48°51’31.98″N 2°17’44.71″E 1003ft
2023/03/02-11:20:04 48°51’31.69″N 2°17’44.71″E 1002ft
2023/03/02-11:20:07 48°51’31.42″N 2°17’44.54″E 1001ft
2023/03/02-11:20:10 48°51’31.21″N 2°17’44.23″E 1000ft

Mon premier réflexe a donc été de tracer le chemin du drone en 3d, le résultat est le suivant (j’ai traité les données GPS comme des données cartésiennes puisqu’à cette échelle, ça n’allait pas changer grand chose au tracé) :

import numpy as np
import matplotlib.pyplot as plt

import re


if __name__ == "__main__":
    with open("./DroneFlightPath.txt", 'r') as f:
        data = f.read()

    x, y, z = [], [], []
    for l in data.split("\n"):
       r = re.findall(r".*\t48°51'(.*)\"N\t2°17'(.*)\"E\t(.*)ft", l)
       if r:
          r = r[0]
          x.append(float(r[0]))
          y.append(float(r[1]))
          z.append(r[2])

    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.plot(x, y, z)
    plt.show()

On obtient la figure suivante :

Représentation 3D

Représentation 3D

 

On peut observer donc que le drone tourne en rond (sur 16 points) et on remarque également qu’en terme d’altitude on a environ 2 possibilités : haut ou bas au bruit près.

On peut donc extraire le binaire représenté par les altitudes du drone (0 pour bas et 1 pour haut) :

import re

if __name__ == "__main__":
    with open("./DroneFlightPath.txt", 'r') as f:
        data = f.read()

    res = []
    for l in data.split("\n"):
        r = re.findall(r".*\t48°51'(.*)\"N\t2°17'(.*)\"E\t(.*)ft", l)
        if r:
            r = r[0]
            if int(r[2]) > 1050:
                res += "1"
            else:
                res += "0"
    print("".join(res))

On obtient alors le résultat suivant :

00000000000001011101110111000101110100011101110101000111010101000101000101110100011101110100011101010100011101011101000101011100011101000101011101000101110100010101011101110001010101110001011100010101110111011100011101110101110001110100010111010100010101110100000000000000000000000

J’ai pas mal cherché à quoi ça pouvait correspondre, ce n’est clairement pas du binaire car on peut reconnaitre des patterns, comme le fait qu’on ne peut avoir que des chaine de longueur 1 ou 3 « 1 » ou « 0 ».
Apres plusieurs tentatives de guess, nous avons enfin trouvé l’encodage : c’est du morse pour lequel « 1 » signifie « . », « 111 » : « -« , « 0 » : passage au caractère suivant et « 000 » : passage à la lettre suivant.

"00000000000001011101110111000101110100011101110101000111010101000101000101110100011101110100011101010100011101011101000101011100011101000101011101000101110100010101011101110001010101110001011100010101110111011100011101110101110001110100010111010100010101110100000000000000000000000".replace("000", " ").replace("111", "-").replace("1", ".").replace("0", "")

On obtient alors :

.— .-. –.. -… .. .-. –. -… -.-. ..- -. ..-. .-. …– …- .- ..— –.- -. .-.. ..-.

ou

JRZBIRGBCUNFR3VA2QNLF

C’est moche mais au moins ça se décode.
On pense alors directement à du ROT13, et c’est effectivement ça nous donne :

WEMOVETOPHASE3IN2DAYS

Le flag est donc : THCon23{WEMOVETOPHASE3IN2DAYS}

HeadorteilINGÉNIEUR SÉCURITÉ
Pentester & CTF enjoyer

Add a comment

*Please complete all fields correctly