PLanET ABhisEK
< March 2007 >
SuMoTuWeThFrSa
     1 2 3
4 5 6 7 8 910
11121314151617
18192021222324
25262728293031

Sat, 03 Mar 2007 17:45:00 IST

Snort DCE/RPC Preprocessor buffer overflow

Wrote an exploit after a long time.. nothing interesting, but a simple stack overflow but initially proved to be a bit hard to trigger.

Started by taking a diff of snort-2.6.1.2 and snort-2.6.1.3 which instantly revealed the vulnerable code.

diff -Naur snort-2.6.1.2/src/dynamic-preprocessors/dcerpc/smb_andx_decode.c
snort-2.6.1.3/src/dynamic-preprocessors/dcerpc/smb_andx_decode.c
--- snort-2.6.1.2/src/dynamic-preprocessors/dcerpc/smb_andx_decode.c
2006-12-05 00:08:36.000000000 +0530
+++ snort-2.6.1.3/src/dynamic-preprocessors/dcerpc/smb_andx_decode.c
2007-02-17 13:00:11.000000000 +0530
@@ -31,6 +31,7 @@
#include 

#include "debug.h"
+#include "bounds.h"

#include "snort_dcerpc.h"
#include "smb_structs.h"
@@ -61,39 +62,80 @@
 static void ReassembleSMBWriteX(SMB_WRITEX_REQ *writeX, u_int8_t *smb_data)
 {
     SMB_WRITEX_REQ temp_writeX;
-    unsigned int   smb_hdr_len = (u_int8_t *)writeX - _dcerpc_pkt->payload;
-    unsigned int   writeX_len = smb_data - (u_int8_t *)writeX;
+    u_int16_t      smb_hdr_len = sizeof(SMB_HDR) + sizeof(NBT_HDR);
+    u_int16_t      writeX_len = (u_int16_t)(smb_data - (u_int8_t *)writeX);
+    u_int32_t      check_len;
+    int            ret;
+
+    check_len = (u_int32_t)smb_hdr_len + (u_int32_t)writeX_len +
(u_int32_t)_dcerpc->write_andx_buf_len;

.
.
.
/* Mock up header */
-    memcpy(&temp_writeX, writeX, writeX_len);
+    memcpy(&temp_writeX, writeX, sizeof(SMB_WRITEX_REQ));
     temp_writeX.remaining = _dcerpc->write_andx_buf_len;
     temp_writeX.dataLength = _dcerpc->write_andx_buf_len;

After a bit of funtion call flow tracing and stuff.. got it right.
and oh, This helped a lot.

Thus, the following steps can reliably trigger the bug:
1. Send SMB TreeConnectAndX for \\X.X.X.X\IPC$
2. Send SMB NTCreateAndX
3. Send SMBWriteAndX + DCERPC Bind/Call with fraglength > payload (fragmented PDU)
4. Send SMBWriteAndX with a pretty large ( > 16 or so) padding containing ret and payload.
5. Bang! pwned.

For my testing purpose, I had nc listening on port 139 monitored by Snort 2.6.1.2 and the exploit connects to the port and blindly delivers the payloads.
In practical senario, however its better to use a single TCP packet with chained SMB headers triggering the bug with a single TCP packet as snort runs in pretty stateless mode and doesnt really checks weather the packet is a part of a valid TCP session.

In case anybody is interested:
Original advisory: http://www.iss.net/threats/257.html
PoC: http://eos-india.net/abhisek/codez/exploits/snort_dcerpc_pwn-v0.1.c

Users of vulnerable version of snort should try to upgrade to Snort 2.6.1.3 ASAP.

posted at: 17:45 | path: / | permanent link to this entry

Made with PyBlosxom