xss漏洞扫描器开发随想

前言

很喜欢xss的各种脑洞打开的利用方式,也想着能够实现自动挖掘xss,但是个人觉得像大多数漏洞扫描器那样用收集的大量的payload,采用暴力测试的那种手段不够聪明,后来也发现了一款宣称smarter的xss扫描器——xssstrike,也去认真读了下源代码,发现确实是一款很聪明的漏扫,在学习了它的源码过后,不动手自己也写一个总觉得会遗憾,于是就有了下面的构思

思路

想一想我们平时是怎么挖掘xss漏洞的?

  1. 查找输入点
  2. 哪些输入点会有输出
  3. 输入一些特殊字符以此判断哪些字符被过滤
  4. 知道过滤规则过后开始考虑编写能够绕过过滤的payload
  5. 根据页面是否弹窗等信息判断是否存在xss

上面的流程应该算是一个比较粗略地挖掘流程吧,现在我们要做的就是把这个流程自动化,当然,计算机是很笨的,有些人可以一眼就识别出来的特征机器需要我们告诉它一步步怎么做,这也就是难点所在了。

确定输入

扫描器的目的就是提高我们的挖掘效率,重复性的工作都可以丢给他做,如果手工测试每个参数是否存在xss漏洞,我们就需要多次重复上面的步骤,所以我们可以做一个扫描器一次只判断一个参数或几个参数是否存在xss(我们只需要提供url和指定需要测试的参数),或者做一个可以挖掘整个站点xss漏洞的扫描器(利用爬虫爬取整个网站的表单以及url,依次测试)

指定参数这种测试方式倒是挺简单的,整站测试稍微要复杂一点,需要做一个爬虫爬取链接并进行数据清洗,去掉外链等

确定输出

确定输出也挺简单的,就是利用requests库,参数赋值为特定的字符串,然后获取到响应,并在响应中利用正则匹配那个字符串,如果匹配成功,那么我们就找到输出点了。

但是上面仅仅是确定哪些参数能够输出在页面上,并没有进一步确认输出点到底在哪里,例如输出在标签中?输出在属性中?这些也是一个聪明的扫描器需要得到的信息,毕竟后续生成payload需参考这些信息来实现定制化。好的,我们想一下手工测试的时候我们会怎么做,根据经验,我们通常把输入分为:

  1. 标签之间
  2. 作为html属性值
  3. script标签之间
  4. 注释中

一般来说,如果输出在标签之间的话利用就不会那么麻烦,但是需要注意输出是否是在textarea noscript title noframes iframe xmp plaintext这些特殊标签内,这些标签会对输出在它们之间的内容进行htmlencode。

作为属性值,需要判断是哪些属性,是不是on开头的属性(onclick,onfocus),是不是src,href等,这些属性是有不同的利用方式的,如果排除掉上面几种可能,就需要再判断属性值是否被引号(双引号、单引号)包裹

在script标签的话,情况是很复杂的,输出可能作为一个变量值,可能是函数的某个形参,可能是函数名,可能是局部变量。这种情况是很难确定是否有漏洞存在的…

如果输出在html注释中,我们需要做的就是逃逸注释

waf探测

waf探测到底该放在什么时候进行,读者自己把控。在渗透测试中,waf是一个挺让人头痛的存在,恶意请求、http请求频率过高都可能导致ip被ban掉,所以我们需要探测一下waf是否存在以此来决定下一步的动作。原理倒也很简单,用一个恶意请求去触发waf,然后进行特征匹配

过滤检查

即使没有waf,稍微有点安全意识的开发人员都会对用户输入的特殊字符进行过滤,所以在进行payload构造之前,我们需要确定哪些字符我们可以使用,否则可能生成的payload大部分不能使用,岂不是很亏?而xsstrike中检查过滤的原理是用我们需要检测的特殊字符拼接上特定字符串,然后请求发过去,最后在响应中寻找拼接了特殊字符串的字符,但是xsstrike中的做法更加有意思。

生成payload

终于来到了重头戏,生成payload是与前面两个模块息息相关的,也可以说前面的确定输出以及过滤检查模块都是在为生成payload收集信息,例如,我要定制一个输出在属性中的payload,那么我首先要看我可以实用哪些特殊字符,其次我就要看这个属性名是什么,属性值是否被引号包裹,如果属性名是src,或许我可以生成一个payload像这样:

javascript:alert(1);

如果属性名为name,并且属性值被双引号包裹,那么我扫描器可能就需要生成一个像下面这样的payload:

" onmouseover=alert(1);

当然这种payload是很难成功的,因为太简单了,所有我们生成的payload要具有一定的混淆过滤器的能力,比如用一些特殊的不可打印的字符替代空格,大小写混合等等。

验证payload

验证payload,对于人来说可能就是看看浏览器是否弹窗之类的,但是对于机器来说可能就没那么轻松了,它还是需要去响应中去寻找我们的payload,如果我们的payload原模原样的出现在了响应中,那么基本可以确定漏洞确实存在了,就可以报告出来了


未完待续>>>

发布了116 篇原创文章 · 获赞 161 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/he_and/article/details/85009951