VBA Maldoc & UTF7 (APT-C-35)
Hallo, ddsdm's hier, senior handel bij de internetstormcentrum. Ik ga de analisatie van een managingsdokument met vba-code doen die UTF-7 gebruikt voor de code shellcode en geëxecuëerd is. Laten we eens kijken. Ik heb de sample hier en ik run olidump. En dus is het een OXML file, omdat het woord is voor vbaproject.bin, dus het is een doc-m file en hier heeft deze stream makkels. Dus ik selecteer deze stream v, het is redelijk groot. Dus inderdaad een veel uitgang. Laten ik dit summariseren met een plug-in. Ik gebruik vaak vba-dco. Dus deze zullen we kijken voor geëxecuëerd statements en geëxecuëerd statements en dingen zoals dat. Oké en hier kunnen we verschillende geëxecuëerd statements zien en hier ook en dan zijn ze gebruikt. Het is niet dat het makkelijk is om te verstehen omdat de opvisatie die gebruikt is voor variable naam en functie naam is. Dus deze letters hier, deze identifiseren zijn wel bijzonder, maar ze zijn niet. Dus een ding dat ik heb in de plug-in is om te generaliseren identifiseren zoals dit naar iets dat is makkelijker te luisteren voor ons. En je doet dit door een plug-in optie te gebruiken, plug-in opties, want deze zijn opties voor de plug-in, niet voor de dump, maar voor de plug-in. En hier optie j voor generaliseren. Oké, en hier is het al steeds meer readbaar. Je kunt hier een alocatie van virtual memory zien, multibijtig widecar en dan internaal in U-languizen. Dit kan gebruikt zijn om de geëxecuëerd statement te beginnen. Dit is om een memorie te aloceren voor de geëxecuëerd statement en dit is een soort van conversie en we zullen de dichterij kijken later op. En je ziet dit twee keer. Oké, meestal is dat omdat het voor 64-bit en 32-bit shellcodes is. Dus de twee shellcodes zal in hier 64-bit en 32-bit zijn. Dus we kunnen kijken naar een volledig code met generalisatie met optie A, plug-in optie A en dan hebben we hier al de code. Oké, dus hier heb je het document open. En inderdaad, als we 64-bit winnen, kiezen we dit subproutine of function en anders deze. Dus identiferen we 28, dat is voor 64-bit en 33, dat is voor 32-bit. Dus we kunnen pre-define onze houdnames met optie B en ik ga zeggen, identiferen we 28. Dit is een subproutine 64 en 33. Dat is een subproutine voor 32-bit.  Oké, en dat is wat ik krijg. Nu gaan we eens kijken op de code hier. Dus declaratie en hier subproutine 64. Een declaratie van een array of bytes, 5000 bytes hier, identiferen we 29. Dus dit is waarschijnlijk de array die de shellcode zal containeren. En inderdaad hier kun je zien, identiferen we 29, positie 0. Zijn het exadismal value 2B. Ampercent H is een exadismal value in VBA. Hier Ampercent H56. Oké, we gaan proberen te decode dit. De eerste keer ga ik het 29 verplaatsen. Met iets dat is meer makkelijker om te horen, om te horen. Dus het is een array of bytes voor 64-bit code. Oké ja, hier kunnen we het zien. Laten we naar beneden komen. Dus hier een locatie van memoria. Multi-byte white char. Hier zie je onze array hier van bytes met 64-bit shellcode is transformeerd met de multi-byte white char function. En dan hier hebben we de subproutine voor 32-bit. Identifiererad 34 is de array weer. 34, oké. Dus ik ga het zeggen, 34 is een array of bytes voor 32-bits, zoals dit. En dat is hoe onze code nu ziet. Dat is makkelijker om te horen. Hier zie je weer multi-byte char array of bytes 32, oké. Dus wat is dit multi-byte white char? Het is een API function die strenkt met 2 UTF16. Dus dit is de definitie. Multi-byte white char. Map een karakterstrenk met UTF16. En hoe is de conversion gedaan? Het bedoelt op de code page. En de code page die hier gebruikt is 65.000. En als we verder naar de definitie kijken, 65.000 is UTF7, oké. Dus de code hier, die is in de array gegeven, dat moet uiteindelijk UTF7 en code shellcode zijn, dat we moeten decodeen en dan analyseren. Oké, laten we nu de exadismale waarschuwingen en converteren naar binary. Dus eerst ga ik reprennen alle lijnen die A, B, 64 containeren. Dus referenties naar de array of bytes die 64 containert met shellcode. En hier hebben we alle exadismale waarschuwingen. Ik ga ze met mijn research tool extracten. Dat werkt met een regelaar expression. Een regelaar expression is 1% h, dot, dot. Dus niets karakter zoals dit. Oké, en zoals u kunt zien, heb ik het extracten hier. Nu, ik moet gewoon deze twee hier.  En zoals u kunt zien hier, als het een null byte is, dan zijn het niet twee karakteren, maar twee exadismale karakteren, maar een single exadismale karakter en dan een dubbele quote. Dus ik ga een capture groep defineren, zoals dit. Dan heb ik gewoon exadismale waarschuwingen. En dan gaan we gewoon een grep doen voor de colonne hier. Oké ja, dus en het is alleen voor null bytes die we hebben deze issue. Dus ik ga de stream editor gebruiken. To search and replace 0 colon by 00 globally. Like this and then here we have 00. So now this can be properly converted to binary with x2bin. Oké, and this is UTF7 code. UTF7 code, dat is niet een real formal definition, zoals explained hier, maar Python kan ook de translatie doen. Dus dat is voor de 64 bit. Nu, sinds we hebben geïnterviewd, identifies AB64 en AB32, kan ik deze commanden snel modificeren voor AB32. En dan moet ik hier een andere code krijgen en dat zou de code naar 32 bits. Oké, dus ik ga nu transformeren. Convert is van UTF7 tot UTF16, zoals de functie hier multibyte tot widegarde. Maar ik ga dit doen van Python in mijn translatie programma. Ik ga het opereren om alle data, niet om byte per byte instances, maar om de volledige data in een goos te maken. Dus ik moet in dat geval een functie, een lambda functie defineren. Het heeft een argument, de bytes, de data. En dus de data hier zijn bytes. En ik moet die bytes op de string bezoeken door UTF7. Zo. En dan moet ik dit weer op UTF16 encodeen. En gewoon zoals de Windows API functie doet. En laten we zien wat we ervaren. En we krijgen een error hier. UTF16 encodeen kan niet encodeen. Deze karakter, position 54. Laten we deze met een 32 bit shellcode proberen. Zullen we eerst kijken of we beter hebben. Hetzelfde error, maar een verschillende waarde en een verschillende positie. En dat is inderdaad de issue die je kunt hebben met UTF7. De definietie die in Python is en de definietie die in de Windows API is waarschijnlijk een beetje anders. Nu, laten we zien of we gewoon als werkgezond de ergens verantwoordd zijn. Dus ik ga zeggen, verantwoordd zijn ergens. En dan ga ik het binary data. En naast dat hier assemblycode.  Dus dat is normaal, dat dit assemblycode hier is. Het moet niet worden gehaald. Het is waarschijnlijk een error dat de malware developers hebben gemaakt om ook de deel van de assemblycode te ontdekken. Maar dit hier is de actuale binary data die we kunnen disassemblen met de netwijd disassembler. Dus dit is 64 bitcode en ik reed van standard in. Dus dit ziet er niet goed uit. Oh ja, ik heb een verandering. Dus dit is AB32 en ik disassembler het als 64 bitcode. Dus dat is niet wat we moeten doen. We moeten hier een 64 bitcode bekijken. Oké, hier heb je de shellcode. Nu, de FFFE. Dit is de byteorder markt van UTF16. Dus dat is niet echt een deel van de shellcode. Het is een resultaat van de translation in Python. Maar dan hebben we een knob, een persoonlijke knob. En hier zie je een kleine loop met een XOR. Dus het is een XOR met 1B. Maar voor de XOR is er ook een knob van dit. Dus dit is eigenlijk dezelfde als een XOR FF. En dan is er een kleine loop hier. Dus de payload is waarschijnlijk encoded met een XOR FF XOR 1B. Dus we kunnen het calculeren. Dus 1, nee, excertisme. 1B hier. 1B XOR FF E4. Dat moet ook een actueel key zijn voor de decoding. Dus zonder deze assembly. Laten we dit transmiseren. En deze keer ga ik dit byte per byte doen. Dus byte XOR met E4. En dan hebben we hier iets. Dus laten we de strings uitleggen. Oké, hier URL momen. En dit URL hier. Maar zoals je kunt zien, de URL is niet proper decoded. En dit is waarschijnlijk omdat we dat UTF7 erover hebben gehad. Dat ik de Python instructeerde om te ignoreren. Dus ik deed iets anders om dit te fixen. Ik ben eigenlijk, als een tweede solution, dat ik in de tweede directie geënsplieft. Ik gebruik de API function. True Python te doen de decoding. En ik heb een kleine script voor dit decode UTF7. Dus ik importe C type zodat ik de API functions, Windows API functions, en een kleine definition van een function decode UTF7 dat de data geënsplieft is. Ik reserve 10.000 bytes. En dan heb ik een multibyte met 65.000. Flag 0, de data als input. En hier de resultaat als uitput.  En dan heb ik gewoon een return resultat. Nu, twee dingen. Dit werkt natuurlijk alleen op Windows. Als je dit op Linux doet, dan kan dit niet gebeuren. Het werkt niet. Dus dit werkt alleen op Windows. De tweede, ook zeker als je dat doet, dat je niet op API functions gebruikt. Dat zou de decode geënsplieft zijn. Zoals dat enum function. Dat is gebruikt om decode geënsplieft te gebruiken. En niet gebruiken dat, wanneer je het in een sandbox doet, waar je geen risico is als de machine geïnsplieft is. Dus dit is de functie dat ik ga gebruiken. Dus ik ga de decode script loaden. Full read. Ik heb alles geparseerd. En de functie die ik gebruik is decodeutf7. En nu, dit keer, krijgen we dit. Het ziet er weer goed uit. Laten we dit veranderen. Dus doen we de XOR. Dus byte E4. En dan veranderen we de strings. En nu hebben we een proper URL. En nu kan ik het exact dezelfde doen. Voor 32-bit. En inderdaad, ze gebruiken dezelfde key. Het is dezelfde URL, maar dit is deze. En dit is met PNG. En dit met ICO. Nu, als je niet kan onderstaan in het assembly langzaam en de key vinden, kan je ook proberen te doen met mijn XOR search tool. Dus XOR search, we read van standard in. En we gaan kijken voor keyword HTTP, voor string HTTP. En dan hier, het vond dit string met XOR E4 op deze positie. Nu, XOR search zal printen uit als ik niet 40 karakters heb gevolgd. Dus als je meer wilt, moet je een optie langs gebruiken. En laten we zeggen dat we bijvoorbeeld 100 willen. En dan hier hebben we de volledige URL. En als ik dat doe met 64-bit code, dan hebben we deze URL. Nu, zoeken voor HTTP met XOR search werkt, want de URL is properlijk decoded. Maar remember, van de Python UTF translation, we had een error. En de URL was niet eigenlijk HTTP, maar HTTP en dan iets anders. Dus dit zou niet werken. Je zou moeten kijken voor een andere keyword. Of proberen te decodeven alles en het door wat recognition patterns zoals het volgt. Dus let's go back naar dat decoding. Oké, dus hier 64-bit. En hier doe ik de decoding met Python en niet met de Windows API. 