Contents

ECSC Prequals 2019 - Exfiltration

Challenge sur l’exfiltration d’un fichier Docx xoré, joué pendant le CTF annuel organisé par l’ANSSI.

Énoncé
Notre SoC a détecté qu’un document confidentiel avait été exfiltré ! La méthode utilisée ne semble pas avancée et heureusement, une capture réseau a pu être faite au bon moment… Retrouvez ce document.

Découverte du pcap

Pour ce challenge on dispose d’un fichier pcap de 19 Mo. Voici rapidement à quoi il ressemble.

/img/ecsc-prequals-2019-exfiltration/1.png

À première vue, on a du DNS, du HTTP, du HTTPS : ça ressemble à une navigation web banale.

Pour y voir plus clair, on lance cette commande qui nous permet de déterminer quels protocoles sont présents dans la capture :

$ tshark -r exfiltration.pcap |awk '{print $7}' |sort -u

1
2
3
4
5
6
7
8
9
DNS
HTTP
HTTP/XML
ICMP
OCSP
TCP
TLSv1
TLSv1.2
TLSv1.3

Dans un contexte d’exfiltration, les protocoles qui nous intéresseront le plus au premier regard seront DNS et ICMP.

Regardons les domaines des requêtes DNS.

$ tshark -r exfiltration.pcap -Y 'dns' -Tfields -e dns.qry.name |sort -u

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
status.geotrust.com
n5dscf.akamaiedge.net
status.geotrust.com
n1dscf.akamaiedge.net
n1dscf.akamaiedge.net
n1dscf.akamaiedge.net
n2dscf.akamaiedge.net
fastlane.rubiconproject.com
fastlane.rubiconproject.com
fastlane.rubiconproject.com
optimized-by.rubiconproject.net.akadns.net
fastlane.rubiconproject.com
optimized-by.rubiconproject.net.akadns.net
optimized-by.rubiconproject.net.akadns.net
perf-optimized-by.rubiconproject.net.akadns.net
perf-optimized-by.rubiconproject.net.akadns.net
optimized-by.rubiconproject.net.akadns.net
...

On en obtient un paquet, mais aucun n’est réellement suspect, ou alors il s’agit de trackers web.

On se penche donc sur l’ICMP :

$ tshark -r exfiltration.pcap -Y 'icmp'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
5183 2019-04-29 21:18:37,434515 192.168.1.26 → 198.18.0.10  ICMP   42 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
5184 2019-04-29 21:18:37,438237  198.18.0.10 → 192.168.1.26 ICMP   60 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52
5228 2019-04-29 21:18:38,526199 192.168.1.26 → 198.18.0.10  ICMP   42 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
5229 2019-04-29 21:18:38,529140  198.18.0.10 → 192.168.1.26 ICMP   60 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52
5382 2019-04-29 21:18:39,646903 192.168.1.26 → 198.18.0.10  ICMP   81 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
5393 2019-04-29 21:18:39,650153  198.18.0.10 → 192.168.1.26 ICMP   81 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52 (request in 5382)
6265 2019-04-29 21:18:41,067100 192.168.1.26 → 198.18.0.10  ICMP   65 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
6266 2019-04-29 21:18:41,070125  198.18.0.10 → 192.168.1.26 ICMP   65 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52 (request in 6265)
6297 2019-04-29 21:18:42,159239 192.168.1.26 → 198.18.0.10  ICMP   82 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
6298 2019-04-29 21:18:42,162210  198.18.0.10 → 192.168.1.26 ICMP   82 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52 (request in 6297)
6321 2019-04-29 21:18:43,264340 192.168.1.26 → 198.18.0.10  ICMP   65 Echo (ping) request  id=0x0000, seq=0/0, ttl=64
6322 2019-04-29 21:18:43,266807  198.18.0.10 → 192.168.1.26 ICMP   65 Echo (ping) reply    id=0x0000, seq=0/0, ttl=52 (request in 6321)

Intéressant, on a très peu de paquets pour une grosse capture. Regardons les données qu’ils transportent :

$ tshark -r exfiltration.pcap -Y 'icmp && ip.src == 192.168.1.26' -Tfields -e data.data |tr -d ':' |xxd -r -p

1
2
3
4
config : exfiltered_file_size=4193bytes
config : file_type=DOCX
config : data_len_for_each_packet=random
config : encryption=XOR

Ce sont nos premières infos sur l’exfiltration !

Maintenant, on sait que :

  • L’exfiltration a lieu de 192.168.1.26 vers 198.18.0.10
  • Le fichier transporté est un fichier Docx, transporté sur plusieurs paquets de tailles randoms
  • Le Docx est xoré

Analyse de l’exfiltration

Il s’agit maintenant de déterminer comment ce fichier a été exfiltré. Pour cela, filtrons tous les paquets à la recherche de ceux correspondant à notre IP source et notre IP destination. Dans Wireshark, on peut entrer le filtre ip.src == 192.168.1.26 && ip.dst == 198.18.0.10

On obtient la liste de paquets suivante.

/img/ecsc-prequals-2019-exfiltration/2.png

Les trames HTTP POST attirent très vite notre attention, et voici ce qu’elles contiennent.

/img/ecsc-prequals-2019-exfiltration/3.png

On a donc le paramètre data, qui contient sûrement un fragment de notre fichier Docx xoré, et le paramètre uuid, qui ne nous sert à rien.

On ressort tshark pour extraire les données des requêtes POST qui nous intéressent :

1
2
filtre='ip.src == 192.168.1.26 && ip.dst == 198.18.0.10 && urlencoded-form'`
tshark -r exfiltration.pcap -Y "$filtre" -Tfields -e urlencoded-form.value |cut -d ',' -f 1 |tr -d '\n' |xxd -r -p > docx.xor`

Déchiffrement du fichier

On a maintenant récupéré notre Docx, plus qu’à la déxorer. Après quelques essais via l’uuid, on détermine que ce n’est pas la clé puisque le fichier déchiffré est illisible. On sort donc xortool.

$ xortool -b docx.xor

/img/ecsc-prequals-2019-exfiltration/4.png

Parmi les clés guess, on retrouve “ecsc”, ça sent bon. De plus, xortool essaie de déchiffrer notre fichier avec toutes les clés qu’il teste, et stocke tout ça dans un dossier xortool_out du répertoire courant.

Nous, on veut voir s’il a réussi à trouver du fichier Word :

$ file xortool_out/* |grep -i 'word'

1
xortool_out/000.out:                               Microsoft Word 2007+

Il nous en a sorti un !

$ libreoffice xortool_out/000.out

/img/ecsc-prequals-2019-exfiltration/flag.png

Flag
ECSC{v3ry_n01sy_3xf1ltr4t10n}