Tak jak wspominałem w poprzednim poście niniejszy będzie o sposobach (de)szyfrowania stosowanych w pewnej rodzinie trojanów bankowych pisanych w delphi.
Oczywiście tradycyjnie zaczniemy od przedstawienia naszego bohatera:
[=]Dane[=]
Antivirus Version Last Update Result a-squared 4.5.0.24 2009.08.28 Trojan-Spy.Win32.Bancos!IK AhnLab-V3 5.0.0.2 2009.08.28 - AntiVir 7.9.1.7 2009.08.28 TR/Spy.Banker.DS.5102592 Antiy-AVL 2.0.3.7 2009.08.24 - Authentium 5.1.2.4 2009.08.28 - Avast 4.8.1335.0 2009.08.28 Win32:Spyware-gen AVG 8.5.0.406 2009.08.28 PSW.Banker5.IQR BitDefender 7.2 2009.08.28 DeepScan:Generic.Banker.OT.4CC5D1C8 CAT-QuickHeal 10.00 2009.08.28 - ClamAV 0.94.1 2009.08.28 Trojan.Agent-119128 Comodo 2125 2009.08.28 - DrWeb 5.0.0.12182 2009.08.28 Trojan.PWS.Banker.based eSafe 7.0.17.0 2009.08.27 - eTrust-Vet 31.6.6706 2009.08.28 - F-Prot 4.5.1.85 2009.08.27 - F-Secure 8.0.14470.0 2009.08.28 - Fortinet 3.120.0.0 2009.08.28 W32/Banker.B!tr.pws GData 19 2009.08.28 DeepScan:Generic.Banker.OT.4CC5D1C8 Ikarus T3.1.1.68.0 2009.08.28 Trojan-Spy.Win32.Bancos Jiangmin 11.0.800 2009.08.28 - K7AntiVirus 7.10.830 2009.08.28 - Kaspersky 7.0.0.125 2009.08.28 - McAfee 5723 2009.08.28 PWS-Banker.gen.b McAfee+Artemis 5723 2009.08.28 Artemis!504F1C591479 McAfee-GW-Edition 6.8.5 2009.08.28 Trojan.Spy.Banker.DS.5102592 Microsoft 1.5005 2009.08.28 TrojanSpy:Win32/Bancos.gen!C NOD32 4378 2009.08.28 probably a variant of Win32/Spy.Banker.QEO Norman 2009.08.28 W32/Banker.EKFF nProtect 2009.1.8.0 2009.08.28 - Panda 10.0.2.2 2009.08.28 Trj/CI.A PCTools 4.4.2.0 2009.08.28 - Prevx 3.0 2009.08.28 - Rising 21.44.40.00 2009.08.28 Trojan.PSW.Win32.Banker.dnl Sophos 4.45.0 2009.08.28 Mal/Generic-A Sunbelt 3.2.1858.2 2009.08.28 - Symantec 1.4.4.12 2009.08.28 Infostealer.Bancos TheHacker 6.3.4.3.389 2009.08.27 - TrendMicro 8.950.0.1094 2009.08.28 - VBA32 3.12.10.10 2009.08.28 - ViRobot 2009.8.28.1907 2009.08.28 - VirusBuster 4.6.5.0 2009.08.28 TrojanSpy.Banker.CDVF Additional information File size: 5102592 bytes MD5 : 504f1c5914799e5122c69620c0b892e2 SHA1 : 32980745998151bda4a9e3bab767201ebc52fc0a SHA256: 54d974192dd53aba186d56803087224ff8f8b0aba9687604332891842bb5ef58
[=]Prolog[=]
Tak jak pewnie udało wam się zauważyć w poprzednim poście malware ten posiada np. zaszyfrowane ścieżki, do których zostaną wykonana jego kopie. Przykładowy zaszyfrowany ciąg wygląda tak:
GpfSH6zZTMrbRdHp865kP21JPNHqQMvdSrn1R6mWLNDbSdDSJMLkTI19RcbZQM5oN51oRsToOMrXSrn9RcbZQM5iQNfXSbnNQMvaRtTpCp8kPNXb
gdzie po deszyfrowaniu otrzymujemy łańcuch:
C:Documents and SettingsAll UsersMenu IniciarProgramasInicializarWindows32.exe
W jaki sposób funkcjonuje ten algorytm ? Tego dowiemy się już za chwilę.
Wcześniej jednak sprecyzuje „elementy”, które w tym malware’e wymagają deszyfrowania:
– ścieżki, do który kopiowany jest malware
– tytuły okien IE(malware używa tytułów okien do rozpoznania czy user znajduje się obecnie na stronie, dla której trojan ma przygotowany np. fałszywy panel logowania)
– treść fałszywych komunikatów mówiących o tym, że np. Internet Explorer wykonał
nieprawidłową operacje i zostanie zamknięty.
w niektórych wersjach także:
– login&hasło do serwera ftp/mysql używanego jako drop host
– adresy email na które mają zostać przesłane skradzione dane
Warto tutaj wspomnieć o różnicy, która występuje w podejściu autorów trojana obecnego i tego z poprzedniego postu. Jak pamiętamy tam autor nie dość, że stosował różnego rodzaju klucze xor’ujące to jeszcze zmieniały się w nieznacznym stopniu same procedury szyfrowania. Tutaj spoglądając na wygląd ciągów reprezentujących zaszyfrowane dane:
Można zakładać, że procedura deszyfrująca jest jedna, globalna. Po dokładnej analizie okazuje się, że faktycznie tak jest i nadszedł czas żeby przyjrzeć się jej bliżej.
Oczywiście jej lokalizację można w prosty sposób ustalić po przez przejście do kawałka kodu, który odwołuje się do jednego z zaszyfrowanych ciągów:
Wywołanie funkcji deszyfrującej. Oczywiście argumenty, są przekazywane zgodnie z konwencja __fastcall typową dla Borlanda.
[=]Analiza[=]
Procka deszyfrująca przedstawia się następująco:
gdzie:
ESI – długość zaszyfrowanego ciągu
Local.1 – pointer na zaszyfrowany ciąg
Jak widać procka jest o wiele pokaźniejsza od tych, które mogliśmy obserwować w poprzednim malware’e.
[=]Deszyfrowanie[=]
Bez większe zastanawiania się tworzymy decryptor, który w pythonie przedstawia się następująco:
import sys #Delephant decryption script ascii_table = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz+/" def decrypt(encrypted): decrypted = [] local_4 = 0 edi = 0 for index in range(0,len(encrypted)): pos = ascii_table.find(encrypted[index]) if pos < 0: return "Encrypted string is in unproper format" pos = pos + (local_4 << 6) local_4 = pos edi = edi + 6 if edi < 8: continue edi = edi - 8 local_4 = local_4 % ( 1 <> (edi & 0xff) ) & 0x800000ff if pos < 0: pos = ( (pos - 1) & 0xffffff00 ) + 1 decrypted.append( chr(pos) ) return "".join(decrypted) if __name__ == "__main__": if len(sys.argv) < 2: print "Usage: %s encrypted_string" % sys.argv[0] sys.exit(0) print decrypt(sys.argv[1])
Rezultat deszyfrowania losowo wybranych stringów:
Warto tutaj zauważyć jedną znacząco różnice:
MOV EAX,[Local.5] ; kolejny znak z zaszyfrowanego ciagu
MOV EDX,zloavgtr.00480BAC ; ASCI „0123456789ABCD….”
CALL StrPos
MOV EBX,EAX
DEC EBX
i odpowiednik tego kodu w Python’e:
pos = ascii_table.find(encrypted[index])
Trzeba być tutaj świadomym jednej rzeczy, a mianowicie tego ze StrPos Borlandowy indexuje pozycje znaków w stringu od 1 a find Pythonowy od 0. Dlatego też w kodzie pythona nie pojawia się dekrementacja wartości pozycji znaku do odszyfrowania.
[=]Epilog[=]
Jak można zauważyć, procedura deszyfrująca tego trojana jest objętościowa ok.3 razy większa od tych, z którymi mieliśmy do czynienie w poprzednim sampel’u co jednak nie przeszkodziło nam w stworzeniu python’ego decryptor’a.
Jeżeli chodzi o algorytmy wykorzystywanego przez ten malware’u do „szyfrowania„ skradzionych danych to są to przeważnie:
– URL Encode
– Base64
ze względu na powszechność nie zostały one tutaj opisane.
Na sam koniec dla ciekawych, chcących przeanalizować krok po kroku działanie decryptor’a pare stringów do deszyfracji:
“IKLuS6nlScK”
“IMvcRt9jOUVZRo1fRcDlSd9bT64X851oPMLkOsXX86DlSd9bT65jPMvqPI1l86DXRN1l84HfPsbqRou”
“H65aRtCWIMvZRt9oPNHlSomWK6zo86PXTczo86HfPsbqPI1kRtPXRMLkT6Kk”
“K6zo86PXTczoB21fRcPlScrb86baPMvqQMPfOs7dusyi865dPMvZQM4i86DlRdHX”
“Kt8eOIak84PXTczo86HfPsbqON8WOI1pTM4WSsLkQ64WP64WT65YPMnX86DlSd9bT65jPMvqPIu”
“LNDruN9fRoukBYukBYukBYukBZe”
“K6zo86rlT6bsRo1aPI1JPMTrSc5kvs4WSsLr84D1KbJ3Jo14HI1JHKTLKa5Enq4WP6LsPI1pPN8WKcLZOMHXStHoOMHlB21JRsnfOsbqOMrlSo1nTMKWLczZwY18OM9fR6bqPI1pPNKWGs5oTEDl86Hb85DbPtLoOMxdOI1ERtPXRMLkT6Kk”
“Gc5kOsyWINHX+Y0j84PbQNHl851XSc4WLczZwY0WBI1DQMDoRtDlPdGWIMvqPN9kPNGWHNXmR6zoPN8”