注入、XSS自动检测工具开发的设想
“XSS与SQL注入是否能被计算机通过自动化的手段较完整的检测出来?”
我为何这么吊?
很显然,我会纠结这个问题在于我企图依法偷懒。XSS和注入已经成为了老大难的问题,某些开发人员可能会使用参数化查询、服务器上主动防御工具或者直接开启了.Net的请求验证机制之类的内建功能,但是上面的方式除了参数化查询外没有从根本上截断入侵的源头,依旧有被绕过的可能。
已经不止一次地设想工作之后的某天,老大分配任务“XXXX,你把这个分站过一遍”。然后我瞥了一眼,然后默默地打开工具,然后输入地址,然后点击Fuck按钮,然后打开快播学习岛国某些老师的新一届*精神。正性致勃勃的时候,pia一声报告生成完毕,一切就这样被搞定。
为了实现这个伟大的梦想,响应某*书记的正确号召,我曾经做过很多前期工作,比如用过这些软件:
1、Acunetix Web Vulnerability Scanner
首先要说我对这工具评价一般,它大多数情况下会检查出“Server版本太低”、“报错信息泄露”之类的错误。对,我称呼它为“错误”。原因在于这里被找到的错误通常无法被直接利用到渗透当中,至多至多能被用于其它严重漏洞的辅助入侵工作上。更多情况下会获取到一些根本就不是问题的问题,你无法根据软件的反馈复现。它也能查到简单、直接、暴力的漏洞,只是标题所提到两种类型的命中率实在偏低。
2、IBM Security AppScan
蓝色巨人出品属不属于精品我不知道,通过官网试用了提供的测试版本之后,发现它的设置项目比较丰富。不过,使用起来的入门门槛比较高,这也可能是为了保证检测类型的全面性。同样的,AppScan也存在一定的误报率。
除这两个之外,一些类似于SQLMap、Havij的入侵工具只提供了啪啪啪的功能,几乎就没提供如何找到妹子啪啪啪的方法。你说这不急死人吗?
它真的这么吊?
也不知道从什么时候开始,哪个家伙带的头。一时间天朝大地上大量涌现例如x60网站安全检测、某度站长平台、X全狗、X全联盟之类的“在线检测”服务。
嘿,你别说,这玩意儿还真有用。
自从我注册其中一个站点并且添加了某站网站之后,我的邮箱就从来没闲过。一会儿有“重大威胁”、一下子又有黑页。呵呵呵呵,尼玛那是我写的过滤器报错消息好吗?!于是果断扔到垃圾邮件。
等到很久之后的某天我打开站点一看,妈蛋这回真的被挂黑页了。结果上网站一看,人家写的评分90分,一切正常。呵呵呵呵,MLGB。
其实说白了,所谓的在线检测实质上就是这些厂商自己开发的一套基于Web的软件,和上节提到的那俩家伙基本没啥区别。当然,命中率和准确率说不定更低就是了。
要想这么吊可能遇到的困难
扯淡内容到上面为止,要开发一个能通过URL自动检测XSS和注入的检测程序,思前想后遇到最大的困难就是“测试覆盖率”。
现存的检测工具依靠爬虫获取的URL,通过修改URL后访问获取返回内容来判定是否存在XSS或者注入的可能(GET方式)。对于POST和其它一部分GET方式,则通过扫描DOM树里FORM元素的方式进行重组和访问。稍微有些能力的,能执行页面中的JS,得到一个较完整的DOM树。
好了,问题来了。这些检测方式碰上现在已经被用得炉火纯青的Ajax,几乎就只有歇菜的命运。
我在写这篇文章之前,TX的安全响应中心刚好对这个vc=">做了点研究。TX研究的角度非常新颖,已经试图从XSS的根源“用户输入”着手开始维稳,建议大伙可以一看。
即使如TX的童鞋所言,Hook输入输出请求(比如抓包),仍然无法避免一个状况:有些请求的触发可能需要与用户或者服务器的多次交互。
这种情况在向导式情景中比较容易见到,进行下一步需要上一步收集的资料作为基础,例如常见的安装向导。甚至有些向导需要根据用户的输入反馈不同的信息,漏洞万一就藏在某一个分支之后呢?
出现这个问题的根源在于,机器无法理解人类的语言并参与互动,而Web2.0的思想正是双向的互动。
该“状况方程”也有唯一解,即代码语义分析。代码语义分析是解决一切漏洞的根本途径,在人工智能不能达到智力正常自然人之前是不能实现的。你不信啊,那咱们来试试。
比如下面这段PHP代码(代码中变量名禁止联想任何汉字的缩写,违法后果自负):
function fuckgfw($sbfbx,$sbgcd) { $dsbfbx = $sbfbx; $sbgcd = $sbgcd | $sbfbx; $sbfbx = $sbfbx & ~$sbgcd; return $dsbfbx | $sbgcd | $sbfbx; }
仔细想想,有什么意义吗???
。
我说不定可以告诉你,这根本就没有意义,只是我想骂人而已。计算机能知道这段代码的真实含义吗?不可能,因为他不知道我可能就是在骂人。哪怕我加上注释//*好*好*国家人民地位高它也还是不知道。可你真的能说它没有意义吗?也不能,我万一把他直接输出,叫访客手动计算并参与到一个Token的校验中怎么办?
所以我们必须返朴归真,从漏洞的根源入手——“用户输入”。
我其实可以这么吊
在我的设想中,这个检测工具应当遵循下面这个流程:
获取页面代码–>执行JS、建立DOM树–>分析INPUT元素,建立INPUTS表–>分析FORM元素,建立FORMS表–>获取所有元素的OnClick、OnSubmit事件,建立EVENTS表(到这步为止信息收集结束)
–>遍历EVENTS表中的所有事件,检查和标记事件中需要用到的INPUT/FORM元素、PROMPT函数,并将随机字符串填入其中再模拟执行–>Hook网络访问请求–>(有符合条件的请求)判断是否存在XSS或者注入问题/(无符合条件的请求或无网络请求)则可能出现多次交互,将其标记异常,写入报告提醒测试者该项目可能需要手工处理。(到这步为止Ajax和隐藏较深的JS请求判定结束)
–>遍历FORMS表,填入随机数据模拟提交–>根据返回结果判断是否存在XSS或者注入问题。(到这步为止,核心流程结束)
这个流程能有着非常大的测试覆盖率,不过也显然有下面的已知弊端:
1、对于加密状态的JS,无法通过JS代码检查PROMPT函数以及所用到的INPUT/FORM元素;
2、对于一些OnClick事件,实质上只是某一个“大事件”中的“子事件”,请求的生成实际上在“大事件”中或者只是干脆操作DOM而已,这里将会产生大量的误报;
3、对于拖动事件、Flash提交、弹窗、重定向(用于可信网址跳转)等情况,无法覆盖测试;
4、对于请求参数来自常量(在页面中就被定义)的情况,无法覆盖测试;
5、对于某些在发送Ajax请求之前对用户输入进行合法性验证(比如电子邮箱)的,会产生异常报告。
如此看来,这个自动化测试工具还有很多困难需要克服啊……
下一篇: 单播、多播(组播)和广播的区别