XSS Hunting
本文记录了我从漏洞赏金项目中的一个发现。该项目范围内有大约20个Web应用程序。
幸运的是,我选择的第一个应用程序是一个漏洞宝库,这让我忙了一阵子。当我决定继续前进时,我随机选择了另一个应用程序,即该组织的招聘应用程序。
我通过HTML文件上传发现了一个跨站脚本(XSS)漏洞,但不幸的是,项目管理员将其标记为重复提交。如果你不熟悉漏洞赏金计划,这是因为另一位研究人员在我之前发现并向项目管理员报告了该漏洞,而只有任何有效漏洞的首次提交才会获得奖励。
经过几次筛选网站后,似乎所有容易发现的漏洞都已经没有了。是时候拿出大杀器了。
这次我使用了我最喜欢的新模糊测试工具ffuf。
ffuf -w /usr/share/wordlists/dirb/big.txt -u https://rob-sec-1.com/FUZZ -o Ffuf/Recruitment.csv -X HEAD -of csv
这就像旧的目录模糊测试工具,如dirb和dirbuster,但它是用Go编写的,速度要快得多。
这个工具会尝试枚举应用程序中的不同目录,用big.txt单词列表中的项目替换FUZZ。如果我们预览一下这个文件的样本:
$ shuf -n 10 /usr/share/wordlists/dirb/big.txt
odds
papers
diamonds
beispiel
comunidades
webmilesde
java-plugin
65
luntan
oldshop
...ffuf将尝试诸如rob-sec-1.com/odds、https:… HTTP方法,该方法只会从目标站点检索HTTP头部而不是完整页面。通常检索HEAD就足以确定该隐藏页面是否存在。我最喜欢ffuf的一点是自动校准选项,它可以确定应用程序返回的"正常情况"。我这里没有使用这个选项,但如果你传递-ac参数(我不建议与-x HEAD一起使用),它会抓取一些随机的URL路径,看看应用程序是否遵循Web标准对不存在的页面返回HTTP 404错误,或者是否返回其他内容。在后一种情况下,如果返回了非标准的内容,ffuf通常会确定这个响应的独特之处,并调整其引擎只输出与通常不同的结果,从而值得调查。这将使用页面响应大小作为其中一个因素,这就是我不建议使用-x HEAD的原因,因为它不返回正文及其大小,因此自动校准将受到严重限制。
无论如何,回到应用程序。Ffuf运行:
运行上述命令生成了以下CSV,我们可以使用Linux终端中的column命令读取:
column -s, -t Ffuf/Recruitment.csv
我上面突出显示的结果引起了我的注意。部署到Web应用程序的第三方工具可能是漏洞的重要来源,因为代码通常可以在没有审查的情况下放入,而且由于它正在工作,往往会被遗忘并且永远不会更新。快速谷歌搜索显示,这实际上来自一个名为ZeroEditor的软件包,可能不仅仅是网站上的一个目录:
请注意,像往常一样,我已经在我的实验室中对应用程序、第三方软件和漏洞的详细信息进行了匿名化和重新创建。详细信息已更改以保护易受攻击的对象。如果你谷歌搜索,你不会在第一个结果中找到ASP.NET HTML编辑器,我的帖子与返回的网站和应用程序无关。
从第三方供应商的网站,我下载了zip格式的可用源代码,然后使用以下命令将安装目录结构转换为我自己的自定义单词列表:
find . -type f > ../WebApp/ZeroEditor-Fuzz-All.txt
在这个文件中,我注意到许多"非危险"文件类型,例如"Images"目录中的文件,因此我这样过滤:
cat ZeroEditor-Fuzz-All.txt | grep -v 'Images' > ZeroEditor-Fuzz-No-Images.txt
现在我们可以看到这个编辑器的未过滤和过滤后的自定义单词列表的前几行:
现在我们可以再次运行ffuf,这次使用我们制作的自定义单词列表:
ffuf -w ZeroEditor-Fuzz-No-Images.txt -u https://rob-sec-1.com/ZeroEditor/FUZZ -o Ffuf/Recruitment-ZeroEditor-Fuzz.csv -X HEAD -of csv -H 'User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0' -t 1
这次我们只运行一个线程(-t 1),因为从我们之前的模糊测试可以看出,Web应用程序或其服务器在性能方面并不出色,所以在这种情况下我们愿意慢一点。
我们可以像以前一样用列显示:
我的注意力被最后两个结果吸引。一个ASPX文件——里面可能有什么好东西吗?还有一个Shockwave Flash文件。我实际上反编译了后者,但结果只是一个标准的Google视频播放器,我在代码中找不到任何XSS或其他有趣的东西。
回到Spell-Check-Dialog.aspx。我们可以用这个发现的文件做什么?
直接加载页面得到以下内容:
最初我的首选是param-miner,它可以找到隐藏参数,就像我在这里使用wfuzz所做的那样。不同之处在于param-miner更快,因为它会通过采用二分搜索尝试多个参数,并且它还会使用算法方法来检测内容差异,而无需你指定基线是什么(在这方面类似于Ffuf)。
但我们不需要这样做,因为我已经有源代码了!我可以自己进行代码分析来寻找漏洞。
检查代码时,我发现了以下反映参数的内容:
<asp:panel id="DialogFrame" runat="server" visible="False" enableviewstate="False">
<iframe id="SpellFrame" name="SpellFrame" src="Spell-Check-Dialog.aspx?ZELanguage=<%=Request.Params["ZELanguage"]%>" frameborder="0" width="500" scrolling="no" height="340" style="width:500;height:340"></iframe>
</asp:panel>
代码<%=Request.Params["ZELanguage"]%>从查询字符串或POST数据输出ZELanguage,而没有进行缓解跨站脚本攻击的措施——输出编码。
然而,当我继续传递ZELanguage的查询字符串时,什么也没有发生:
https://rob-sec-1.com/ZeroEditor/Spell-Check-Dialog.aspx?ZELanguage=FOOBAR
我猜这可能是因为上面asp:panel标签中的默认visible="False"。进一步检查后,我找到了使DialogFrame可见的代码:
void Page_Init(object sender, EventArgs e)
{
// show iframe when needed for MD support
if (Request.Params["MD"] != null)
{
this.DialogFrame.Visible = true;
return;
}
}
总之,看起来我只需要同时设置MD为某个值。因此,从隐藏页面我找到了两个隐藏的查询字符串参数:MD=true&ZELanguage=FOOBAR。
通过审查代码了解其工作原理,使我能够构造新的查询字符串:
https://rob-sec-1.com/ZeroEditor/Spell-Check-Dialog.aspx?MD=true&ZELanguage=FOOBAR"></iframe><script>alert(321)</script>
宾果,XSS:
如果供应商进行了输出编码,本可以缓解此问题:<%=Server.HTMLEncode(Request.Params["ZELanguage"])%>
下载的zip中还有另一个文件,如果存在,可能允许服务器端请求伪造(SSRF)或目录遍历,然而,在目标的模糊测试中没有发现它,表明它在部署后已被删除。Spell-Check-Dialog.aspx中还有一些目录操作代码,将用户输入作为路径的一部分,然而,它似乎没有对文件做任何太疯狂的事情,并且它还附加了静态文件扩展名,使其用途有限。这让我们暂时只有XSS,尽管我在漏洞赏金计划中发现了更多有趣的发现,但它们更难在实验室环境中重现。如果项目管理员的客户将来允许,发布它们会很好。
时间线
- 2019年12月27日:向项目管理员报告。
- 2019年12月29日:由项目管理员进行分类。
- 2020年3月3日:向HTML编辑器供应商报告,因为在写这篇文章时我想到检查最新版本是否易受攻击。粗略一看表明它是易受攻击的。没有向供应商披露任何易受攻击目标的详细信息,因为代码本身是易受攻击的。
- 2020年4月28日:从漏洞赏金计划获得400美元奖励。
- 待定:供应商的回应。
- 2020年5月19日:文章最后更新。