Cyber Crime Challenge 0xFFD
Afgelopen maand werd de Cybercrime Challenge gehouden: een digitale speurtocht georganiseerd door het Team High Tech Crime van de Nederlandse politie, in samenwerking met Tweakers.net en Certified Secure. In deze weblogpost geef ik de antwoorden van de challenge en de methode die ik gebruikt heb om die antwoorden te vinden.
Wie het leuk vindt om de challenge zelf te doen, moet vooral niet verder lezen!
Hierin staat ook het e-mailadres van de afzender: missm7dd@gmail.com.
De M staat dus voor Monotropa.

Miss M heet dus Liselotte Landervore.

Met behulp van Google Maps is de gefotografeerde locatie te vinden, op de hoek van de Silostraat en de Korenstraat in Winterswijk:
In Google Streetview is het opschrift op de gevel te lezen: "Dierenartsenpraktijk Winterswijk". Hierop Googlen levert het adres op: Korenstraat 2.
Vultura is het brein achter de organisatie.
De hier gebruikte authenticatie-methode wordt beschreven in XEP 0078. Het komt er op neer dat de digest die de client naar de server stuurt berekend wordt als hex(sha1(stream_id + wachtwoord)) of in dit geval:
hex(sha1("3807744839" + wachtwoord)) = "b8f6a6eb3bd3f928647ce6b8b787eddb5dc13a74".
Omdat het aantal mogelijkheden voor het wachtwoord redelijk beperkt is, kunnen we een programmaatje schrijven om alle mogelijkheden te bruteforcen:
Compileren en linken tegen libcrypto (OpenSSL) en dan (ongeveer een kwartier) geduld hebben:
./crack
password is 'u9.fwh'[/cmd]
Met dit wachtwoord kan de TrueCrypt container geopend worden.
Het gezochte rekeningnummer is gewoon leesbaar: 6049474.
Een van de gebruikers (in dit geval uayeuzxw) is een "control bot". We kunnen deze user aanspreken:
De control bot antwoordt met base-64-gecodeerde binary data, die lijkt op het formaat dat het crypto-programma produceert! Helaas hebben we een wachtwoord nodig om deze tekst te decoderen, en dat weten we nog niet.
Uit de memory dump blijkt dat het crypto-programma actief was toen Liselotte's computer in beslag werd genomen. Het benodigde wachtwoord staat dus waarschijnlijk ergens in het geheugen. Om uit te vinden waar precies, moeten we de crypto binary analyseren. Dit vereist enige kennis van x86 assembly.
De assembly code kan geprint worden met een commando als objdump -d crypto. De meest interessante functie heet crypto(), want die leest het wachtwoord van de gebruiker in (via een call naar de standaardfunctie getpass()) en genereert op basis daarvan een cryptografische sleutel. De assembly code van deze functie begint zo:
Deze functie reserveert eerst 288 bytes op de stack. Dan wordt er een string ("q1ePg3J1") base-64-gecodeerd naar de stack geschreven op locatie ebp-0x1c. Daarna wordt met getpass() om een wachtwoord gevraagd, en de lengte van de geretourneerde string wordt naar locatie ebp-0x100 geschreven, waarna tenslotte het ingevoerde wachtwoord naar locatie ebp-0x7c gekopieerd wordt.
Samenvattend ziet de stackframe er dus zo uit:
Omdat de uitvoer van de base-64-codering voorspelbaar is kunnen we die gebruiken om de stack frame in de geheugendump te vinden:
480341292 is de locatie corresponderend met ebp - 0x10c. Het is nu eenvoudig om het hele stackframe uit te lezen:
Deze dump bevat het gehele stackframe en offsets zijn relatief ten op zichte van de stackpointer. De lengte van het wachtwoord staat dus op offset 0x20: 0x12 ofwel 18 bytes. Het wachtwoord zelf begint op offset 0xa4: 7eSCoHWEA0rtMvAxWH. (Merk op dat de rest van de buffer al met willekeurige karakters geïnitialiseerd was, vandaar dat we de lengte van het wachtwoord nodig hebben om te bepalen waar het wachtwoord eindigt.)
Nu we het goede wachtwoord hebben, kunnen we het crypto-programma zelf uitvoeren om met de control bot te communiceren. De bot blijkt de volgende commando's te ondersteunen:
homefdd283.vulturacommunicationhq.com. (Let op: de username van de control bot en de uitvoer van "history" wisselen tijdens de challenge regelmatig!)
Wie het leuk vindt om de challenge zelf te doen, moet vooral niet verder lezen!
LEVEL 1
Originele posting:Друзья! Развертывание вымогателей в Западную Европу больше не является проблемой, благодаря нашей уникальной бэкэнда вредоносных программ: H4ck3nb3rg версии 0x7DD. Многие наши клиенты уже стали миллионерами. Наша программа подходит поймать проигравших, которые используют Windows, Mac и Android. Наши программные блоки системы с помощью наших состоянии современных ботнетов. Он будет отображать экран по умолчанию или изображение по вашему выбору. Система может быть разблокирована, заплатив сумму в MeKash ваучеры или законных счетов с авторитетными европейскими банками, такими как оранжевым львов диване, BAN-бродят и Arbo банка. Новый H4ck3nb3rg 0x7DD не обнаруживается по поддержанию правопорядка!Ежемесячно лицензия стоит 5000 евро, доставка через наш. Лука-сайте Tor. Оплата с помощью кредитной карты от всех. Только три лицензии осталось!
Miss M.
1. Wat is de naam van de gijzelingsmalware die door Miss M wordt verkocht?
Ik spreek geen Russisch, maar Google translate wel:Het antwoord is dus: H4ck3nb3rg.Deploying extortionists in Western Europe is no longer a problem, thanks to our unique backend malware: H4ck3nb3rg version 0x7DD. [..]
2. Wat is het e-mailadres van Miss M?
Googlen op "h4ck3nb3rg" gecombineerd met "MissM" levert een link op naar een PasteBin post met een (Engelstalige) versie van het bovenstaande mailtje. Vooral de mailheaders zijn interessant:Delivered-To: <M8R-vftnqj@mailinator.com> Received: from 193.200.198.87 ([193.200.198.87]) by mail.mailinator.com with SMTP (Postfix) for M8R-vftnqj@mailinator.com; Fri, 22 Feb 2013 10:09:01 +0000 (UTC) Received: by 193.200.198.87 with SMTP id j8so54729qah.8 for <M8R-vftnqj@mailinator.com>; Fri, 22 Feb 2013 02:09:01 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.224.185.141 with SMTP id co13mr800511qab.33.1361527741255; Fri, 22 Feb 2013 02:09:01 -0800 (PST) Received: by 10.49.71.168 with HTTP; Fri, 22 Feb 2013 02:09:01 -0800 (PST) Date: Fri, 22 Feb 2013 11:09:01 +0100 Message-ID: <CAM-WngbS18XMX6utu-r3QzGf_34g25Z-E_Q2J5+m2z4h4hPrJg@mail.gmail.com> Subject: H4ck3nb3rg From: Miss M <missm7dd@gmail.com> To: Undisclosed Recipients Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
Hierin staat ook het e-mailadres van de afzender: missm7dd@gmail.com.
3. Vanaf welk IP adres is de e-mail verzonden?
Ook dit blijkt uit de mail headers: 193.200.198.87. (Merk op dat de 10.x.x.x adressen uit een private range komen; dat zijn intranetadressen die geen onderdeel uitmaken van het internet en voor de politie dus niet interessant zijn.)4. Waar staat de M in Miss M voor?
Een reverse DNS lookup op het IP-adres dat we hierboven vonden leidt naar het domein van de verzender:$ host 193.200.198.87 87.198.200.193.in-addr.arpa domain name pointer missmonotropa.com.
De M staat dus voor Monotropa.
5. Wat is de echte naam van MissMonotropa?
Googlen op "Miss Monotropa" onthult een Twitter account met daarop een een tweet van Miss Monotropa's moeder:
Miss M heet dus Liselotte Landervore.
LEVEL 2
6. Onder welke naam heeft Liselotte Landervore een Flickr account?
Wederom googlen op "Liselotte Landervore" levert een Tweakers.net account op, en een forumpost van Liselotte met daarin een link naar haar Flickr account: monomiss19.7. Op welk adres woont Liselotte Landervore?
Liselotte heeft op Flickr vier foto's in het mapje "Thuis" geplaatst. Op één daarvan is een straatnaambordje te zien:
Met behulp van Google Maps is de gefotografeerde locatie te vinden, op de hoek van de Silostraat en de Korenstraat in Winterswijk:
In Google Streetview is het opschrift op de gevel te lezen: "Dierenartsenpraktijk Winterswijk". Hierop Googlen levert het adres op: Korenstraat 2.
LEVEL 3
Het afluisteren van de vaste en mobiele-internetverbinding van Liselotte levert een heleboel data op in de vorm van pcap dumps die met tcpdump of Wireshark geanalyseerd kunnen worden.8. Wat is de nickname van het brein achter de ransomware organisatie?
internet.pcap bevat een plain-text conversatie via IM-client Pidgin tussen MissM en ene "Vultura" over hun criminele activiteiten:<message type="chat" id="purpleeb436f31" to="vultura@h4ck3nb3rg/BitlBee"> <body>harvest staat klaar</body> </message>
Vultura is het brein achter de organisatie.
LEVEL 4
Een inval bij Liselotte levert een geheugendump op en een TrueCrypt container. In de eerder gelogde chat tussen Vultura en MissM wordt over deze container gesproken:Deze conversatie bevat een aantal hints:MissM: hier is de updated tc
Vultura: WERKT NIET
Vultura: MET JE JABBERPASS TOG???
MissM: ja
MissM: ehm capslock?
Vultura: lol
Vultura: was k vergeten
Vultura: ok is open
...
Vultura: wrom zit die hidden er nog in?
MissM: kak
MissM: sorry
MissM: niemand die het ziet
- het wachtwoord van de container gelijk is aan Liselotte's jabber-wachtwoord.
- capslock moet uit (dus waarschijnlijk bestaat het wachtwoord uit kleine letters).
- er zit nog een hidden volume in de TrueCrypt container (waarvan Vultura ook het wachtwoord kent).
De andere netwerk dump, mobile.pcap, bevat een Jabber-authenticatiepoging:Message of the day:
- there are no rules
- allowed password format: ^[a-zA-Z0-9., _-]{4,6}$
XML:
1
2
3
4
5
6
| <?xml version='1.0'?><stream:stream xmlns="jabber:client" to="h4ck3nb3rg" xmlns:stream="http://etherx.jabber.org/streams" > <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='3807744839' from='h4ck3nb3rg' xml:lang='en'> <iq type="get" id="1"><query xmlns="jabber:iq:auth"><username>missmonotropa</username></query></iq> <iq type="result" id="1"><query xmlns="jabber:iq:auth"><username>missmonotropa</username><password/><digest/><resource/></query></iq> <iq type="set" id="2"><query xmlns="jabber:iq:auth"><username>missmonotropa</username><digest>b8f6a6eb3bd3f928647ce6b8b787eddb5dc13a74</digest><resource>old-client</resource></query></iq> <iq type="result" id="2"/> |
De hier gebruikte authenticatie-methode wordt beschreven in XEP 0078. Het komt er op neer dat de digest die de client naar de server stuurt berekend wordt als hex(sha1(stream_id + wachtwoord)) of in dit geval:
hex(sha1("3807744839" + wachtwoord)) = "b8f6a6eb3bd3f928647ce6b8b787eddb5dc13a74".
Omdat het aantal mogelijkheden voor het wachtwoord redelijk beperkt is, kunnen we een programmaatje schrijven om alle mogelijkheden te bruteforcen:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/sha.h> static char password[32] = "3807744839"; static char goal[20] = "\xb8\xf6\xa6\xeb\x3b\xd3\xf9\x28\x64\x7c" "\xe6\xb8\xb7\x87\xed\xdb\x5d\xc1\x3a\x74"; void search(int len) { char digest[20], *p; SHA1(password, len, digest); if (memcmp(digest, goal, 20) == 0) { password[len] = '\0'; printf("password is '%s'\n", password + 10); exit(0); } if (len < 16) { for (p = "abcdefghijklmnopqrstuvwxyz0123456789., _-"; *p != '\0'; ++p) { password[len] = *p; search(len + 1); } } } int main() { search(10); return 0; } |
Compileren en linken tegen libcrypto (OpenSSL) en dan (ongeveer een kwartier) geduld hebben:
$ cc -O2 -o crack crack.c -lcrypto
./crack
password is 'u9.fwh'[/cmd]
Met dit wachtwoord kan de TrueCrypt container geopend worden.
9. Naar welk rekeningnummer werd door Vultura op 25 februari 2013 een bedrag van 5.000 dollar overgemaakt?
De TrueCrypt container bevat een bestand met een screenshot van Liberty Reserve:Het gezochte rekeningnummer is gewoon leesbaar: 6049474.
10. Welk IRC kanaal wordt gebruikt door Vultura en Miss M?
Level 4 wordt vergezeld van een "briefing" in de vorm van een YouTube filmpje van Tek Tok over de zaak "IJsvogel". Hierin wordt gesuggereerd dat criminelen soms een spatie achter hun wachtwoord zetten om een hidden TrueCrypt volume te beveiligen. Deze truc werkt hier ook en opent een tweede partitie met daarin twee bestanden:- config: een configuratiebestand voor irssi (een IRC client)
- crypto: en een encryptie-programma
LEVEL 5
Ingelogd op de IRC server geeft /WHO #VrD8r4Nv informatie over de gebruikers in het kanaal:23:53 -!- #VrD8r4Nv pdoxxmsk H+ 0 ~pdoxxmsk@no.ip [None] 23:53 -!- #VrD8r4Nv eertzggo H+ 0 ~eertzggo@no.ip [None] 23:53 -!- #VrD8r4Nv gbzwdruc H+ 0 ~gbzwdruc@no.ip [None] ... 23:53 -!- #VrD8r4Nv uayeuzxw H+ 0 ~abpfehoh@no.ip [control bot] 23:53 -!- #VrD8r4Nv CHANSERV H*@ 1 chan@services.int [channel registration service]
Een van de gebruikers (in dit geval uayeuzxw) is een "control bot". We kunnen deze user aanspreken:
<maks> hallo <uayeuzxw> dfI8J5hkgaQ6vtYtKK2d7Qlou650S9m1FZ697bZ01TCOTnCTWtyCzqyZe9UV4bBHZN9nkm4j/2PyZ/0L6ga3AQ==
De control bot antwoordt met base-64-gecodeerde binary data, die lijkt op het formaat dat het crypto-programma produceert! Helaas hebben we een wachtwoord nodig om deze tekst te decoderen, en dat weten we nog niet.
Uit de memory dump blijkt dat het crypto-programma actief was toen Liselotte's computer in beslag werd genomen. Het benodigde wachtwoord staat dus waarschijnlijk ergens in het geheugen. Om uit te vinden waar precies, moeten we de crypto binary analyseren. Dit vereist enige kennis van x86 assembly.
De assembly code kan geprint worden met een commando als objdump -d crypto. De meest interessante functie heet crypto(), want die leest het wachtwoord van de gebruiker in (via een call naar de standaardfunctie getpass()) en genereert op basis daarvan een cryptografische sleutel. De assembly code van deze functie begint zo:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| push %ebp mov %esp,%ebp push %esi push %ebx sub $0x120,%esp ... mov $0x80e33bc,%eax ; (char*)0x80e33bc == "q1ePg3J1" movl $0x10,0xc(%esp) lea -0x1c(%ebp),%edx mov %edx,0x8(%esp) movl $0x8,0x4(%esp) mov %eax,(%esp) call 80482e3 <base64_encode> ; base64_encode("q1ePg3J1", 8, ebp-0x1c, 16); movl $0x80e33c5,(%esp) ; (char*)0x80e33c5 == "password" call 8092ac0 <getpass> ; char *p = getpass("password: "); mov %eax,-0x108(%ebp) mov -0x108(%ebp),%eax mov %eax,(%esp) call 808e130 <strlen> ; *(int*)(ebp - 0x100) = strlen(p); mov %eax,-0x100(%ebp) mov -0x100(%ebp),%eax mov %eax,0x8(%esp) mov -0x108(%ebp),%eax mov %eax,0x4(%esp) lea -0x7c(%ebp),%eax mov %eax,(%esp) call 808f000 <memcpy> ; memcpy(ebp - 0x7c, p, strlen(p)); .... |
Deze functie reserveert eerst 288 bytes op de stack. Dan wordt er een string ("q1ePg3J1") base-64-gecodeerd naar de stack geschreven op locatie ebp-0x1c. Daarna wordt met getpass() om een wachtwoord gevraagd, en de lengte van de geretourneerde string wordt naar locatie ebp-0x100 geschreven, waarna tenslotte het ingevoerde wachtwoord naar locatie ebp-0x7c gekopieerd wordt.
Samenvattend ziet de stackframe er dus zo uit:
ebp - 0x120 | = esp | : begin stackframe |
ebp - 0x100 | = esp + 0x020 | : lengte wachtwoord |
ebp - 0x07c | = esp + 0x0a4 | : kopie van wachtwoord |
ebp - 0x01c | = esp + 0x104 | : base64("q1ePg3J1") == "cTFlUGczSjE=" |
ebp | = esp + 0x120 | : einde stackframe |
Omdat de uitvoer van de base-64-codering voorspelbaar is kunnen we die gebruiken om de stack frame in de geheugendump te vinden:
$ grep -abo cTFlUGczSjE= memory.raw 480341292:cTFlUGczSjE=
480341292 is de locatie corresponderend met ebp - 0x10c. Het is nu eenvoudig om het hele stackframe uit te lezen:
$ head -c $[480341292 + 0x1c] memory.raw | tail -c $[0x120] | xxd 0000000: 9c33 0e08 1f00 0000 e803 0000 2000 0000 .3.......... ... 0000010: 0cad a3bf 3003 0000 10d8 9109 9c33 0e08 ....0........3.. 0000020: 1200 0000 5c70 3971 5f75 5974 6f3d 4975 ....\p9q_uYto=Iu 0000030: 536d 6c51 4572 5e2f 6d28 6178 2155 653b SmlQEr^/m(ax!Ue; 0000040: 603d 4b75 6664 4624 3858 772c 7446 5a4c `=KufdF$8Xw,tFZL 0000050: 6c25 2237 5160 7943 675f 7442 6e5e 5c53 l%"7Q`yCg_tBn^\S 0000060: 542c 273f 494c 423a 293f 4622 3e59 4d2f T,'?ILB:)?F">YM/ 0000070: 5e29 4568 4278 6462 5c5e 2929 7564 5b4f ^)EhBxdb\^))ud[O 0000080: 4a62 6d4c 6735 6670 2d65 714a 4378 585a JbmLg5fp-eqJCxXZ 0000090: 5a57 4721 5431 3c69 6e45 7242 622c 7065 ZWG!T1<inErBb,pe 00000a0: 4763 3734 3765 5343 6f48 5745 4130 7274 Gc747eSCoHWEA0rt 00000b0: 4d76 4178 5748 5370 382f 5556 2f59 6f5e MvAxWHSp8/UV/Yo^ 00000c0: 3456 5072 5d67 2932 722c 3e4f 366a 5c62 4VPr]g)2r,>O6j\b 00000d0: 5c41 2b50 2637 4572 4553 4d2e 3142 6b78 \A+P&7ErESM.1Bkx 00000e0: 5174 6f68 6c99 160e 2cdd 68f6 8b9e 0993 Qtohl...,.h..... 00000f0: 8453 fc49 9ca6 ab9d f2ee d143 9966 3e1c .S.I.......C.f>. 0000100: b246 1b40 6354 466c 5547 637a 536a 453d .F.@cTFlUGczSjE= 0000110: 00ad a3bf 00f2 27b7 0000 0000 50ff 0708 ......'.....P...
Deze dump bevat het gehele stackframe en offsets zijn relatief ten op zichte van de stackpointer. De lengte van het wachtwoord staat dus op offset 0x20: 0x12 ofwel 18 bytes. Het wachtwoord zelf begint op offset 0xa4: 7eSCoHWEA0rtMvAxWH. (Merk op dat de rest van de buffer al met willekeurige karakters geïnitialiseerd was, vandaar dat we de lengte van het wachtwoord nodig hebben om te bepalen waar het wachtwoord eindigt.)
Nu we het goede wachtwoord hebben, kunnen we het crypto-programma zelf uitvoeren om met de control bot te communiceren. De bot blijkt de volgende commando's te ondersteunen:
- help: "supported commands: info, help, history, stats, zombies"
- info: "Ransomware bot v0.45"
- history: "last login from Vultura@homefdd283.vulturacommunicationhq.com on 2013-03-08 22:34:29"
- stats: "26252 machines and received 182679 payments so far"
- zombies: "currently 9382 zombies are waiting orders"
11. Wat is de laatst bekende hostname van Vultura?
Deze blijkt uit het antwoord van de control bot op het "history" commando:homefdd283.vulturacommunicationhq.com. (Let op: de username van de control bot en de uitvoer van "history" wisselen tijdens de challenge regelmatig!)
12. Wat is de werkelijke naam van Vultura?
Een WHOIS-lookup van het gebruikte domein (vulturacommunicationhq.com) levert de naam en het adres van de aanvrager op:Het laatste antwoord is dus Oscar Zevendees. Blijkbaar gaat de politie er gemakshalve vanuit dat criminelen hun echte naam opgeven bij domeinregistratie.Zevendees, Oscar
Roosveldstraat 404
Haarlem, 2013 NH

01-'14 Fenwick trees demystified
02-'13 High-Color GIF Images
Reacties
Elegante manier om de stack direct uit de memdump te vissen. 
Ik had al een stack/heapdump liggen als bijproduct van een (vruchteloze) zoektocht bij een eerdere vraag; De console input buffer staat nog (deels) op de heap, daar kun je het wachtwoord al deels vinden als pretty much enige sensible ascii string.
Aangezien 'ie echter partly overwritten is ontkom je er echter niet aan het gebruik van de stackdump...

Ik had al een stack/heapdump liggen als bijproduct van een (vruchteloze) zoektocht bij een eerdere vraag; De console input buffer staat nog (deels) op de heap, daar kun je het wachtwoord al deels vinden als pretty much enige sensible ascii string.
Aangezien 'ie echter partly overwritten is ontkom je er echter niet aan het gebruik van de stackdump...
Dit lijkt me we de meest ideale situatie. Wat doe je als haar pc bijvoorbeeld uit gestaan had...
Dan denk ik: dat is hier niet het geval en dus ook niet de vraag. Je moet werken met de middellen die je hebt, kom je informatie te kort om een stap te vervolledigen dan heb je gewoon brute pech en loopt je onderzoek daar vast en moet je op zoek naar andere manieren om aan die informatie te komen.Xessive schreef op zondag 31 maart 2013 @ 08:47:
Dit lijkt me we de meest ideale situatie. Wat doe je als haar pc bijvoorbeeld uit gestaan had...
Haha, leuk adres. Die straat loopt maar tot nr 80, Rooseveldstraat 404, Not Found 
Postcode 2013CC was eigenlijk wel een klein beetje voorspelbaar, je moet er maar opkomen...

Postcode 2013CC was eigenlijk wel een klein beetje voorspelbaar, je moet er maar opkomen...

[Reactie gewijzigd op zondag 31 maart 2013 17:22]
Hoelang ben je hier uiteindelijk mee bezig geweest?
Wat enigszins apart is, dat ze de achternaam van haar moeder gebruikt, terwijl 9/10 kinderen de achternaam van de vader krijgen (of de moeder trouwt na een scheiding opnieuw en gebruikt de naam van de nieuwe echtgenoot, in deze tijden niet ondenkbaar). Gemakshalve hebben ze dit vast zo gedaan, maar irl had ze denk ik een andere achternaam gehad en kun je niet concluderen dat "Landervore" haar echte achternaam is, gok ik zo.
Reageren is niet meer mogelijk