Web安全 — XSS漏洞自动化验证

摘要

Win32 API即为Microsoft 32位平台(包括:Windows 9x, Windows NT3.1/4.0/5.0, WindowsCE等)的应用程序编程接口(Application Programming Interface),是构筑所有32位Windows平台的基石,所有在Win32平台上运行的应用程序都可以调用这些函数。

Win32 API简介

Win32 API即为Microsoft 32位平台(包括:Windows 9x, Windows NT3.1/4.0/5.0, WindowsCE等)的应用程序编程接口(Application Programming Interface),是构筑所有32位Windows平台的基石,所有在Win32平台上运行的应用程序都可以调用这些函数。

使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。

在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。

标准Win32 API函数可以分为以下几类:

  • 窗口管理
  • 窗口通用控制
  • Shell特性
  • 图形设备接口
  • 系统服务
  • 国际特性
  • 网络服务
    win32api可参考 https://msdn.microsoft.com/en-us/library/windows/desktop/ff818516(v=vs.85).aspx .aspx)

    Pywin32

    安装Pywin32

    由于本次操作是使用python来操作Win32api,需要先安装Pywin32,可以从这里下载对应的Python和Windows版本文件,下载完后直接运行安装就可以了。

    安装文件: https://sourceforge.net/projects/pywin32/files/

    截图思路

    截图操作的大致思路如下:

  • 模拟按下键盘上的“win + PrtSc”组合键
  • 从剪贴板读取缓存的截图
  • 将截图文件保存在本地

    模拟按键

    使用的是win32api中的 keydb_event 函数,相关详细信息可以参考 https://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx .aspx)

    键位码可以参考 https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx .aspx)

    win32api.keybd_event(0x91, 0, 0, 0)     # 0x91 --> win key win32api.keybd_event(0x2C, 0, 0, 0)     # 0x2C --> PRINT SCREEN key win32api.keybd_event(0x91, 0, win32con.KEYEVENTF_KEYUP, 0) win32api.keybd_event(0x2C, 0, win32con.KEYEVENTF_KEYUP, 0)

    PrtSc相关知识

    当按下“win + PrtSc”组合键后,截图被保存在剪贴板中,可以直接在word或者是附件中的画图程序里粘贴后使用,使用剪贴板查看器可以查看剪贴板的内容。

    剪贴板在Windows 7/8/10 中是没有的,可以在网上搜索下载一个,一般为clipbrd.exe。

    Web安全 — XSS漏洞自动化验证

    自己操作下就会发现,剪贴板只能存储最近复制的内容,新内容会替换旧内容(不区分图片或文字),QQ截图使用的也是系统剪贴板。

    从剪贴板查看器的查看选项可以看到,这里有两种图片格式:位图和DIB位图。

    Web安全 — XSS漏洞自动化验证

从剪贴板中读取截图

win32api中有一个模块 win32clipboard 是负责剪贴板相关的操作。相关详细信息可以参考 https://msdn.microsoft.com/zh-cn/library/windows/desktop/ff468802(v=vs.85).aspx .aspx)

win32clipboard.IsClipboardFormatAvailable(formats) 确定剪贴板是否包含指定格式的数据。

win32clipboard.GetClipboardData(formats) 可以从剪贴板里读取数据。

需要指定数据的格式 formats ,有关标准剪贴板格式的说明,请参阅标准剪贴板格式 https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms649013(v=vs.85).aspx#_win32_Standard_Clipboard_Formats .aspx#_win32_Standard_Clipboard_Formats)

此处选用 CF_DIBCF_DIB 返回一个内存对象,包含BIT格式图片的信息。相关详细信息可以参考 https://msdn.microsoft.com/zh-cn/library/windows/desktop/ff729168(v=vs.85).aspx .aspx)

win32clipboard.OpenClipboard() if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_DIB):   data = win32clipboard.GetClipboardData(win32clipboard.CF_DIB)

BMP简介

BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。

典型的BMP图像文件由四部分组成:

  • 位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;
  • 位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
  • 调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
  • 位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
    详细内容可查看 https://baike.baidu.com/item/BMP/35116?fr=aladdin

    构建结构体

    BMP文件头结构体

    详细内容可参考 https://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx .aspx)

    class BITMAPFILEHEADER(Structure):   _pack_   = 1   _fields_ = [       ('bfType', WORD),       ('bfSize', DWORD),       ('bfReserved1', WORD),       ('bfReserved2', WORD),       ('bfOffBits', DWORD),       ]

    位图信息头结构体

    详细内容可参考 https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx .aspx)

    class BITMAPINFOHEADER(Structure):   _pack_   = 1   _fields_ = [       ('biSize', DWORD),       ('biWidth', LONG),       ('biHeight', LONG),       ('biPLanes', WORD),       ('biBitCount', WORD),       ('biCompression', DWORD),       ('biSizeImage', DWORD),       ('biXpelsPerMeter', LONG),       ('biYpelsPerMeter', LONG),       ('biClrUsed', DWORD),       ('biClrImportant', DWORD),       ]

    用sizeof获取二者的大小并赋值给 SIZEOF_BITMAPFILEHEADERSIZEOF_BITMAPINFOHEADER

    拷贝截图数据

    从内存中拷贝出BMP数据用到的是ctypes中的 memmove 函数。详细内容可查看 https://docs.python.org/2/library/ctypes.html?highlight=memmove#ctypes.memmove

    同时,新建一块区域,全部用0来填充,用到的是ctypes中的 memset 函数。详细内容可查看 https://docs.python.org/2/library/ctypes.html?highlight=memmove#ctypes.memset

    “`python

    BitMapInfoHeaderHandle = BITMAPINFOHEADER()

    memmove(pointer(BitMapInfoHeaderHandle), data, SIZEOF_BITMAPINFOHEADER)

  • BitMapFileHeaderHandle = BITMAPFILEHEADER()

    memset(pointer(BitMapFileHeaderHandle), 0, SIZEOF_BITMAPFILEHEADER)

    #### 写文件头 构建文件头的详细内容可参考[https://baike.baidu.com/item/BMP/35116?fr=aladdin](https://baike.baidu.com/item/BMP/35116?fr=aladdin) ```python BitMapFileHeaderHandle.bfType = ord('B') | (ord('M') << 8) BitMapFileHeaderHandle.bfSize = SIZEOF_BITMAPFILEHEADER + len(data) SIZEOF_COLORTABLE = 0 BitMapFileHeaderHandle.bfOffBits = SIZEOF_BITMAPFILEHEADER + SIZEOF_BITMAPINFOHEADER + SIZEOF_COLORTABLE

    生成图片

    以二进制方式,先写文件头,再写从剪贴板获取到的字符串到本地的.bmp文件中,完成图片生成。

    with open(filename, 'wb') as bmp_file:     bmp_file.write(BitMapFileHeaderHandle)     bmp_file.write(data) print 'file "{}" created from clipboard image'.format(filename)

    XSS简介

    XSS是一个非常常见的Web漏洞,各大互联网公司对XSS的重视程度差别很大,有的作为高危,有的最多当中危甚至当低危,原因无非是这两方面:一方面是XSS虽然数量过多但是利用时需要很多前置条件,不容易成功利用;另一方面一但被成功利用危害又较大,会造成盗取帐号、控制数据、盗窃资料、网站挂马等危害。

    XSS漏洞检测

    绝大多数Web漏洞扫描器都可以检测出某一网站是否存在XSS漏洞,网上也能找到很多专用的XSS检测工具,具体的原理及检测过程不再赘述。有兴趣可查看极客学院的课程 《XSS检测与防御》

    XSS自动化验证

    验证的前提是已经确认某页面存在XSS漏洞,并有成功触发的POC(Web漏洞扫描器都会返回吧?)。

    验证的思路如下:

    • 判断该POC的发送方式:GET和POST
    • 若为GET,直接发送即可触发
    • 若为POST,拆分POC,本地构造输入框,提交POST请求
    • 触发后自动截图

      判断发送方式

      此处使用的是某厂商的Web漏扫,很人性化的提示当前使用的POC是用那种方式提交,不用自己进行判断,其他情况后续再做补充。

      GET:

      Web安全 — XSS漏洞自动化验证

      POST:

      Web安全 — XSS漏洞自动化验证

    浏览器操作

    既然是漏洞验证,得提供充足的证据来证明该漏洞确实是存在的。对于XSS来讲,截取浏览器界面,证明POC触发成功是一个强有力的证据,所谓“无图无真相”嘛。此处就得操作浏览器了。

    浏览器操作选用selenium + Firefox。

    安装selenium

    代码是用python写的,所以基础环境为 Windows 10 + python 2.7。

    安装selenium只需要一条命令:

    pip install selenium

    下载Firefox driver

    selenium需要驱动程序与你所选的浏览器进行连接。Firefox需要安装geckodriver才能正常运行,同时,确保它在你的PATH环境中。

    下载地址: geckodriver

    其他受支持的浏览器也有自己的驱动程序可用。一些更受欢迎的浏览器的驱动程序下载链接如下:

    Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads

    Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

    Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/

    selenium简单操作

    简单说下selenium的操作,编写代码,让浏览器依次执行以下指令:

  • 打开一个新的Firefox浏览器
  • 加载百度主页
  • 等待一段时间
  • 关闭浏览器

    代码如下:

    “`from selenium import webdriver

    driver = webdriver.Firefox()

    driver.get(‘ https://www.baidu.com ‘)

    driver.implicitly_wait(10)

    driver.quit()

    #### 漏洞验证 如果漏洞POC触发方式为`GET`时,在上面代码的基础上稍作修改,增加窗口最大化以及截图功能即可实现。 关键代码如下:

    ……

    maxWidth = driver.execute_script(“return window.screen.availWidth;”)

    maxHeight = driver.execute_script(“return window.screen.availHeight;”)

    driver.set_window_size(maxWidth, maxHeight)

    ……

    if driver.switch_to_alert():

    printScreen.printScreen(‘crackme2.bmp’)

    ……

    `  有关自动截图部分的内容请看[Python调用Win32 API实现截图]()  因为selenium操作浏览器时,不支持直接发送POST请求,如果触发方式为

    POST`时,则需要先构造表单,用浏览器模拟点击操作来发送POST请求。

    表单构造

    从Web漏扫获取到的风险点中,POST触发方式的链接多为如下形式:

    http://***.***.com:80/register/register.php?FirstName=135791&LastName=135791&Password=admin&DOB=135791&Address=135791&txtCity=135791&drpState=Alabama&TelephoneNo=13412312345&[email protected]&UserId=admin>'><ScRiPt/>window.a==1?1:pr**pt(a=1)</ScRiPt>

    构造表单的目的只是用来向服务器发送一个POST请求,所以,越简单越好。

  • 拆分获取到的url
    从Web漏扫获取存在XSS漏洞的风险点,首先拆分出使用的网络协议、域名、路径以及传递的参数。
    import urlparse url = "http://crackme.cenzic.com:80/kelev/register/register.php?FirstName=135791&LastName=135791&Password=admin&DOB=135791&Address=135791&txtCity=135791&drpState=Alabama&TelephoneNo=13412312345&<a href="/cdn-cgi/l/email-protection" data-cfemail="a7e2cac6cecb9ac6c3cacec9e7c6c3cacec989c4c8ca">[email protected]</a>&UserId=admin>'><ScRiPt>window.a==1?1:pr**pt(a=1)</ScRiPt>?qqdrsign=042c6" res = urlparse.urlparse(url) scheme = res[0] host = res[1] path = res[2] data_string = res[4]
  • 构造表单内容

    将传递的参数进一步拆分,还原成表单,生成html代码。

    form = '' s = data_string.split('&')  for i in range(0, len(s)):    p = s[i].split('=', 1)    inputName = p[0]    inputValue = p[1]    tr = '<tr><td align=right><b>' + inputName + ':</b></td><td><input type=text name="' + inputName + '" value="' + inputValue + '" size=80></td></tr>'    form = form + tr
  • 构造页面

    添加html代码,生成完整的 .html 文件,方便浏览器使用。

    <!DOCTYPE html> <html>   <head>       <meta http-equiv="content-type" content="text/html; charset=utf-8">       <title>WebApi</title>        <style>           body{ font-size:14px;  font-family:"Microsoft Yahei";background-color:#fff;}           td{table-layout: fixed; word-wrap:break-word;word-break:break-all;}       </style>   </head>   <body>       <table border=0 width='90%'>           <tr>               <td align=right style=width:120px;>                   <b>url(Action):</b>               </td>               <td>                   <a id=id_action target=_blank href="{{ url_base }}">{{ url_base }}</a>               </td>           </tr>            <form name=theForm action="{{ url }}" method=post>           {% csrf_token %}                {% autoescape off %}                   {{ form }}               {% endautoescape %}            <tr>               <td></td>               <td>                   <input onclick="theForm.action=document.getElementById('id_action').href;" id=id_input_action type=submit value=' 使用Action提交POST数据 '>               </td>           </tr>           </form>       </table>   </body> </html>

    效果图如下:

    Web安全 — XSS漏洞自动化验证

  • 发送POST请求

    XSS验证表单构造完毕后,下一步即为发送POST请求。在前文“selenium简单操作”部分的代码基础上,增加点击过程即可。

    首先,定位元素名为“id_input_action”的按钮,然后执行点击操作,紧接着判断是否有弹窗,最后截图保存到当前目录。代码如下:

    driver.find_element_by_id("id_input_action").click() time.sleep(3) if driver.switch_to_alert(): printScreen.printScreen('crackme2.bmp')

    生成报告

    此处为了简便,直接生成html报告,后期需要,也可转换成pdf等格式。

    构造报告模板

    此处为了简便,可以直接生成html报告,后期需要,也可转换成pdf等其他格式。

    构造方式可参考上文表单构造部分内容,只需要传入存在漏洞的链接以及存放图片的路径即可,也可按自己想法或需求,增加漏洞产生的原因、解决方案等内容。

    效果展示

    脚本运行后,先从扫描器结果中获取XSS漏洞的url(涉及到api请求与处理),分析当前url触发方式,选用不同的提交方式去触发,最后截图保存(也可以直接写入word文件中)。

    Web安全 — XSS漏洞自动化验证