漏洞描述:

3月27日,在Windows 2003 R2上使用IIS 6.0 爆出了0Day漏洞(CVE-2017-7269),漏洞利用PoC开始流传,但糟糕的是这产品已经停止更新了。网上流传的poc下载链接如下。

github地址:https://github.com/edwardz246003/IIS_exploit

结合上面的POC,我们对漏洞的成因及利用过程进行了详细的分析。在分析过程中,对poc的exploit利用技巧感到惊叹,多次使用同一个漏洞函数触发,而同一个漏洞同一段漏洞利用代码却实现不同的目的,最终通过ROP方式绕过GS的保护,执行shellcode。

调试环境:

虚拟机中安装Windows Server 2003企业版,安装iss6.0后,设置允许WebDAV扩展。使用的调试器为:windbg:6.7.0005.1

远程代码执行效果如下:

由上图可到,漏洞利用成功后可以network services权限执行任意代码。

漏洞分析:

漏洞函数

漏洞位于ScStoragePathFromUrl函数中,通过代码可以看到,在函数尾部调用memcpy函数时,对于拷贝的目的地址来自于函数的参数,而函数的参数为上层函数的局部变量,保存在上层函数的栈空间中。在调用memcpy时,没有判断要拷贝的源字符长度,从而导致了栈溢出。

通过伪代码更容易看出:

漏洞利用:

在POC中,可以看到发送的header中包含两部分<>标签,这会使上面的每个循环体都会运行两次,为了下面的描述方便,我们对这两个header的标签部分分别定义为HEAD_A与HEAD_B。

漏洞利用流程:

  1. 在HrCheckIfHeader函数中,通过使用HEAD_A溢出,使用HEAD_B被分配到堆空间地址中。

  2. 在HrGetLockIdForPath函数中,再次通过使用HEAD_A溢出,使HEAD_B所在的堆地址赋值给局部对象的虚表指针,在该对象在调用函数时,控制EIP。

  1. 最终调用IEcb类的对象偏移0x24处的函数指针,控制EIP

漏洞利用主要在于HrCheckIfHeader函数与函数HrGetLockIdForPath中。

函数HrCheckIfHeader主要功能是对用户传递来的Header头进行有效性的判定。在函数中HrCheckIfHeader通过了while循环来遍历用户输入的Header头中的数据。

HrGetLockIdForPath主要功能是对传递来的路径信息进行加锁操作。在HrGetLockIdForPath函数中,也是通过while循环来遍历路径信息,同样也对应着两次调用漏洞函数。

调试过程:

两次溢出控制EIP

对这4个调用漏洞函数的地方分别下断:

bp httpext!CParseLockTokenHeader::HrGetLockIdForPath+0x114 ".echo HrGetLockIdForPath_FIRST";
bp httpext!CParseLockTokenHeader::HrGetLockIdForPath+0x14f ".echo HrGetLockIdForPath_SECOND";
bp httpext!HrCheckIfHeader+0x11f ".echo HrCheckIfHeader_FIRST";
bp httpext!HrCheckIfHeader+0x159 ".echo HrCheckIfHeader_SECOND";

调试程序,共会断下6次,我们对这6次断点处漏洞函数在利用时的功能进行归纳:

第一次:

暂停在HrCheckIfHeader _FIRST,对漏洞利用没有影响

第二次:

断在HrCheckIfHeader _SECOND,此处调用漏洞函数的目的是为了使用HEAD_A标签,来溢出漏洞函数,目的是使用HEAD_A标签中的堆地址覆盖栈中的地址,此堆地址会在随后使用。

运行漏洞函数前,

运行过漏洞函数后,可以看到栈空间中的0108f90c位置处的内容已经被覆盖成了680312c0,680312c0正是一个堆中的地址。

第三次:

暂停在HrCheckIfHeader_FIRST,此时漏洞函数的作用是,将HEAD_B标签拷贝到上面的堆地址中。本来正常的程序在这里会将用户传递进来的HEADER拷贝到栈空间中,但在上面因为溢出,将HEAD_B标签拷贝到了堆中。可以看到使用的堆地址680312c0。

第四次:

暂停到HrCheckIfHeader_FIRST,对漏洞利用没有影响

第五次:

HrCheckIfHeader_SECOND,此处调用漏洞函数的目的是为了使用HEAD_A标签,来溢出漏洞函数,目的是使用HEAD_A标签中的堆地址覆盖栈中的地址,此堆地址会在随后使用。溢出AAA  db ebp-14 将栈中的地址改成了与堆中的地址 680312c0,在这里ebp-14的地址也被覆盖,这个地址在下面第六次的溢出时,会赋值给对象指针,在这里就控制了ebp_14的值,也就可以控制下一步中的对象指针。

第六次:

HrCheckIfHeader_FIRST在这个函数下面的子子函数中会调用虚函数,从而控制EIP。

总结一下,在上面六次调用处,需要关注的利用过程是:

1) 第二次与第三次处是必须的,因为没有第二次处的利用,就不会有第三次处的把HEAD_B拷贝到堆中。没有堆中的地址在第六次调用时就没法控制虚表指针。所以没有第二次的溢出调用,就不会有堆中的HEAD_B内存。(本来HEAD_B的归宿是栈空间,就是因为溢出了才把HEAD_B放到了堆空间中)

2) 第五次再次把栈溢出,把堆的地址写到了局部变量中,才导致第六次能成功调用虚函数。因为第六次调用虚函数时,是调用的局部变量的虚函数。如果没有第五次断点处的溢出,就无法把堆中地址成功的写入到局部变量的虚函数中,也就无法控制虚函数指针。

由此可以看出,两次对漏洞函数溢出操作,其中一次溢出操作(第二次断点处)将栈地址改写为堆地址,保证了HEAD_B被写入到堆中,另外一次溢出操作(第五次断点处)将局部变量对象的指针指向堆。两次溢出代码相同,实现的目的却不同,双剑合壁,鬼斧神工,巧妙结合实现对EIP的控制。

ROP

控制EIP后,使用ROP技术绕过GS的保护。

使用SharedUserData的方法执行自定义的函数

来到shellcode处:

Shellcode进行一次循环解码:

解码完成后,就是长得比较漂亮的shellcode了

缓解方案:

l 禁用 IIS 的 WebDAV 服务

l 使用 WAF相关防护设备

l 建议用户升级到最新系统 Windows Server 2016。

总结

通过分析可以看到,漏洞原理只是因为没有对拷贝函数的长度做判断,而导致了栈溢出。这也提醒广大程序员们,慎用不安全的内存操作函数,在编译代码时开启所有保护。从漏洞利用角度分析,对于栈溢出,喜闻乐见的利用手法为修改返回地址,覆盖虚表指针等方法,但这种利用栈溢出把指针引向堆空间中,在需要的时候,再通过溢出将堆空间中的地址引回到栈空间中的利用手法确实也是标新立异、与众不同,同一个漏洞代码处使用多次溢出最终实现exploit,即使在分析完成后也对利用手法回味悠长。

CVE-2017-7269—IIS 6.0 WebDAV远程代码执行漏洞分析的更多相关文章

  1. thinkphp5.0.22远程代码执行漏洞分析及复现

    虽然网上已经有几篇公开的漏洞分析文章,但都是针对5.1版本的,而且看起来都比较抽象:我没有深入分析5.1版本,但看了下网上分析5.1版本漏洞的文章,发现虽然POC都是一样的,但它们的漏洞触发原因是不同 ...

  2. IIS 6.0曝远程代码执行漏洞CVE-2017-7269

    一.漏洞说明 漏洞编号:CVE2017-7269 影响中间件:IIS6.0 影响服务器版本:windows 2003 R2 二. 环境搭建 虚拟机kali : 192.168.1.2 靶机window ...

  3. Tomcat/7.0.81 远程代码执行漏洞复现

    Tomcat/7.0.81 远程代码执行漏洞复现 参考链接: http://www.freebuf.com/vuls/150203.html 漏洞描述: CVE-2017-12617 Apache T ...

  4. [转帖]Windows DHCPServer远程代码执行漏洞分析(CVE-2019-0626)

    Windows DHCPServer远程代码执行漏洞分析(CVE-2019-0626) ADLab2019-03-15共23605人围观 ,发现 4 个不明物体安全报告漏洞 https://www.f ...

  5. Spring框架的反序列化远程代码执行漏洞分析(转)

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  6. CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析

    Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器.         Microsoft Internet Explorer 6至9版本中存在漏 ...

  7. CVE-2012-0003 Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞 分析

    [CNNVD]Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞(CNNVD-201201-110)    Microsoft Wi ...

  8. Nexus Repository Manager 3(CVE-2019-7238) 远程代码执行漏洞分析和复现

    0x00 漏洞背景 Nexus Repository Manager 3是一款软件仓库,可以用来存储和分发Maven,NuGET等软件源仓库.其3.14.0及之前版本中,存在一处基于OrientDB自 ...

  9. CVE-2018-7600 Drupal核心远程代码执行漏洞分析

    0x01 漏洞介绍 Drupal是一个开源内容管理系统(CMS),全球超过100万个网站(包括政府,电子零售,企业组织,金融机构等)使用.两周前,Drupal安全团队披露了一个非常关键的漏洞,编号CV ...

随机推荐

  1. CodeForces - 1004C

    Since Sonya is interested in robotics too, she decided to construct robots that will read and recogn ...

  2. 【洛谷 P3705】 [SDOI2017]新生舞会(费用流,01分数规划)

    题目链接 看到这题我想到了以前做过的一题,名字记不清了,反正里面有"矩阵"二字,然后是道二分图匹配的题. 经典的行列连边网络流. 第\(i\)行和第\(j\)列连边,费用为\(b[ ...

  3. HDU 2319 Card Trick (模拟)

    题目链接 Problem Description The magician shuffles a small pack of cards, holds it face down and perform ...

  4. Django之Form组件验证

    今天来谈谈Django的Form组件操作 Django中的Form一般有两种功能: ·输入html ·验证用户输入 Form验证流程 ·定义规则(是一个类)    ·前端把数据提交过来 ·匹配规则 · ...

  5. Django中的MiddleWare中间件

    1. middleware简介 Django的middleware的概念相当于SSH框架里面的filter的概念.中间键的作用就是对所有的request,在request前,和在response后做一 ...

  6. Unity MMO 参考数值

    贴图格式: iOS :RGBA 32 (pvrtc 4 ) Android : RGB Compresed ETC 4 或 RGBA 32  . DrawCall: 总计Drawcall 平均 100 ...

  7. c++动态规划dp算法题

    问题1:找硬币,换钱的方法 输入: penny数组代表所有货币的面值,正数不重复 aim小于等于1000,代表要找的钱 输出:换钱的方法总数 解法1:经典dp,空间复杂度O(n*aim) class ...

  8. javaScript-继承2种方式

    1.组合继承 组合继承带来的问题很明细就是父类的构造函数会调用两次,如: function Person(name, age, sex) { this.name = name; this.age = ...

  9. Xcode及模拟器SDK下载

    http://blog.csdn.net/zhangao0086/article/details/38491271 吐槽下,百度打着无限分享的旗号,却又让分享资源过期,让分享者持续维护 如果你嫌在Ap ...

  10. 洛谷P1876开灯 题解

    题目传送门 这道题目是道数学题(下面也写了),所以仔细研究发现:N轮之后,只有是小于N的完全平方数的灯能亮着.所以接下来就好办了: #include<bits/stdc++.h> usin ...