欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

通过Fuzzing找出浏览器的一些怪癖

来源:本站整理 作者:佚名 时间:2019-05-31 TAG: 我要投稿

在这篇文章中我将向你展示我如何通过Fuzzing找出Firefox浏览器的多个”怪癖”。一般来说,研究者Fuzzing的目的大多是找出引发内存损坏的行为,但我是个例外;我要找的是浏览器一些其他的有趣行为。例如某些字符可以引起标签发生异常(打开或闭合),或某些字符可以绕过JavaScript解析器作出某种行为。上述这些意外行为通常可以绕过安全策略和实现Javascript沙盒逃逸,从而有助于XSS攻击。
我想讨论的第一个Bug是关于如何通过其他的方式闭合HTML注释。如果你阅读过HTML规范,你应该知道可以使用-->或--!来闭合注释,但还有其他方法吗?这是一个好问题,很适合我们展开Fuzzing。我们只要准备一些代码就可以找出该问题的答案。
时间回到2008年,我在构造Shazzer用于对浏览器进行模糊测试,那时我被限制每页只能导入10000个攻击向量,但回到2019一切都更快了,我们可以一次性对更多目标进行模糊测试。同时也可以使用DOM来加速Fuzzing,因为我不用再把向量逐个加载到当前文档中。但需要注意这不是万能的,你得到的结果可能不完整,实际我发现DOM在属性(例如href)赋值中允许NULL字符,但HTML解析器不会解析。这里还有一些其他很酷的bug,但你不能轻信浏览器的结果,你需要深入研究HTML解析器的行为。尽管这种输出HTML的方法比使用服务端语言快得多,但在大多数情况下都不适用。
第一步已经完成——我们找出问题”有什么字符可以闭合HTML注释?”。为了找出答案我们要利用已知可闭合HTML注释的字符,然后fuzz那些我们目前不知道的字符。下一步则是使用工具开展Fuzz,这里我使用的是Hackvertor(也可以在本地web服务器搭建)。加载完Hackvertor,通常是向输入框中写入内容并使用特定标记做一些转换,对输出做某些操作后然后获取最终输出。但我们没有要转换的内容,因此我们直接导入内容到输出框中。点击输出框区域的按钮,创建数组存储字符,然后创建div元素开始测试HTML:
log = [];
div=document.createElement('div');
接下来我们要fuzz超过1000000个unicode字符(准确地说是0x10ffff)。所以先创建一个for循环:
for(i=0;i
然后再使用div元素,这里我测试的是!之后的位置,所以字符要注入到!后面。然后使用一个img元素来查看结果是否有效,如果这个元素为显性则代表HTML注释已闭合。我们已经准备好了一些有趣的字符!
div.innerHTML = '-->';
使用querySelector检查img是否存在,然后将字符添加到日志,然后关闭if语句和for循环,最后把结果会显示在左侧的输入框中:
if(div.querySelector('img')){
 log.push(i);
 }
}
input.value=log
这里有完整的代码,你只需在Firefox中打开URL,然后把内容放到输出框,点击“Execute JS”按钮开始字符fuzz。Fuzz完毕后你应该在输入框中可以看到数字,数字对应有效的字符代码。在撰写本文时Firefox(67版本)仍允许通过把换行字符-n和r-放到!后面来闭合注释。很快我就收到消息,告知该bug已修复。Fuzzing最后的阶段就是开始组装Payload,这很简单你只要用换行符替换字符代码,然后添加XSS Payload:
 -->
你可以再次使用Hackvertor来测试它是否有效,只需将上面的内容粘贴到输出框中,然后点击“Test HTML”引发弹窗。

这样我们就在Firefox HTML解析器里找到了一个很cool的bug。OK,让我们继续找下一个,一个新问题:“什么字符可以作为注释开头?”。我们现在的目标是通过HTML注释打破存在的HTML属性,而不是闭合HTML注释。我相信大家都知道可以把作为HTML注释的开头。OK,这里我会再次使用相同的代码,但会做一些小调整,我修改innerHTML的赋值,以检查注释的开头:
div.innerHTML = '+String.fromCodePoint(i)+'- >">';
所以我们把Fuzzing的字符放到第一个连字符后面,如果某个字符可以用作注释开头,那将注释掉div元素,从而突破title属性。这次点击“Excute JS”后,我们在Firefox上得到两个结果:“0 , 45”。由于连字符,45是存在的,而0代表NULL字符!这意味着Firefox会将视为注释开头。有点不可思议(我觉得浏览器服务商应该对产品做足够多的行为Fuzzing)。为完整这次测试,我们现在要创建攻击向量,将String.fromCodePoint函数替换为NULL字符,然后插入XSS Payload:
document.body.innerHTML = '!-x00- >div title="-->">div>';
让我们跳出HTML,转向JavaScript。我测试了大部分浏览器,Sorry,Mozilla的Firefox再次让我惊讶。我是从 @jinmo123的一篇推文获得灵感,他们使用一个很酷的ES6新特性来实现无括号调用函数,但结合Fuzzing来说我的问题是哪些字符可以放到in或者说instanceof运算符后面,我们仍需用到Hackvertor,遵循上面模版创建代码,但这次不需要DOM。我们先创建数组和for循环:
log = [];
for(i=0;i
然后我们将使用eval替换innerHTML进行Fuzzing。首先用一个try catch块来包围它,以捕获无效字符引发的异常。
try{
eval("/a/"+String.fromCodePoint(i)+"instanceof function(){}");
eval函数用来验证JavaScript是否有效,如果有效,程序将跳转到下一行,如果无效,它将抛出一个异常并且异常立马被捕获,然后Fuzz下一个字符。下面一行只记录成功字符,剩下的代码关闭try catch块和for循环,最后把结果反馈至输入框。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载