I. Introduction
Nous allons voir un calcule de hash que vous rencontrerez
indirectement lors d'analyse
Ce hash est basé sur SHL avec comme valeur 1 et moins
utilisé que les familles ROL ou ROR
Mais comme elle apparaît de plus en plus dans des
échantillons sur les sous éléments d'un malware. Il est utile de repasser
dessus et refaire un petit tour sur celui-ci.
II. Référence des Hashs Api et Module
Nous mettons un petit tableau de hash classique en
SHL1AdditiveLowercase pour trouver d'autre exemple ou d'article sur cette
algorithme de hash.
Hash
|
String
|
0x000D4E88
|
Kernel32.dll
|
0x0003AB08
|
WS2_32.dll
|
0x000CA608
|
ADVAPI.dll
|
0x00037908
|
MSVCRT.dll
|
0x000D5786
|
LoadLibraryA
|
0x00348BFA
|
GetProcAddress
|
0x0038D13C
|
VirtualProtect
|
0x0000677C
|
Connect
|
0x069BB2E6
|
GetSystemDirectoryA
|
0x0006BC6A
|
ExitProcess
|
0x00000C4E
|
Free
|
0x000DCDB4
|
RevertToSelf
|
0x00067746
|
CreateFileA
|
0x00000CD8
|
Send
|
0x00000CC0
|
recv
|
0x000D269A
|
GetStdHandle
|
0x00000CD8
|
Send
|
0x0001CA42
|
WriteFile
|
0x00039314
|
WSAStartup
|
0x000036A4
|
Socket
|
0x0000D562
|
ReadFile
|
III. Algorithme de création des hashs
Nous avons implémenté une fonction en C effectuant ce
calcule de hash gérant les deux mode de chaîne ANSI ou UNICODE. Car vous
trouverez beaucoup de model de cette fonction dans différent shellcode à base
de cette algorithme de hash gérant cela comme ceci.
DWORD
GetHashShl1AdditiveLowercaseWithSelectorTypeString(char*
pName,DWORD dwMod)
{
int idx
= 0;
DWORD dwHash=0x0;
do
{
char
c =(DWORD)pName[idx];
c = c|0x60;
dwHash = dwHash+ c;
dwHash = dwHash << 1;
idx +=dwMod;
}while(pName[idx]!=0x00);
return
dwHash;
}
|
Nous avons intégré cela dans un petit programme pour le
calcule de hash sous le bouton "Hash1 Asm" et effectué la capture
avec comme string "LoadLibraryA" qui nous renvoi la valeur 0x000D5786
Nous avons également intégré une version assembleur de la
fonction
DWORD
__declspec(naked) __stdcall
AsmHashShl1AdditiveLowercaseWithSelectorTypeStringV2(char* pName,DWORD
dwType)
{
__asm
{
push ebp
mov ebp, esp
push ecx
push ebx
push edx
xor ecx, ecx
xor ebx, ebx
xor edx, edx
mov eax,
[ebp+0x8] ; target string
hashloop:
mov dl,
[eax]
or dl, 0x60
add ebx,
edx ; Add hash to value carac
shl ebx, 1
add eax,
[ebp+0xc] ; Add address to eax ASCII of UNICODE flag
mov cl,
[eax]
test cl, cl
jnz
hashloop
mov eax, ebx
pop edx
pop ebx
pop ecx
mov esp, ebp
pop ebp
ret 8 ; ret and cleanup stack
argument
}
}
|
Attention
Traditionnellement, les appels de fonction C sont effectués
avec l'appelant qui pousse certains paramètres sur la pile, En appelant la
fonction, lors du retour de la fonction l'appelant et en charge de nettoyer ces
arguments poussés ou plus simplement que la pile revient à l'état initial.
D'autre convention existe dont __stdcall. Dans celui-ci, les
paramètres sont à nouveau définis par l'appelant et passé par la pile, mais la
pile est nettoyée directement par la fonction appelé. Il s'agit de la
convention standard pour les fonctions de l'API Win32
(telle que définie par la macro WINAPI dans
<windows.h>). Elle est parfois appelée convention d'appel
"Pascal" lié au passé.
Nous pouvons également utiliser l'option de compilation / Gz
pour spécifier __stdcall pour toutes les fonctions non explicitement déclarées
avec une autre convention d'appel.
Il est assez simple de repérer cela au niveau de
l'assembleur via le code instruction "ret" quand elle est écrit 0xC2
0xXX 0xYY
ou le nombre qui suit l'opcode C2 correspond on décalage de
pile avant retour ( Esp = Esp + YYXXh )
nous avons utiliser cette convention dans notre fonction
incluant également le fait que le souhaite pas de Prolog et d'Epilog via __declspec(naked).
Dans notre outil cette fonction correspond au bouton
"Hash2 Asm", et vous pouvez voir qu'elle renvoi également le hash
souhaité pour notre chaîne "LoadLibraryA".
IV. Cas pratique dans un échantillon
Maintenant que vous avez les bases, on va rentrer plus dans
le détaille sur un exemple pris d'un bloc d'échantillon d'un malware ( le bloc
est une partie du sous élément du packer )
Dont voici le listing dumper du bloc extrait
0000 E8 14 02 00
00 33 C0 C3 8B 54 24 0C 8B 4C 24 04
.....3...T$..L$.
0010 8B C2 4A 57 8B F9 85 C0 74 12 56 8D 72 01
8B 54 ..JW....t.V.r..T
0020 24 10 8A 02 88 01 41 42 4E 75 F7 5E 8B C7
5F C3 $.....ABNu.^.._.
0030 55 8B EC 51 51 53 56 57 90 90 90 90 68 86
57 0D U..QQSVW....h.W.
0040 00 68 88 4E 0D 00 E8 1A 00 00 00 89 45 FC
68 FA .h.N........E.h.
0050 8B 34 00 68 88 4E 0D 00 E8 08 00 00 00 89
45 F8 .4.h.N........E.
0060 E9 B9 00 00 00 55 8B EC 53 56 57 51 64 FF
35 30 .....U..SVWQd.50
0070 00 00 00 58 8B 40 0C 8B 48 0C 8B 11 8B 41
30 6A ...X.@..H....A0j
0080 02 8B 70 08
57 50 E8 5B 00 00 00 85 C0 74 04 8B
..p.WP.[.....t..
0090 CA EB E7 8B
41 18 50 8B 58 3C 03 C3 8B 58 78 58
....A.P.X<...XxX
00A0 50 03 D8 8B 4B 1C 8B 53 20 8B 5B 24 03 C8
03 D0 P...K..S .[$....
00B0 03 D8 8B 32 58 50 03 F0 6A 01 FF 75 0C 56
E8 23 ...2XP..j..u.V.#
00C0 00 00 00 85 C0 74 08 83 C2 04 83 C3 02 EB
E3 58 .....t.........X
00D0 33 D2 66 8B 13 C1 E2 02 03 CA 03 01 59 5F
5E 5B 3.f.........Y_^[
00E0 8B E5 5D C2 08 00 55 8B EC 51 53 52 33 C9
33 DB ..]...U..QSR3.3.
00F0 33 D2 8B 45 08 8A 10 80 CA 60 03 DA D1 E3
03 45 3..E.....`.....E
0100 10 8A 08 84 C9 E0 EE 33 C0 8B 4D 0C 3B D9
74 05 .......3..M.;.t.
0110 90 90 90 90 40 5A 5B 59 8B E5 5D C2 0C 00
8B 45 ....@Z[Y..]....E
0120 08 8B 4D FC 5F 5E 89 08 8B 45 0C 8B 4D F8
5B 89 ..M._^...E..M.[.
0130 08 C9 C3 55 8B EC 81 EC 08 04 00 00 53 56
33 DB ...U........SV3.
0140 57 33 D2 8D 85 F8 FB FF FF B9 00 01 00 00
89 10 W3..............
0150 42 83 C0 04 3B D1 7C F6 33 FF 8D B5 F8 FB
FF FF B...;.|.3.......
0160 8B C7 33 D2 F7 75 14 8B 45 0C 0F B6 04 02
03 06 ..3..u..E.......
0170 03 C3 8B D9 99 F7 FB 8A 06 47 88 45 FF 8B
DA 8B .........G.E....
0180 94 9D E8 EB FF FF 89 16 83 C6 04 0F B6 55
FF 8D .............U..
|
Nous avons passer dans outil pour effectuer une
transformation en un format shellcode de ce dump ( bloc binary )
Nous avons remis en
dessous le shellcode obtenu
\xE8\x14\x02\x00\x00\x33\xC0\xC3\x8B\x54\x24\x0C\x8B\x4C\x24\x04
\x8B\xC2\x4A\x57\x8B\xF9\x85\xC0\x74\x12\x56\x8D\x72\x01\x8B\x54
\x24\x10\x8A\x02\x88\x01\x41\x42\x4E\x75\xF7\x5E\x8B\xC7\x5F\xC3
\x55\x8B\xEC\x51\x51\x53\x56\x57\x90\x90\x90\x90\x68\x86\x57\x0D
\x00\x68\x88\x4E\x0D\x00\xE8\x1A\x00\x00\x00\x89\x45\xFC\x68\xFA
\x8B\x34\x00\x68\x88\x4E\x0D\x00\xE8\x08\x00\x00\x00\x89\x45\xF8
\xE9\xB9\x00\x00\x00\x55\x8B\xEC\x53\x56\x57\x51\x64\xFF\x35\x30
\x00\x00\x00\x58\x8B\x40\x0C\x8B\x48\x0C\x8B\x11\x8B\x41\x30\x6A
\x02\x8B\x70\x08\x57\x50\xE8\x5B\x00\x00\x00\x85\xC0\x74\x04\x8B
\xCA\xEB\xE7\x8B\x41\x18\x50\x8B\x58\x3C\x03\xC3\x8B\x58\x78\x58
\x50\x03\xD8\x8B\x4B\x1C\x8B\x53\x20\x8B\x5B\x24\x03\xC8\x03\xD0
\x03\xD8\x8B\x32\x58\x50\x03\xF0\x6A\x01\xFF\x75\x0C\x56\xE8\x23
\x00\x00\x00\x85\xC0\x74\x08\x83\xC2\x04\x83\xC3\x02\xEB\xE3\x58
\x33\xD2\x66\x8B\x13\xC1\xE2\x02\x03\xCA\x03\x01\x59\x5F\x5E\x5B
\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x51\x53\x52\x33\xC9\x33\xDB
\x33\xD2\x8B\x45\x08\x8A\x10\x80\xCA\x60\x03\xDA\xD1\xE3\x03\x45
\x10\x8A\x08\x84\xC9\xE0\xEE\x33\xC0\x8B\x4D\x0C\x3B\xD9\x74\x05
\x90\x90\x90\x90\x40\x5A\x5B\x59\x8B\xE5\x5D\xC2\x0C\x00\x8B\x45
\x08\x8B\x4D\xFC\x5F\x5E\x89\x08\x8B\x45\x0C\x8B\x4D\xF8\x5B\x89
\x08\xC9\xC3\x55\x8B\xEC\x81\xEC\x08\x04\x00\x00\x53\x56\x33\xDB
\x57\x33\xD2\x8D\x85\xF8\xFB\xFF\xFF\xB9\x00\x01\x00\x00\x89\x10
\x42\x83\xC0\x04\x3B\xD1\x7C\xF6\x33\xFF\x8D\xB5\xF8\xFB\xFF\xFF
\x8B\xC7\x33\xD2\xF7\x75\x14\x8B\x45\x0C\x0F\xB6\x04\x02\x03\x06
\x03\xC3\x8B\xD9\x99\xF7\xFB\x8A\x06\x47\x88\x45\xFF\x8B\xDA\x8B
\x94\x9D\xE8\xEB\xFF\xFF\x89\x16\x83\xC6\x04\x0F\xB6\x55\xFF\x8D
|
Nous le passons au travers de notre désassembleur de
Shellcode X32
Nous avons remis le listing obtenu
00000000: E8 14 02 00 00 CALL 00000214h (+214h ->:00000219)
00000005: 33 C0 XOR EAX,EAX
00000007: C3 RET
00000008: 8B 54 24 0C MOV EDX,DWORD PTR [ESP+0Ch]
0000000C: 8B 4C 24 04 MOV ECX,DWORD PTR[ESP+0x04]
00000010: 8B C2 MOV
EAX,EDX
00000012: 4A DEC
EDX
00000013: 57 PUSH
EDI
00000014: 8B F9 MOV
EDI,ECX
00000016: 85 C0 TEST
EAX,EAX
00000018: 74 12 JZ
0x12 (+12h ->:0000002C)
0000001A: 56 PUSH
ESI
0000001B: 8D 72 01 LEA
ESI,[EDX+0x01]
0000001E: 8B 54 24 10 MOV EDX,DWORD PTR [ESP+10h]
00000022: 8A 02 MOV
AL , BYTE PTR [EDX]
00000024: 88 01 MOV
BYTE PTR[ECX],AL
00000026: 41 INC ECX
00000027: 42 INC EDX
00000028: 4E DEC
ESI
00000029: 75 F7 JNZ
F7h (rel8)(-09h ->:00000022)
0000002B: 5E POP
ESI
0000002C: 8B C7 MOV
EAX,EDI
0000002E: 5F POP
EDI
0000002F: C3 RET
00000030: 55 PUSH
EBP
00000031: 8B EC MOV
EBP,ESP
00000033: 51 PUSH
ECX
00000034: 51 PUSH
ECX
00000035: 53 PUSH
EBX
00000036: 56 PUSH
ESI
00000037: 57 PUSH
EDI
00000038: 90 NOP
00000039: 90 NOP
0000003A: 90 NOP
0000003B: 90 NOP
0000003C: 68 86 57 0D 00 PUSH 000D5786h "†W " dw:874374 / {134
87 13 0} / < w:3328 | w:34391 >
00000041: 68 88 4E 0D 00 PUSH 000D4E88h "ˆN " dw:872072 / {136
78 13 0} / < w:3328 | w:34894 >
00000046: E8 1A 00 00 00 CALL 0000001Ah (+1Ah ->:00000065)
db
"‰Eühú‹4"
0000004B: 89 45 FC 68 FA 8B 34 00
00000053: 68 88 4E 0D 00 PUSH 000D4E88h "ˆN " dw:872072 / {136
78 13 0} / < w:3328 | w:34894 >
00000058: E8 08 00 00 00 CALL 00000008h (+08h ->:00000065)
db
"‰Eøé¹"
0000005D: 89 45 F8 E9 B9 00
00000063: 00 00 ADD
BYTE PTR[EAX],AL
00000065: 55 PUSH
EBP
00000066: 8B EC MOV
EBP,ESP
00000068: 53 PUSH
EBX
00000069: 56 PUSH
ESI
0000006A: 57 PUSH
EDI
0000006B: 51 PUSH
ECX
0000006C: 64 FF 35 30 00 00 00 PUSH DWORD PTR FS:[00000030h]
00000073: 58 POP
EAX
00000074: 8B 40 0C MOV
EAX,DWORD PTR[EAX+0x0C]
00000077: 8B 48 0C MOV
ECX,DWORD PTR[EAX+0Ch]
0000007A: 8B 11 MOV
EDX,DWORD PTR [ECX]
0000007C: 8B 41 30 MOV
EAX,DWORD PTR[ECX+0x30]
0000007F: 6A 02 PUSH
02h (2) '[1]'
00000081: 8B 70 08 MOV
ESI,DWORD PTR[EAX+08h]
00000084: 57 PUSH
EDI
00000085: 50 PUSH
EAX
00000086: E8 5B 00 00 00 CALL 0000005Bh (+5Bh ->:000000E6)
0000008B: 85 C0 TEST
EAX,EAX
0000008D: 74 04 JZ
0x04 (+04h ->:00000093)
0000008F: 8B CA MOV
ECX,EDX
00000091: EB E7 JMP
E7h (-19h ->:0000007A)
00000093: 8B 41 18 MOV
EAX,DWORD PTR[ECX+0x18]
00000096: 50 PUSH
EAX
00000097: 8B 58 3C MOV
EBX,DWORD PTR [EAX+3Ch]
0000009A: 03 C3 ADD
EAX,EBX
0000009C: 8B 58 78 MOV
EBX,DWORD PTR [EAX+78h]
0000009F: 58 POP
EAX
000000A0: 50 PUSH
EAX
000000A1: 03 D8 ADD
EBX,EAX
000000A3: 8B 4B 1C MOV
ECX,DWORD PTR [EBX+1Ch]
000000A6: 8B 53 20 MOV
EDX,DWORD PTR[EBX+0x20]
000000A9: 8B 5B 24 MOV
EBX,DWORD PTR [EBX+24h]
000000AC: 03 C8 ADD
ECX,EAX
000000AE: 03 D0 ADD
EDX,EAX
000000B0: 03 D8 ADD
EBX,EAX
000000B2: 8B 32 MOV
ESI,DWORD PTR[EDX]
000000B4: 58 POP
EAX
000000B5: 50 PUSH
EAX
000000B6: 03 F0 ADD
ESI,EAX
000000B8: 6A 01 PUSH
01h (1) ''
000000BA: FF 75 0C PUSH
DWORD PTR [EBP+0Ch]
000000BD: 56 PUSH
ESI
000000BE: E8 23 00 00 00 CALL 00000023h (+23h ->:000000E6)
000000C3: 85 C0 TEST
EAX,EAX
000000C5: 74 08 JZ
0x08 (+08h ->:000000CF)
000000C7: 83 C2 04 ADD
EDX,04h (ADD(r/m16,imm8))
000000CA: 83 C3 02 ADD
EBX,02h (ADD(r/m16,imm8))
000000CD: EB E3 JMP
E3h (-1Dh ->:000000B2)
000000CF: 58 POP
EAX
000000D0: 33 D2 XOR
EDX,EDX
000000D2: 66 8B 13 MOV
DX,WORD PTR[EBX]
000000D5: C1 E2 02 SHL
EDX,02h
000000D8: 03 CA ADD
ECX,EDX
000000DA: 03 01 ADD
EAX,DWORD PTR[ECX]
000000DC: 59 POP
ECX
000000DD: 5F POP
EDI
000000DE: 5E POP ESI
000000DF: 5B POP
EBX
000000E0: 8B E5 MOV
ESP,EBP
000000E2: 5D POP EBP
000000E3: C2 08 00 RET(imm16)
0008h
000000E6: 55 PUSH
EBP
000000E7: 8B EC MOV
EBP,ESP
000000E9: 51 PUSH
ECX
000000EA: 53 PUSH
EBX
000000EB: 52 PUSH
EDX
000000EC: 33 C9 XOR
ECX,ECX
000000EE: 33 DB XOR
EBX,EBX
000000F0: 33 D2 XOR
EDX,EDX
000000F2: 8B 45 08 MOV
EAX,DWORD PTR [EBP+08h]
000000F5: 8A 10 MOV
DL, BYTE PTR[EAX]
000000F7: 80 CA 60 OR
DL,0x60
000000FA: 03 DA ADD
EBX,EDX
000000FC: D1 E3 SHL
EBX,1
000000FE: 03 45 10 ADD
EAX,DWORD PTR [EBP+10h]
00000101: 8A 08 MOV
CL, BYTE PTR [EAX]
00000103: 84 C9 TEST
CL,CL
00000105: E0 EE LOOPNE
EEh (-FFFFFFEEh=>:000000F5)
00000107: 33 C0 XOR
EAX,EAX
00000109: 8B 4D 0C MOV
ECX,DWORD PTR [EBP+0Ch]
0000010C: 3B D9 CMP
EBX,ECX
0000010E: 74 05 JZ
0x05 (+05h ->:00000115)
00000110: 90 NOP
00000111: 90 NOP
00000112: 90 NOP
00000113: 90 NOP
00000114: 40 INC
EAX
00000115: 5A POP
EDX
00000116: 5B POP
EBX
00000117: 59 POP
ECX
00000118: 8B E5 MOV
ESP,EBP
0000011A: 5D POP
EBP
0000011B: C2 0C 00 RET(imm16)
000Ch
0000011E: 8B 45 08 MOV
EAX,DWORD PTR [EBP+08h]
00000121: 8B 4D FC MOV
ECX,DWORD PTR [EBP-04h]
00000124: 5F POP
EDI
00000125: 5E POP
ESI
00000126: 89 08 MOV
DWORD PTR[EAX],ECX
00000128: 8B 45 0C MOV
EAX,DWORD PTR [EBP+0Ch]
0000012B: 8B 4D F8 MOV
ECX,DWORD PTR [EBP-08h]
0000012E: 5B POP
EBX
0000012F: 89 08 MOV
DWORD PTR[EAX],ECX
00000131: C9 LEAVE
( equivaut MOV ESP,EBP / POP EBP) en X86
00000132: C3 RET
00000133: 55 PUSH
EBP
00000134: 8B EC MOV
EBP,ESP
00000136: 81 EC 08 04 00 00 SUB ESP,0x00000408
0000013C: 53 PUSH
EBX
0000013D: 56 PUSH
ESI
0000013E: 33 DB XOR
EBX,EBX
00000140: 57 PUSH EDI
00000141: 33 D2 XOR
EDX,EDX
00000143: 8D 85 F8 FB FF FF LEA EAX,DWORD PTR[EBP - 00000408h]
00000149: B9 00 01 00 00 MOV ECX, 00000100h ""
0000014E: 89 10 MOV
DWORD PTR[EAX],EDX
00000150: 42 INC EDX
00000151: 83 C0 04 ADD
EAX,04h
00000154: 3B D1 CMP
EDX,ECX
00000156: 7C F6 JL
F6h (rel8)(-0Ah ->:0000014E)
00000158: 33 FF XOR
EDI,EDI
0000015A: 8D B5 F8 FB FF FF LEA ESI,[EBP-0x00000408]
00000160: 8B C7 MOV
EAX,EDI
00000162: 33 D2 XOR
EDX,EDX
00000164: F7 75 14 DIV
DWORD PTR[EBP+0x14]
00000167: 8B 45 0C MOV
EAX,DWORD PTR [EBP+0Ch]
0000016A: 0F B6 04 02 MOVZX EAX,BYTE PTR[EDX+EAX*1]
0000016E: 03 06 ADD
EAX,DWORD PTR[ESI]
00000170: 03 C3 ADD
EAX,EBX
00000172: 8B D9 MOV
EBX,ECX
00000174: 99 CDQ
(convert Doubleword to Quadword)
00000175: F7 FB IDIV
EBX
00000177: 8A 06 MOV
AL, BYTE PTR [ESI]
00000179: 47 INC
EDI
0000017A: 88 45 FF MOV
BYTE PTR[EBP-01h],AL
0000017D: 8B DA MOV
EBX,EDX
0000017F: 8B 94 9D E8 EB FF FF MOV EDX,DWORD PTR[EBP+EBX*4-00001418h]
00000186: 89 16 MOV
DWORD PTR[ESI],EDX
00000188: 83 C6 04 ADD
ESI,04h
0000018B: 0F B6 55 FF MOVZX EDX,BYTE PTR[EBP-0x01]
0000018F: 8D
|
Nous avons mis en rouge la partie qui nous intéresse au
dessus et en bleu comment on a ciblé ce
bloc.
En dessous nous avons mis la partie bleu ( en neutralisant
la détection de data , qui mauvaise )
0000003C: 68 86 57 0D 00 PUSH 000D5786h "†W " dw:874374 / {134
87 13 0} / < w:3328 | w:34391 >
00000041: 68 88 4E 0D 00 PUSH 000D4E88h "ˆN " dw:872072 / {136
78 13 0} / < w:3328 | w:34894 >
00000046: E8 1A 00 00 00 CALL 0000001Ah (+1Ah ->:00000065)
0000004B: 89 45 FC MOV
DWORD PTR[EBP-04h],EAX
0000004E: 68 FA 8B 34 00 PUSH 00348BFAh "ú‹4" dw:3443706 / {250
139 52 0} / < w:13312 | w:64139 >
00000053: 68 88 4E 0D 00 PUSH 000D4E88h "ˆN " dw:872072 / {136
78 13 0} / < w:3328 | w:34894 >
00000058: E8 08 00 00 00 CALL 00000008h (+08h ->:00000065)
|
Vous pouvez voir les
hashs de
0x000D5786
|
LoadLibraryA
|
0x00348BFA
|
GetProcAddress
|
0x000D4E88
|
Kernel32.dll
|
maintenant allons regarde la fonction que pointé en
0x00000065 en la regardant, nous arrivons à un appel
000000BE: E8 23 00 00 00 CALL 00000023h
(+23h ->:000000E6)
ou l'on voit le passage d'un des hashs via qui correspond à
l'api rechercher dans le module passer également au travers d'un hash
000000BA: FF 75 0C PUSH DWORD PTR [EBP+0Ch]
Si on regarde de plus en détail cette fonction que l'on va
nommé Fn2( X, Y , Z ,.. )
000000E6: 55 PUSH
EBP
000000E7: 8B EC MOV
EBP,ESP
000000E9: 51 PUSH
ECX
000000EA: 53 PUSH
EBX
000000EB: 52 PUSH
EDX
000000EC: 33 C9 XOR
ECX,ECX
000000EE: 33 DB XOR
EBX,EBX
000000F0: 33 D2 XOR
EDX,EDX
000000F2: 8B 45 08 MOV
EAX,DWORD PTR [EBP+08h]
000000F5: 8A 10 MOV
DL, BYTE PTR[EAX]
000000F7: 80 CA 60 OR
DL,0x60
000000FA: 03 DA ADD
EBX,EDX
000000FC: D1 E3 SHL
EBX,1
000000FE: 03 45 10 ADD
EAX,DWORD PTR [EBP+10h]
00000101: 8A 08 MOV
CL, BYTE PTR [EAX]
00000103: 84 C9 TEST
CL,CL
00000105: E0 EE LOOPNE
EEh (-FFFFFFEEh=>:000000F5)
00000107: 33 C0 XOR
EAX,EAX
00000109: 8B 4D 0C MOV
ECX,DWORD PTR [EBP+0Ch]
0000010C: 3B D9 CMP
EBX,ECX
0000010E: 74 05 JZ
0x05 (+05h ->:00000115)
00000110: 90 NOP
00000111: 90 NOP
00000112: 90 NOP
00000113: 90 NOP
00000114: 40 INC
EAX
00000115: 5A POP
EDX
00000116: 5B POP
EBX
00000117: 59 POP
ECX
00000118: 8B E5 MOV
ESP,EBP
0000011A: 5D POP
EBP
0000011B: C2 0C 00 RET(imm16)
000Ch
|
en rouge on retrouve un bloc de calcule de hash
SHL1AdditiveLowercase caractérisé par le OR ? , 0x60
comme on peut le voir dans l'appel en ligne 0x000000BE , la
fonction prend 3 paramètre
000000B8: 6A 01 PUSH
01h (1) ''
000000BA: FF 75 0C PUSH
DWORD PTR [EBP+0Ch]
000000BD: 56 PUSH
ESI
|
comme EBP+0x0C, correspond au hash de l'Api et le dernier paramêtre le mode
il est assez simple d'écrire le prototype de la fonction et
même ce qu'elle fait via la comparaison inclus dans celle-ci.
DWORD
__stdcall AsmCalculateHashAndCompareToRef(char* pName,DWORD dwHashRef,DWORD
dwMod)
Nous avons implément la dit fonction dans notre testeur
comme ceci.
DWORD
__declspec(naked) __stdcall AsmCalculateHashAndCompareToRef(char* pName,DWORD
dwHashRef,DWORD dwMod)
{
__asm
{
PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH EBX
PUSH EDX
XOR ECX,ECX
XOR EBX,EBX
XOR EDX,EDX
MOV EAX,DWORD PTR [EBP+0x08] ; target string
hashloop:
MOV DL, BYTE PTR[EAX]
OR DL,0x60
ADD EBX,EDX ;
accumulate
SHL EBX,1
ADD EAX,DWORD PTR
[EBP+0x10] ; add to eax ASCII of UNICODE flag
MOV CL, BYTE PTR [EAX]
TEST CL,CL
LOOPNE hashloop ;jnz hashloop
XOR EAX,EAX
MOV ECX,DWORD PTR
[EBP+0x0C]
CMP EBX,ECX
JZ notSearchHash
NOP
NOP
NOP
NOP
INC EAX
notSearchHash:
POP EDX
POP EBX
POP ECX
MOV ESP,EBP
POP EBP
RET 0x000C ; ret and
cleanup stack argument
}
}
|
vous pouvez voir que en passant la chaine correspondant au
hash , la fonction renvoi 0 si le hash calculé à partir de la chaîne est
identique au hash fournit en référence.
Nous avons intégrer la signature de cette fonction dans
notre outil d'analyse de shellcode X32 comme vous pouvez le voir dans la
capture en dessous:
V. Conclusions
L'intérêt si on identifie la méthode
de génération des hashs d'api, on peut lister les Apis utiliser par le
programme malveillant et aussi faire des rapprochement entre des échantillons
différents. Souvent le générateur
peut être aussi une signature de l'auteur. l'auteur de ce programme ou
schellcode utilise des sous-routines ou bloc de shellcode qui on déjà fait
leurs preuve dans d'autre projet et testé
Il faut pas oublier que cela peu
prendre du temps de crée ses tools comme tous développeurs
Il ne réécrit pas tous mais
assembles des blocs comme des classes métier ou dédier à des opérations.
De plus cela permet aussi ciblé des
recherche sur ses hash pour trouvé d'autre code moins visible.
Nous espérons que ses quelque ligne,
vous apporterons d'autre voix à explorer.
Aucun commentaire:
Enregistrer un commentaire