XSS漏洞挖掘实战:通过文件上传与目录模糊测试发现跨站脚本漏洞

本文详细记录了作者在漏洞赏金项目中发现的XSS漏洞,通过HTML文件上传和目录模糊测试技术,利用ffuf工具发现第三方组件ZeroEditor中的安全漏洞,最终成功构造出可执行恶意脚本的XSS攻击向量。

XSS Hunting

本文记录了我从漏洞赏金项目中的一个发现。该项目范围内约有20个Web应用程序。

幸运的是,我选择的第一个应用程序是一个漏洞宝库,这让我忙了一段时间。当我决定继续前进时,我随机选择了另一个应用程序,即该组织的招聘应用程序。

我通过HTML文件上传发现了一个跨站脚本(XSS)漏洞,但不幸的是,项目经理将其标记为重复。如果您不熟悉漏洞赏金,这是因为另一位研究人员在我之前已经发现并向项目经理报告了该漏洞,并且只有第一个提交的有效漏洞才会被考虑奖励。

在多次筛选网站后,似乎所有容易发现的漏洞都已消失。是时候拿出大杀器了。

这次它是以我最喜欢的新模糊测试工具ffuf的形式出现的。

1
ffuf -w /usr/share/wordlists/dirb/big.txt -u https://example.com/blog-rs1/FUZZ -o Ffuf/Recruitment.csv -X HEAD -of csv

这就像旧的目录模糊测试工具,如dirb和dirbuster,但是,它是用Go编写的,速度要快得多。

这个工具将尝试枚举应用程序中的不同目录,用big.txt单词列表中的项目替换FUZZ。如果我们偷看这个文件的一个样本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ shuf -n 10 /usr/share/wordlists/dirb/big.txt
odds
papers
diamonds
beispiel
comunidades
webmilesde
java-plugin
65
luntan
oldshop

…ffuf将尝试诸如https://example.com/blog-rs1/odds、https://example.com/blog-rs1/papers、https://example.com/blog-rs1/diamonds等URL路径,并报告其发现。-X参数告诉它使用HEAD HTTP方法,该方法仅从目标站点检索HTTP头部而不是完整页面。通常检索HEAD足以确定该隐藏页面是否存在。我最喜欢ffuf的一点是自动校准选项,它确定应用程序返回的"正常情况"。我在这里没有使用这个选项,但如果您传递-ac参数(我不建议与-x HEAD一起使用),它将自行获取一些随机URL路径,以查看应用程序是否遵循Web标准对不存在的页面返回HTTP 404错误,或者是否返回其他内容。在后一种情况下,如果返回了非标准内容,ffuf通常会确定使此响应独特的因素,并调整其引擎仅输出与通常不同且值得调查的结果。这将使用页面响应大小作为其中一个因素,这就是我不建议使用-x HEAD的原因,因为它不返回正文及其大小,因此自动校准将受到严重限制。

无论如何,回到应用程序。Ffuf运行:

运行上述命令生成了以下CSV,我们可以使用Linux终端中的column命令读取:

1
column -s, -t Ffuf/Recruitment.csv

我上面高亮显示的结果引起了我的注意。部署到Web应用程序的第三方工具可能是漏洞的巨大来源,因为代码通常可以在未经审查的情况下放入,并且由于它正在工作,往往被遗忘且从未更新。快速Google搜索显示,这实际上来自一个名为ZeroEditor的软件包,可能不仅仅是网站上的一个目录:

请注意,像往常一样,我已经在我的实验室中对应用程序、第三方软件和漏洞的细节进行了匿名化和重新创建。细节已更改以保护易受攻击的对象。如果您Google这个,您不会在第一个结果中找到ASP.NET HTML编辑器,我的帖子与返回的网站和应用程序无关。

我从第三方供应商的网站下载了可用的zip格式源代码,然后使用以下命令将安装目录结构转换为我自己的自定义单词列表:

1
find . -type f > ../WebApp/ZeroEditor-Fuzz-All.txt

在这个文件中,我注意到许多"非危险"文件类型,例如"Images"目录中的那些,因此我这样过滤:

1
cat ZeroEditor-Fuzz-All.txt | grep -v 'Images' > ZeroEditor-Fuzz-No-Images.txt

现在我们可以看到这个编辑器的未过滤和过滤自定义单词列表的前几行:

现在我们可以再次运行ffuf,这次使用我们制作的自定义单词列表:

1
ffuf -w ZeroEditor-Fuzz-No-Images.txt -u https://example.com/blog-rs1/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类似)。

但我们不需要这样做,因为我已经有源代码!我可以自己进行代码分析以寻找漏洞。

检查代码时,我发现了以下反映参数的内容:

1
2
3
<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的查询字符串时,什么也没有发生:

1
https://example.com/blog-rs1/ZeroEditor/Spell-Check-Dialog.aspx?ZELanguage=FOOBAR

我猜测这可能是因为上述asp:panel标签中的默认visible="False"。进一步检查后,我找到了使DialogFrame可见的代码:

1
2
3
4
5
6
7
8
9
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

并审查代码以了解其工作原理使我能够构造新的查询字符串:

1
https://example.com/blog-rs1/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日:帖子最后更新。
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计