首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>漏洞检测>文章内容
采众家之长分析及改进Cmail漏洞
来源:黑客防线 作者:LoveMelody 发布时间:2009-02-17  

来源:黑客防线
作者:LoveMelody

看了ISNO大虾的《我是如何发现CCProxy漏洞的》,心里痒痒的,也想按照ISNO大虾介绍的方法,依葫芦画瓢的分析分析一个漏洞。分析什么漏洞呢?F.Zh在《菜鸟版exploit编写指南》的开山之作中,详细讲解了Cmail Server漏洞的利用过程,让我这样的菜鸟受益匪浅,以后屡用其法。但F.Zh在文章的最后,留下了一句话:“定位,如果是固定长度的话,确实可以通过两次溢出定位,但实际上这个是和安装的路径有关的,还有没有好一点的方法来定位呢?”

什么意思我不大明白,F.Zh也没有再说下去,那我们就尝试分析Cmail Server吧,看看为什么覆盖那么长的字符串正好实现溢出;也看看能不能解决F.Zh说的不定长问题;当然,更重要的,是复习总结下ISNO和F.Zh介绍的方法,并改进改进,让它更适合我们菜鸟使用。

分析

安装好一个CmailServer 4.00beta1,应该有漏洞吧,如图1所示。

 

1.jpg
大小: 37.92 K
尺寸: 500 x 359
浏览: 0 次
点击打开新窗口浏览全图
图1

 

验证一下,进入DOS控制台,在窗口下输入Telnet 127.0.0.1 110,其中110是POP3协议所用端口,然后输入USER和一长串的a,接着回车。如图2所示。

 

2.jpg
大小: 12.42 K
尺寸: 500 x 343
浏览: 0 次
点击打开新窗口浏览全图
图2

 

弹出出错对话框了。XP下的出错对话框和2000不同,没有直接给出报错点,如图3所示。

 

3.jpg
大小: 20.67 K
尺寸: 419 x 229
浏览: 0 次
点击打开新窗口浏览全图
图3

 

怎么办?我们不能看到执行的地址了吗?不,还是有办法的。点击对话框中蓝色的字 “请单击此处”,系统就会给出详细的出错报告数据了。Offset:61616161,表示执行0x61616161这个地址时出现了错误。0x61就是小写的a,就是我们输入的USER中的数据,因为0x61616161地址非法,所以出错,这下XP下的定位和2000一样方便了。如图4所示。

 

4.jpg
大小: 41.79 K
尺寸: 500 x 309
浏览: 0 次
点击打开新窗口浏览全图
图4

 

好了,到了使用ISNO方法分析漏洞的时候了。重新启动Cmail,打开SoftICE,然后再发送超长的字符串。这下SoftICE捕获异常,弹了出来,停留在这句。

001B :61616161 FFFF INVALID

意思是61616161指向的指令非法。再看看上下左右相关的数据吧,输入Data命令,会出现一个数据窗口,然后输入d EIP,就会在数据窗口中显示出如下的值。

001B : 61616161?? ?? ?? ?? ?? ??

001B : 61616171?? ?? ?? ?? ?? ??

上下左右的数据都是非法的,因为没有代码加载在这个部分,所以系统默认填充1,就是全F。原EIP和堆栈,都已经被我们过长的数据覆盖,现在无法从现今的堆栈中,找到问题代码的位置。

小知识:SoftICE默认情况下,是开了异常捕获功能的,即有什么异常发生时,会自动激活SoftICE,我们可以使用指令Fault on和Fault off来打开或关闭异常捕获功能。

使用ISNO的方法,记下这个时候ESP的值,ESP = 02AE841C,即某个函数在02AE841C附近保存了返回地址,而在函数执行的过程中,保存的返回地址被我们超长字符串覆盖,从而返回时去执行非法的0x61616161。现在的关键就是找到这个在02AE841C附近保存地址的函数。

退出SoftICE,重新启动Cmail,CTRL+D呼出SoftICE,输入Addr CmailServer进入Cmail程序的地址空间,然后下一个ISNO介绍的经典断点:bpmw 02AE841C w。意思就是当往地址02AE841C进行写操作的时候,中断下来。如果一个函数,在地址02AE841C中保存返回地址,也是一个写操作,也会被中断,我们就可以找到是那个函数出现了字符串的覆盖。

回到程序空间,再运行攻击代码,果然有写操作时,SoftICE中断弹了出来。经过了几次中断,到达了下面这句指令。

00415A61:call 004049E0

此时ESP = 02AE841C,就是004049E0这个函数,把返回地址保存在02AE841C-4=02AE8418中。如果按F8执行,马上就会弹到001B:61616161 FFFF INVALID中去,而ESP会恢复成02AE841C,我们找到了被覆盖返回地址的函数004049E0!

ISNO大虾的方法就是好,按着方法一步步的做,就成功了,大家也试试吧。找到了出问题函数后,再用Ollydbg来看004049E0处的函数。

重新启动挂掉的Cmail,用Ollydbg附加上Cmail进程,然后Ctrl+G输入地址004049E0,就可以看到如下的代码,如图5所示。

 

5.jpg
大小: 28.49 K
尺寸: 500 x 302
浏览: 0 次
点击打开新窗口浏览全图
图5

 

直接看反汇编代码,头看裂了都看不出什么名堂来,还是动态执行,边走边看。在004049E0设一个断点,然后再运行我们的攻击程序。执行到004049E0 sub esp, 220h时,Ollydbg就会中断下来。按F8继续单步执行,在执行的时候注意查看每次调用的参数值。

00404A72 55 PUSH EBP

在内存窗口中CTRL+G然后输入EBP,发现EBP对应的是我们输入的aaaaaaaaaa……超长字符串!直觉感到马上水落石出了。下一句是:

00404A73 PUSH CMailSer.004F9640

004F9640地址是什么呢?在内存窗口中查看004F9640,是“F:\Study\课堂讲义\投稿\heifang\CMail漏洞分析”,晕,是我机器上Cmail的安装路径,早知道选个漂亮点的安装位置,免得象现在这样丢脸。算了,还是继续吧:

00404A7C PUSH CMailSer.00474498;

压入的00474498内容是“%s\mail\%s”,格式化串!看来就是作拷贝了。最后压入EAX,call一个字符串拷贝程序:

00404A81 50 PUSH EAX

00404A82 E8 18730200 CALL CMailSer.0042BD9F

明白了,调用这个函数,就大概相当于执行:

sprintf ( EAX,

"%s\mail\%s",

F:\Study\课堂讲义\投稿\heifang\CMail漏洞分析

aaaaaaaaaaaa……)

EAX中拷贝Cmail安装路径+\mail\+我们发送的USER名字,因为没有长度检查,所以导致了溢出!怪不说F.Zh说溢出点和安装路径有关,因为覆盖的字符串中,包含有Cmail的安装路径。

保存返回地址的ESP = 0x02AE8418;存放字符串的起始地址EAX = 02AE81F8,那么从EAX到ESP需要的字符串长度为:0x02AE8418-0x02AE81F8 = 0x220=544。其中安装路径“F:\Study\课堂讲义\投稿\heifang\CMail漏洞分析”是44个字节,还有“\mail\”是6个字节,那么需要覆盖a的长度为544 - 44 - 6 = 494字节!

函数执行完毕,保存地址的0x02AE8418果然被覆盖成了0x61616161,如下图6所示。

 

6.jpg
大小: 13.29 K
尺寸: 237 x 218
浏览: 0 次
点击打开新窗口浏览全图
图6

 

当函数要返回时,就会跳到执行0x61616161的地方中去,导致了异常。如图7所示。

 

10.jpg
大小: 41.78 K
尺寸: 500 x 309
浏览: 0 次
点击打开新窗口浏览全图
图7

 

验证

上面是通过直接分析,得到需要覆盖a的长度为494字节,但我们菜鸟心中没有底,还是使用熟悉的F.Zh黑盒法验证一下!我把F.Zh的定位方法改进了一下,分别定位百位,十位,个位,这样更容易定位比较长的溢出。利用Python写定位程序,首先定位百位:

import poplib

m = poplib.POP3('127.0.0.1')

s = 'a' * 100+'b' * 100+'c' * 100+'d' * 100+'e' * 100

m.user(s)

Python真是个写Exp和测试用的好东东,只要这几句话,就给Cmail服务器发送了100个a,100个b,100个c……的用户名,报错对话框如下图8所示:

 

7.jpg
大小: 41.79 K
尺寸: 500 x 309
浏览: 0 次
点击打开新窗口浏览全图
图8

 

65-61=4,所以百位是4,然后定位十位。因为知道百位是4,所以先发送400个a,发送10个a,10个b……程序如下。

import poplib

m = poplib.POP3('127.0.0.1')

s = 'a'*400+'a' * 10+'b' * 10+'c' * 10+'d' * 10+'e' * 10+'f' * 10+'g' * 10+'h' * 10+'i' * 10+'j' * 10

m.user(s)

这次报错对话框变为Offset:6a6a6a6a,如图9所示。

 

8.jpg
大小: 41.83 K
尺寸: 500 x 309
浏览: 0 次
点击打开新窗口浏览全图
图9

 

6a-61=9,所以十位为9,最后定位个位,490个a,然后是“abcdefghij”,程序如下:

import poplib

m = poplib.POP3('127.0.0.1')

s = 'a'*490+'abcdefghij'

m.user(s)

得到68676665处不能执行,如图10所示。

 

9.jpg
大小: 41.78 K
尺寸: 500 x 309
浏览: 0 次
点击打开新窗口浏览全图
图10

 

那么个位是65-61 = 4,400+90+4=494,果然和直接算出来的一样,494字节!爽!现在不仅知其然,而且还知其所以然了。

解决不定长路径思路

因为Cmail会把大写字母变成小写字母,所以用F.Zh文章里的方法,覆盖494个a,然后是JMP ESP的地址,最后附上只有小写字母的Search代码和ShellCode,就可以完成利用了!但还有个问题,就是覆盖494字节的a,是在安装路径为“F:\Study\课堂讲义\投稿\heifang\CMail漏洞分析”时,即44个字节的情况下造成的。如果别人的安装路径不是44个字节,比如43个字节,那么就不会导致溢出;如果是45个字节,覆盖的返回点没有对正,就会导致Cmail挂掉而不能利用成功,而我们写Exp,就是想成功攻击别人的机器。如果只能攻击自己的机子,怎么也说不过去吧?

怎么办呢?想来想去有几个办法:

第一:不管长度为多少,想法让JMP ESP的地址对正返回溢出点;

第二:想办法知道对方的安装路径,精确计算出覆盖长度;

第三:如果字符串较短,虽然不会成功,但不会有挂掉的问题,就可以再次攻击。所以可以一个字节一个字节的增加字符串,直到成功为止。

第一种方法比较困难,因为在Cmail中不存在对其机制,一个字节的偏差都会导致失败。但对一些如果有8字节,16字节对其的服务中,可以考虑用JMP ESP地址+JMP08指令进行大片连续覆盖,这样只需要一个覆盖成功,就可以跳入到最后的ShellCode中。

第二种方法在ISNO的CCProxy漏洞利用中使用过,但CCProxy的变长字符串是本方的公网IP地址,所以我们可以准确的知道长度;而Cmail中对方的安装路径,好像还不容易探测到,可以考虑使用社会工程学,先挂掉对方的Cmail,然后去给他好心的说:“独哥啊,你的Cmail挂了,可能和安装目录有问题哦,是在那个目录下啊?”等亲爱的WTF/独行者大哥说出来路径并重启Cmail后……嘿嘿!

第三种方法看来最可行,假设路径的长度最大是128,那就从544-128-6=410个a开始覆盖。如果不成功,对方的Cmail也还会工作,就加长一个字节,即411个a攻击,再412个a攻击,直到成功为止。

其实在Webdav漏洞中,也有一个安装路径的问题,解决的办法也是这样,从小到大一个一个的试,不过Webdav只有4种可利用长度,所以测试的过程少的多,Cmail就比较麻烦了。你还有更好的办法吗?欢迎指教!


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·MS07-014调试手记
·udp_sendmsg空指针漏洞分析
·一段对perl 木马的分析
·小心我“DIR”溢出你!
·CVE-2010-4258漏洞分析
·Adobe Reader 'CoolType.dll' TT
·PHPBB<+2.0.10 漏洞说明
·袁哥写的漏洞研究方法总结
·利用异常处理执行shellcode实例
·注入点检测新方法
·Apache mod_ssl buffer over分析
·RPC漏洞的通用分析方法
  相关文章
·读新术-基于开源代码更新的漏洞
·一个CGI程序的漏洞挖掘
·intval()使用不当导致安全漏洞的
·preg_match(_all)的变量初始化问
·mb_ereg(i)_replace()代码注射漏
·小心我“DIR”溢出你!
·udp_sendmsg空指针漏洞分析
·RPC漏洞的通用分析方法
·Symantec 核心驱动 symtdi.sys
·Rav 核心驱动 memscan.sys 本地
·symtdi.sys本地权限提升漏洞
·对一款国家级内容过滤系统Dos安
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved