Matroesjkapoppetjes: analyse van een packer voor CTB locker

Matroesjkapoppetjes: analyse van een packer voor CTB locker

DearBytesBlogMatroesjkapoppetjes: analyse van een packer voor CTB locker

maandag 8 juni 2015

Onlangs zag ik een phishing-campagne om CTB locker te verspreiden. De slachtoffers kregen een e-mail die afkomstig leek te zijn van een Nederlandse webwinkel en waarin een bestelling van Fifa15 voor Playstation 3 werd beschreven. <sarcasme> En terwijl niemand PS3 meer gebruikt</sarcasme>, waren er toch zowaar mensen die dachten: goh, ik heb Fifa15 voor de PS3 niet besteld bij winkel X, dus laat ik die bijlage eens openen! De bijlage was een zipbestand met daarin een uitvoerbaar genaamd “Bestelling48905155.exe”. De executable had een symbool dat leek op het symbool van Adobe Reader.

Ransomware Wehkamp

 

 

Het bestand werd niet herkend door het antivirusprogramma, dus mijn collega’s stuurden het op naar McAfee/VirusTotal en Malwr, en publiceerden de kenmerken waarmee mensen zich tegen malware konden beschermen (zogenoemde IOC’s). Het betrof een sample van CTB locker/Critroni en ik vroeg me af waarom dat niet standaard werd gedetecteerd. Ik had nog nooit eerder geprobeerd reverse engineering toe te passen op malware, maar nu was ik toch nieuwsgierig: hoe had die malware zich kunnen verstoppen? Omdat het Pasen was, had ik een extra vrije dag om onderzoek te doen dus ik ging aan de slag! De packer was een .NET executable bestand, dus net iets voor mij: genoeg ervaring met code analyse. Met DotPeek kon ik de bron decompileren tot de oorspronkelijke C#-code. Het resultaat is een bijzonder obscuur stuk code, met weinig informatie over wat het doet. Maar de functie main() is volgens mij altijd een goed startpunt.

 

Main Method

Oké, laten we eens rustig kijken wat er in die code staat. Het ziet er misschien rommelig en onbegrijpelijk uit, maar het is belangrijk om iets te zoeken dat je herkent. Voor mij was dat “(Bitmap) ((ResourceManager) …”; het programma laadt een bestand in de vorm van een bitmap. Er is een object van type “TripleDESCryptoServiceProvider” dus er moet in de afbeelding iets zitten dat versleuteld is. Het bronbestand van de bijlage bevat één afbeelding in base64-indeling.

 

image in base64 format

Laten we nu eens kijken of de makers van de malware binnen in de afbeelding informatie prijsgeven. Wanneer we de afbeelding door Unbase64-ing halen, krijgen we een geldig PNG-bestand, maar een ingebedde afbeelding is er niet. De afbeelding bevat geen hints over zijn identiteit, en Virustotal heeft de afbeelding niet als kwaadaardig herkend. We moeten dus proberen te begrijpen wat er gebeurt als de afbeelding wordt gedecodeerd en hoe CTB locker door dit binaire bestand wordt gelanceerd. Daarvoor moeten we de code zien te doorgronden, en die moeten we dus eerst opschonen.

 

xormechanism_predeobfuscate

 

Met deze regel vraag je door middel van de functie JVSOU.mDbkbySDoBrWfPlhU() een PNG op. Wat doet die functie? Het blijkt een multi-byte XOR-mechanisme te zijn. De functie leest een string en past voor elke byte XOR toe met een byte in de byte-array van de XOR-sleutel. Wanneer we de naam en ook de naam van de byte-array van de XOR-sleutel veranderen, wordt de code een stuk leesbaarder. In de oorspronkelijke methode zag het er zo uit:

 

unxormechanism_predeobfuscate

 

Toen ik de naam van de variabelen had veranderd en enkele opmerkingen erbij had gezet, zag de functie er zo uit:

 

unxormechanism_postdeobfuscate

 

Dit leest al een stuk prettiger. Nu moeten we de functie nog testen om te zien of de verdenkingen terecht waren. We hadden al een stuk code dat vermoedelijk een PNG-bestand uit het bronbestand laadt. Wanneer we nu de output ophalen van de regel “JVSOU.xorHashBangToString(“4#38#30#17#58#28#30#34#45#12#13#46#30”, JVSOU.xorKeyByteArray)”, moeten we de naam “PrJEnHJvyXYzJ” (de naam van bovengenoemd PNG-bestand) te zien krijgen. We maken een Console-project aan om dit te testen en schrijven de output van bovenstaande code weg naar de console.

 

png_unxor_fileread

 

Precies wat ik zocht! Nu weten we hoe de malware alle strings verbergt, en moeten we de diverse methoden doorlopen om te zien welke functionaliteit de applicatie heeft. Op deze manier lukte het om alle aangeroepen functionaliteiten in de main-methode te reversen. Zo zag ik dat het binaire bestand nóg een executable in het geheugen laadde, en deze vervolgens uitvoerde.

 

main_method_post_cleanup

 

Het binaire bestand wordt in het geheugen geladen, dus we moeten het op schijf opslaan om het te kunnen onderzoeken. Het beste punt om dit te doen is vlak voor het uitvoeren van het binaire bestand. Eerst moeten we controleren of “BinaryByteArray” een volledige executable bevat. In de array moeten de “magic numbers” te zien zijn waarmee we kunnen zien wat het bestandstype is. De magic numbers voor .exe-bestanden zijn x4Dx5A of “MZ”, genoemd naar de MS-DOS-programmeur Mark Zbikowski. Wanneer we het sample runnen en vlak voor de uitvoering afbreken, kunnen we de array onderzoeken.

 

mz_notreadable

 

 

 

 

 

 

 

Dit lijkt niet de “MZ” te zijn die we zoeken, maar 77 in het decimale stelsel is 4D in het hexadecimale stelsel, en 90 is 5A hexadecimaal. We hebben ons binaire bestand gevonden en moeten het nu extraheren:

 

write_mz_to_disk

We slaan het bestand op en ook dit blijkt in C# .NET te zijn geschreven, zodat we de bron kunnen bekijken. Dit keer ziet het sample er niet zo obscuur uit en zit er veel meer functionaliteit in. Deze tweede stap bevat functionaliteit om analyse te omzeilen door op sandboxen, WireShark en virtualisatie te controleren. Voordat er iets wordt uitgevoerd, detecteert de malware of iemand reverse engineering probeert toe te passen op het sample.

 

sample2_detectsandbox

 

 

 

 

 

 

 

 

 

 

Het sample bevat interessante code. Er zitten functies in om processen en registersleutels te verbergen, en de functies worden afgehandeld door de klasse “KazyRootkit”. Deze klasse bevat functies die zo op Windows werken dat bepaalde namen/waarden voor Regedit of Taskmanager worden verborgen. “Rootkit” is dus een beetje een groot woord, maar de klasse vervult wel degelijk een soort camouflagerol.

 

rootkitfunc

 

Hierna doet de malware nog een paar checks en voert dan de taken uit die aan het begin van het bestand worden gedefinieerd. Dan is het tijd om het volgende binaire bestand te laden. Eerst laadt het programma een byte-array vanuit een bronbestand en vervolgens laadt het een XOR-sleutel. Hierna past het XOR toe op de byte-array en schrijft het alle bytes weg naar een bestand.

 

sample2_checks_insertintomem

Deze keer is het veel gemakkelijker om te zien wat er gebeurt, en numArray1 wegschrijven naar een bestand zou moeten volstaan om te begrijpen wat er aan de hand is. Wanneer we de regel “File.WriteAllBytes(“CTBPacker_step3.exe”, numArray1);” toevoegen, moeten we het nieuwe sample kunnen inspecteren. Dan blijkt dat we eindelijk het laatste matroesjkapoppetje hebben gevonden: het sample voor CTB locker! Dit doet alles waar CTB locker voor gemaakt is; aangezien de code in het geheugen is geïnjecteerd, krijgt het antivirusprogramma niet de kans om te verhinderen dat het sample actief wordt, omdat dit immers niet op de harde schijf staat.

Het eerste sample dat ik analyseerde, gaf een duidelijke aanwijzing over de manier waarop de makers voorkomen dat de malware door een antivirusprogramma wordt gedetecteerd. Wanneer je de XOR-sleutel en daarmee ook de sleutel van de encryptie verandert, zal detectie veel minder vaak lukken. Als de makers dan ook nog het decoderingsmechanisme zouden veranderen, zou het wel heel lastig worden om het sample te detecteren. Ik denk dat detectie van deze malware via het decoderingsalgoritme zal moeten lopen, omdat dit waarschijnlijk minder vaak veranderd wordt.