hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

RELiC
Microsoft RPC Heap Corruption Vulnerability - Part II
Date: 2003-09-10

Author : Marc Maiffret <marc@eeye.com>

Microsoft RPC Heap Corruption Vulnerability - Part II

Release Date:
September 10, 2003

Severity:
High (Remote Code Execution)

Systems Affected:
Microsoft Windows NT Workstation 4.0
Microsoft Windows NT Server 4.0
Microsoft Windows NT Server 4.0, Terminal Server Edition
Microsoft Windows 2000
Microsoft Windows XP
Microsoft Windows Server 2003

Description:

eEye Digital Security has discovered a critical remote vulnerability in the way Microsoft Windows handles certain RPC requests. The RPC (Remote Procedure Call) protocol provides an inter-process communication mechanism allowing a program running on one computer to execute code on a remote system.

A vulnerability exists within the DCOM (Distributed Component Object Model) RPC interface. This interface handles DCOM object activation requests sent by client machines to the server.

Note: this vulnerability differs from the vulnerability publicized in Microsoft Bulletin MS03-026.
(http://www.microsoft.com/technet/security/bulletin/MS03-026.asp)
This is a new vulnerability, and a different patch that must be installed.

By sending a malformed request packet it is possible to overwrite various heap structures and allow the execution of arbitrary code.

Technical Details:

The vulnerability can be replicated with a DCERPC "bind" packet, followed by a malformed DCERPC DCOM object activation request packet. Issuing the API function CoGetInstanceFromFile can generate the required request. By manipulating the length fields within the activation packet, portions of heap memory can be overwritten with data which may be user-defined.

Sending between 4 and 5 activation packets is generally sufficient to trigger the overwrite.

Upon sending the sequence of packets we were able to continually cause an exception within the usual suspect RtlAllocateHeap:

PAGE:77FC8F11 mov [ecx], eax
PAGE:77FC8F13 mov [eax+4], ecx

We control the values of the registers eax and ecx. We can write an arbitrary dword to any address of our choosing.

Execution of code can be achieved through a number of means -- the unhandledexceptionfilter or a PEB locking pointer for instance. For this specific vulnerability the best route was to overwrite a pointer within the writeable .data section of RPCSS.DLL :

.data:761BC254 off_761BC254 dd offset loc_761A1AE7 ; DATA XREF:
sub_761A19EF+1C_r
.data:761BC254 ; sub_761A19EF+11D_w
...
.data:761BC258 off_761BC258 dd offset loc_761A1B18 ; DATA XREF:
sub_761A19EF+108_w
.data:761BC258 ; sub_761A1DCF+13_r
...

At runtime these two pointers reference RtlAllocateHeap and RtlFreeHeap respectively. By overwriting offset 0x761BC258 with our chosen EIP value, we control the processor directly after the heap overwrite. The added benefit in choosing this pointer is we have data from our received packet at ebp->10h which we may modify to our liking, within reason. There is one small obstacle that must be overcome. The first word value at that address is the length field of our packet, this field must translate to an opcode sequence that will allow us to reach our data that follows.

Protection:
Retina Network Security Scanner has been updated to identify this vulnerability.
http://www.eeye.com/html/Products/Retina/index.html
Also our FREE RPC scanner tool has been updated to check for this second vulnerability.
http://www.eeye.com/html/Research/Tools/RPCDCOM.html

Vendor Status:
Microsoft has released a patch for this vulnerability. The patch is available at:
http://www.microsoft.com/technet/treeview/...in/MS03-039.asp

Credit:
Discovery: Barnaby Jack
Additional Research: Barnaby Jack and Riley Hassell.

Copyright © 1998-2003 eEye Digital Security
Permission is hereby granted for the redistribution of this alert electronically. It is not to be edited in any way without express consent of eEye. If you wish to reprint the whole or any part of this alert in any other medium excluding electronic medium, please e-mail alert@eEye.com for permission.

Disclaimer
The information within this paper may change without notice. Use of this information constitutes acceptance for use in an AS IS condition. There are NO warranties with regard to this information. In no event shall the author be liable for any damages whatsoever arising out of or in connection with the use or spread of this information. Any use of this information is at the user's own risk.
Hyp3r
RPC is not new or`is this a new rpc exploit?
Have you the new exploit?

Grezz
Hyp3r
Thebox
Is a new rpc bug. blink.gif
Hyp3r
wow biggrin.gif
great
have you a exploit for this?
Daume
yeah we need it compile tongue.gif
crackie

# The script code starts here
#
function dcom_recv(socket)
{
local_var buf, len;
buf = recv(socket:socket, length:10);
if(strlen(buf) != 10)return NULL;
len = ord(buf[8]);
len += ord(buf[9])*256;
buf += recv(socket:socket, length:len - 10);
return buf;
}
port = 135;
if(!get_port_state(port))port = 593;
else {
soc = open_sock_tcp(port);
if(!soc)port = 593;
else close(soc);
}
if(!get_port_state(port))exit(0);
#-------------------------------------------------------------#
function hex2raw(s)
{
local_var i, j, ret;
for(i=0;i<strlen(s);i+=2)
{
if(ord(s[i]) >= ord("0") && ord(s[i]) <= ord("9"))
j = int(s[i]);
else
j = int((ord(s[i]) - ord("a")) + 10);
j *= 16;
if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9"))
j += int(s[i+1]);
else
j += int((ord(s[i+1]) - ord("a")) + 10);
ret += raw_string(j);
}
return ret;
}
#--------------------------------------------------------------#
function check(req)
{
local_var soc, bindstr, error_code, r;
soc = open_sock_tcp(port);
if(!soc)exit(0);
bindstr =
& quot;05000b03100000004800000001000000d016d016000000000100000000000100a0010000000
00000c00000000000004600000000045d888aeb1cc9119fe808002b10486002000000";
send(socket:soc, data:hex2raw(s:bindstr));
r = dcom_recv(socket:soc);
if(!r)exit(0);
send(socket:soc, data:req);
r = dcom_recv(socket:soc);
if(!r)return NULL;
close(soc);
error_code = substr(r, strlen® - 4, strlen®);
return error_code;
}
function check2(req)
{
local_var soc,bindstr, error_code, r;
soc = open_sock_tcp(port);
if(!soc)exit(0);
bindstr =
& quot;05000b03100000004800000001000000d016d016000000000100000000000100a0010000000
00000c00000000000004600000000045d888aeb1cc9119fe808002b10486002000000";
send(socket:soc, data:hex2raw(s:bindstr));
r = dcom_recv(socket:soc);
if(!r)exit(0);
send(socket:soc, data:req);
r = dcom_recv(socket:soc);
if(!r)return NULL;
error_code = substr(r, strlen® - 24, strlen® - 20);
return error_code;
}
#---------------------------------------------------------------#
# Determine if we the remote host is running Win95/98/ME
bindwinme =
& quot;05000b03100000004800000053535641d016d016000000000100000000000100e6730ce6f98
8cf119af10020af6e72f402000000045d888aeb1cc9119fe808002b10486002000000";
soc = open_sock_tcp(port);
if(!soc)exit(0);
send(socket:soc, data:hex2raw(s:bindwinme));
rwinme = dcom_recv(socket:soc);
close(soc);
lenwinme = strlen(rwinme);
stubwinme = substr(rwinme, lenwinme-24, lenwinme-21);
# This is Windows 95/98/ME which is not vulnerable
if("02000100" >< hexstr(stubwinme))exit(0);
#----------------------------------------------------------------#
REGDB_CLASS_NOTREG = "5401048000";
CO_E_BADPATH = "0400088000";
NT_QUOTE_ERROR_CODE_EQUOTE = "00000000";
#
req1 =
& quot;0500000310000000b0030000010000009803000000000400050002000000000000000000000
0000000000000000000000000000000000000000000009005140068030000680300004d454f57040
00000a201000000000000c0000000000000463803000000000000c00000000000004600000000380
30000300300000000000001100800ccccccccc80000000000000030030000d800000000000000020
00000070000000000000000000000000000000000000018018d00b8018d000000000007000000b90
1000000000000c000000000000046ab01000000000000c000000000000046a501000000000000c00
0000000000046a601000000000000c000000000000046a401000000000000c000000000000046ad0
1000000000000c000000000000046aa01000000000000c0000000000000460700000060000000580
000009000000058000000200000006800000030000000c000000001100800cccccccc50000000000
00000ffffffff0000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000001100800cccccccc4800000000000000005d889aeb1cc9119fe808002b10486010000000000
00000000000000100000000000000b84!
70a005800
000005000600010000000000000000000000c000000000000046cccccccc01100800cccccccc8000
0000000000000000000000000000000000000000000020ba09000000000060000000600000004d45
4f5704000000c001000000000000c0000000000000463b03000000000000c0000000000000460000
00003000000001000100673c70941333fd4687244d093988939d0200000000000000000000000000
000000000000000000000100000001100800cccccccc480000000000000000000000b07e09000000
000000000000f0890a0000000000000000000d000000000000000d000000730061006a0069006100
6400650076005f0078003800360000000800cccccccc01100800cccccccc10000000000000000000
000000000000000000000000000001100800cccccccc5800000000000000c05e0a00000000000000
0000000000001b000000000000001b0000005c005c0000005c006a00690061006400650076005f00
7800000036005c007000750062006c00690063005c00410041004100410000000000010015000110
0800cccccccc200000000000000000000000905b09000200000001006c00c0df0800010000000700
550000000000";
req2 =
& quot;0500000310000000b0030000020000009803000000000400050002000000000000000000000
0000000000000000000000000000000000000000000009005140068030000680300004d454f57040
00000a201000000000000c0000000000000463803000000000000c00000000000004600000000380
30000300300000000000001100800ccccccccc80000000000000030030000d800000000000000020
00000070000000000000000000000000000000000000018018d00b8018d000000000007000000b90
1000000000000c000000000000046ab01000000000000c000000000000046a501000000000000c00
0000000000046f601000000000000c000000000000046ff01000000000000c000000000000046ad0
1000000000000c000000000000046aa01000000000000c0000000000000460700000060000000580
000009000000058000000200000006800000030000000c000000001100800cccccccc50000000000
00000ffffffff0000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000001100800cccccccc4800000000000000005d889aeb1cc9119fe808002b10486010000000000
00000000000000100000000000000b84!
70a005800
000005000600010000000000000000000000c000000000000046cccccccc01100800cccccccc8000
0000000000000000000000000000000000000000000020ba09000000000060000000600000004d45
4f5704000000c001000000000000c0000000000000463b03000000000000c0000000000000460000
00003000000001000100673c70941333fd4687244d093988939d0200000000000000000000000000
000000000000000000000100000001100800cccccccc480000000000000000000000b07e09000000
000000000000f0890a0000000000000000000d000000000000000d000000730061006a0069006100
6400650076005f0078003800360000000800cccccccc01100800cccccccc10000000000000000000
000000000000000000000000000001100800cccccccc5800000000000000c05e0a00000000000000
0000000000001b000000000000001b0000005c005c0000005c006a00690061006400650076005f00
7800000036005c007000750062006c00690063005c00410041004100410000000000010015000110
0800cccccccc200000000000000000000000905b09000200000001006c00c0df0800010000000700
550000000000";
req3 =
& quot;05000e03100000004800000003000000d016d01605af00000100000001000100b84a9f4d1c7
dcf11861e0020af6e7c5700000000045d888aeb1cc9119fe808002b10486002000000";
req4 =
& quot;05000003100000009a000000030000008200000001000000050002000000000000000000000
00000000000000000000000000000000000009596952a8cda6d4ab23619bcaf2c2dea34eb8f00070
0000000000000070000005c005c004d0045004f00570000000000000000005c0048005c004800010
0000058e98f00010000009596952a8cda6d4ab23619bcaf2c2dea01000000010000005c00";
#display(hex2raw(s:req));
#exit(0);
error1 = check(req:hex2raw(s:req1));
error2 = check(req:hex2raw(s:req2));
#error3 = check(req:hex2raw(s:req3));
#error4 = check2(req:hex2raw(s:req4));
#display("error1=", hexstr(error1), "\n");
#display("error2=", hexstr(error2), "\n");
#display("error3=", hexstr(error3), "\n");
#display("error4=", hexstr(error4), "\n");
if(hexstr(error2) == hexstr(error1))
{
if(hexstr(error1) == "0500078000")exit(0); # DCOM disabled
security_hole(port);
}
else {
set_kb_item(name:"SMB/KB824146", value:TRUE);
}

by nessus !
Kenshin
so is that now the remote exploit for the new rpc hole , if yes somebody have to compile this code smile.gif) !!!
And big thx for the code crackie !!
fertile
That is just proof of concept code, you have zero chance of getting that to compile... you'd be there at a shell for days watching the errors fly by smile.gif

But the example is there and in time an exploit will come. Most people are still on high alert from the last RPC problem so as juicy as this 3 pronged RPCSS problem is, it is unlikley to be as fun as the last time.
Kenshin
Yes that can be , so we have to wait for a other exploit !! sad.gif
mekros
you can try that script if you have nessus...
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.