31
Mar
2013

Cybercrime Challenge 0x7DD #2

This series of 2 blog posts comprise a writeup of the ‘Cybercrime Challenge 0x7DD’ recruitment challenge by the Team High Tech Crime of the Dutch Police; as such, both posts are in Dutch (apologies to non-Dutch readers).

Dit is een writeup van de ‘Cybercrime Challenge 0x7DD’, een recruitmentchallenge van het Team High Tech Crime van de Politie.


8. Wat is de nickname van het brein achter de ransomware organisatie ?
A: vultura

In level 3 krijgen we de mogelijkheid om een tap van het telecommunicatieverkeer van Liselotte Landervore aan te vragen. We vragen een tap op van zowel telefonie- als internetverkeer, welke worden geleverd als 3 files.

$ file *.pcap
internet.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
mobile.pcap:   tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
pots.pcap:     tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

De telefoniedump (pots.pcap) blijkt leeg, dus dan gaan we met de overige 2 pcaps aan de slag.

We openen internet.pcap in . Aangezien het een capture is met erg veel data, is het handig om allereerst een overzicht te krijgen van de inhoud. In het Statistics-menu van Wireshark vind je een hoop nuttige opties (Conversations, Endpoints). We besluiten om eerst eens te kijken welke protocollen er allemaal worden gebruikt, en kiezen dus voor Statistics > Protocol Hierarchy.

Wireshark protocol hierarchy

Naast een hoop HTTP traffic valt ons oog op ‘XMPP Protocol’, een protocol dat voor instant messagingverkeer (o.a. Jabber) wordt gebruikt. Met een rechterklik op ‘XMPP Protocol’ > Apply as Filter > Selected filteren we enkel het XMPP-verkeer uit de dump. In de XMPP-traffic vinden we een chatconversatie tussen Miss Monotropa (missmonotropa@h4ck3nb3rg) en haar partner in crime: vultura (vultura@h4ck3nb3rg/BitlBee).

Met een rechterklik op een willekeurige XMPP-packet en dan kiezen voor ‘Follow TCP stream’ krijgen we snel een dump van alle XMPP traffic (XML-based). Zo kunnen we (enigzins onpraktisch) de chatconversatie lezen; als alternatief zou je ervoor kunnen kiezen om met wat code de XML te parsen tot iets leesbaars (of voor de Linux/Unixfanatici: met een toffe shell-oneliner XMPP uit de dump filteren en er strings(1) overheengooien maakt het geheel ook aardig leesbaar).

(In het chatgesprek staan een aantal zaken die erg nuttig zijn voor de resterende vragen, wat maar weer bewijst dat het altijd handig is om aantekeningen te maken.)


Aan het begin van level 4 krijgen we de vraag of we de briefingsvideo willen bekijken. Later blijkt dat dit erg nuttig is voor het beantwoorden van de vragen, dus het is aan te raden om ‘m te bekijken.

Bij vraag 9 & 10 krijgen we een geheugendump van de laptop van Liselotte. Hiernaast is er een TrueCrypt-container aangetroffen, welke we ook kunnen downloaden.


9. Naar welk rekeningnummer werd door Vultura op 25 februari 2013 een bedrag van 5.000 dollar overgemaakt ?
A: 6049474

Hoewel we net zowel een TrueCrypt-container als een geheugendump hebben gehad, is enkel de TrueCrypt-container momenteel van belang. Ook de ongebruikte data en aanwijzingen van vraag 8 zijn van belang.

In de chatconversatie tussen Miss Monotropa en Vultura wordt er gesproken over de TrueCrypt-container en de ‘harvest’ van de afgelopen week (> 20.0000 euro). Blijkbaar is informatie over de weekopbrengst terug te vinden in de TrueCrypt-container, welke uiteraard niet te openen is zonder het juiste password of passphrase. We zetten nog even alle hints uit de chatconversatie op een rijtje:

M: hier is de updated tc
V: WERKT NIET
V: MET JE JABBERPASS TOG???
V: wrom zit die hidden er nog in?

Message of the day:
 - there are no rules
 - allowed password format: ^[a-zA-Z0-9., _-]{4,6}$
  • Informatie over de weekopbrengst bevindt zich in de TrueCrypt-container (dus ook het rekeningnummer dat we zoeken?)
  • Het wachtwoord van de container is het Jabberwachtwoord van Miss Monotropa
  • Er is mogelijk een hidden container(!)

Hoewel we redelijk wat XMPP-traffic in internet.pcap hebben kunnen vinden, is er geen spoor van een Jabberpassword. In mobile.pcap blijkt echter ook XMPP-traffic te vinden, specifieker: een Jabber authentication sequence.

xml

Helaas geen password, maar wel een username en een digest.

In de Jabberdocumentatie staat beschreven hoe deze authenticatie werkt:

1. Concatenate the Stream ID received from the server with the password.
2. Hash the concatenated string according to the SHA1 algorithm, i.e., SHA1(concat(sid, password)).

De Stream ID is in ons geval 3807744839, samen met het juiste wachtwoord zou SHA1(3807744839||WACHTWOORD) de digest op moeten leveren: b8f6a6eb3bd3f928647ce6b8b787eddb5dc13a74

Hoewel de manier van hashen geen ‘plain’ SHA1 is, betreft het een vrij gangbare manier van hashen met een salt (dat is het Stream ID in dit geval). Met een tool als oclHashcat (een tool voor GPU-based hash cracking) kunnen we de hash proberen te cracken (brute force), gebruik makende van de gegeven password constraints (^[a-zA-Z0-9., _-]{4,6}$).

Door de hash en salt als volgt in een textfile te zetten kunnen we ‘m aan oclHashcat (plus) voeren:

b8f6a6eb3bd3f928647ce6b8b787eddb5dc13a74:3807744839

Vervolgens runnen we oclHashcat in salted-SHA1 mode (-m 120), brute force (-a 3) met custom character set (-1 “?l?d?u., _-“) en een lengte van 6 (?1?1?1?1?1?1; nadat lengte 4-5 niets opleverde).

Note: in de character set representeren ?l, ?u, ?d de lowercase en uppercase karakters van A-Z resp. cijfers (0-9).

oclHashcatPlus_64.bin --force -m 120 -a 3  -1 "?l?d?u., _-" hash.txt ?1?1?1?1?1?1

Als je een redelijke videokaart hebt (liefst AMD) heb je binnen enkele seconden de plaintext van de hash: u9.fwh (en dus het Jabberpassword).

Met behulp van dit wachtwoord is de TrueCrypt-container te mounten, hierin vinden we naast een aantal irrelevante PDFs een screenshot van banktransacties. Het gevraagde rekeningnummer is: 6049474.



10. Welk IRC kanaal wordt gebruikt door Vultura en Miss M ?
A: #VrD8r4Nv

Eigenlijk is deze vraag vrij simpel, mits je goed hebt opgelet tijdens de briefingsvideo. Hierin heeft men het over een verdachte die een spatie achter zijn wachtwoorden zette.

Uit de chatconversatie weten we dat er een hidden container in de TrueCrypt-file zit. Door een spatie achter het wachtwoord te zetten (“u9.fwh “) en hiermee de TrueCrypt-container te openen mounten we de hidden container, welke een configuratiebestand (voor de IRC-client irssi) en een ‘crypto’ file oplevert. In het configuratiebestand vinden we het gevraagde IRC-kanaal:

channels = (
  { name = "#VrD8r4Nv"; chatnet = "BOT"; autojoin = "Yes"; },
);

Dus: #VrD8r4Nv



11. Wat is de laatst bekende hostname van Vultura ?
A: homeXXXXXX.vulturacommunicationhq.com

Met het configuratiebestand uit de vorige vraag kunnen we verbinding maken met de IRC server en het C&C-kanaal joinen. Als we de lijst met users in het kanaal bekijken, valt het op dat er 1 user met ‘control bot’ als ‘real name’ is. Het sturen van een bericht naar deze bot levert echter een base64-encoded message op. Decoden levert (schijnbaar) random data op, aangenomen dat dit encrypted data is zullen we de ‘crypto’ binary en memory dump moeten analyseren met als doel de messages van de bot te kunnen decrypten.

Voor het analyseren van de memorydump gebruiken we volatility

Listen van processes in de dump:

$ vol.py -f memory.raw  --profile=Linuxubuntu1004_4x86 linux_psaux
Volatile Systems Volatility Framework 2.3_alpha
Pid    Uid    Gid    Arguments                                                       
866    1000   1000   ./crypto

Alle memory mappings van het crypto-process:

$ vol.py -f memory.raw  --profile=Linuxubuntu1004_4x86 linux_proc_maps -p 866
Volatile Systems Volatility Framework 2.3_alpha
WARNING : volatility.obj      : Overlay structure tty_struct not present in vtypes
Pid      Start      End        Flags       Pgoff Major  Minor  Inode      File Path                                                                       
-------- ---------- ---------- ------ ---------- ------ ------ ---------- --------------------------------------------------------------------------------
     866 0x08048000 0x0810a000 r-x           0x0    251      0     142435 /home/monotropa/crypto                                                          
     866 0x0810a000 0x08115000 rw-       0xc1000    251      0     142435 /home/monotropa/crypto                                                          
     866 0x08115000 0x08117000 rw-           0x0      0      0          0                                                                                 
     866 0x0991c000 0x0993e000 rw-           0x0      0      0          0 [heap]                                                                          
     866 0xb7701000 0xb7703000 rw-           0x0      0      0          0                                                                                 
     866 0xb7703000 0xb7704000 r-x           0x0      0      0          0                                                                                 
     866 0xbfa26000 0xbfa3c000 rw-           0x0      0      0          0 [stack]

Dumpen van alle crypto-mappings:

$ vol.py -f memory.raw  --profile=Linuxubuntu1004_4x86 linux_dump_map -p 866 --dump-dir crypt

In de heap range vinden we slechts een enkele interessante ASCII string:

$ strings -n6 crypt/task.866.0x991c000.vma 
`Qy1oHWEA0rtMvAxWH

Helaas blijkt dit niet het juiste wachtwoord.

Static reverse engineering van de crypto binary dmv. IDA levert de volgende interessante (geannoteerde) pseudocode voor de functie welke het password verwerkt:

char base_dest[128]; // [sp+2Ch] [bp-FCh]@1
char pass_dest; // [sp+ACh] [bp-7Ch]@1

pass = getpass((int)"password: ");
len_pass = strlen(pass);
memcpy(&pass_dest, pass, len_pass);

fill_buffer_with_random_data(pass, 4);
fill_buffer_with_random_data(base_dest, 128);

Hier valt op dat er een kopie van de password input wordt opgeslagen op de stack (in pass_dest), en hier vlak voor een 128-byte buffer ligt welke gevuld wordt met ‘random’ data (in de ASCII range).

Als we strings over de stack dump runnen, vinden we de 128-byte buffer met erna pass_dest.

$ strings -n6 crypt/task.866.0xbfa26000.vma 
...
\p9q_uYto=IuSmlQEr^/m(ax!Ue;`=KufdF$8Xw,tFZLl%"7Q`yCg_tBn^\ST,'?ILB:)?F">YM/^)EhBxdb\^))ud[OJbmLg5fp-eqJCxXZZWG!T1inErBb,peGc747eSCoHWEA0rtMvAxWHSp8/UV/Yo^4VPr]g)2r,>O6j\b\A+P&7ErESM.1BkxQtohl

Splitsen op 128 bytes levert:

\p9q_uYto=IuSmlQEr^/m(ax!Ue;`=KufdF$8Xw,tFZLl%"7Q`yCg_tBn^\ST,'?ILB:)?F">YM/^)EhBxdb\^))ud[OJbmLg5fp-eqJCxXZZWG!T1inErBb,peGc74
7eSCoHWEA0rtMvAxWHSp8/UV/Yo^4VPr]g)2r,>O6j\b\A+P&7ErESM.1BkxQtohl

Combineren met de password bytes van de heap levert het password op: 7eSCoHWEA0rtMvAxWH

Met behulp van dit wachtwoord kunnen we met de crypto-binary berichten van de control-bot decrypten, en door onze eigen berichten te encrypten commando’s aan de bot geven. Met het ‘history’-commando komen we achter de hostname van vultura:

history: "last login from Vultura@homeXXXXXX.vulturacommunicationhq.com on 2013-03-08 22:34:29"

+-+-+ BONUS +-+-+

Een alternatieve oplossing is om (na het reversen van de crypto binary) de hele memory dump af te zoeken naar de juiste AES key. Enigzins naieve implementatie: keyfinder.c



12. Wat is de werkelijke naam van Vultura ?
A: Oscar Zevendees

$ whois vulturacommunicationhq.com
Registrant:
Zevendees, Oscar
   Roosveldstraat 404
   Haarlem, NH 2013 cc
   NL

Comments are closed.