几个月前,有一天我正在滚动推特。而且,突然来自@github的一条推文引起了我的关注。基本上,该推文是关于 GitHub 的新功能,该功能提供通过MathJax库在 Markdown 中渲染或显示数学表达式(TeX 和 LaTeX 样式语法)的能力。
什么是 MathJax?
MathJax 是一个适用于 LaTeX、MathML 和 AsciiMath 表示法的开源 JavaScript 显示引擎,适用于所有现代浏览器,并内置对屏幕阅读器等辅助技术的支持。
阅读该推文后,我了解到“GitHub 现在正在使用 MathJax 库来显示 Markdown 文件中的数学表达式”。因此,我尝试的第一件事就是查找MathJax库中任何以前或已知的错误。主要是,我希望找到任何以前的 XSS 或 HTML 注入 CVE。
幸运的是,我在 MathJax 库中发现了已知的 XSS 问题,该问题影响版本 < 2.7.4 。并且,payload应采用 Unicode 形式才能工作。
\unicode{}
然后,我在测试存储库中创建了一个 markdown 文件。然后,我开始了我的测试。所以,我在文件中输入了👇这个payload:
$$\\u003cu\u003eHello\u003c/u\u003e{}$$
or $$\\u003cu\u003eWhy\u003c\uffofu\u003e{}$$
注:$$...$$
是数学分隔符。
但是,没有什么对我有用。而且,我知道原因是“CVE 仅在 <2.7.4 版本中容易受到攻击,而 GitHub 正在使用较新的版本”。
因此,我认为“我必须自己找到绕过方法才能成功利用攻击,并且如果我能够以某种方式呈现基本的 HTML 标签,例如:<b>,<i>,<u>
”。并且,您可能想知道为什么我只说基本 HTML 标签?因为,大多数时候网站会使用 WAF、不同类型的过滤器和限制来防止使用高级标签,但它们不会对基本标签和常见标签执行相同的操作。这就是为什么我说!
一旦我找到了使用数学表达式渲染基本标签的绕过或方法。那么只有在这种情况下,“我会尝试通过尝试高级标签来扩大影响”。
第一种利用方式或方法:
所以,我做的第一件事“就是找到任何有趣的行为,这对我使用数学表达式渲染基本标签非常有用”。为此,我尝试了不同类型的方法(如 Unicode、URL 编码等)。再说一次,这对我来说也不起作用。
但是,不知何故,我找到了一种对于使用数学表达式渲染基本标签非常有帮助的方法。我注意到“当我在之后使用基本标签时,\
只有在那个时候标签才会渲染,没有任何错误或没有被过滤”。而且,payload是$$\<u>HELLO</u>{}$$
因此,我很快<u>
用其他高级标签(如 <script>、<iframe>、<style>)替换了该标签,以便了解“网站是否使用了更多过滤器来阻止高级标签的使用?” 。答案是肯定的,GitHub markdown 文件正在使用更多过滤器,其中“它们只是过滤了除标签之外的任何高级标签<style>
”。
然后在测试了这个 mathjax 集成之后,我发现可以在其前面<style>
使用反斜杠()添加标签(例如:)。因此,为了自定义 CSS,我在test.md文件中使用了以下payload:\
\<style>{property:value}</style>
$$\<style>*{display:none}</style>{}$$
$$\<style>div{background-color:#66f3e6}</style>{}$$
$$\<style>*{font-size:23px;}</style>{}$$
$$\<style>body{padding:50px;background-color:#4b6bb7;}</style>{}$$
因此,我注意到现在我可以更改整个页面的 CSS。
而且,我创建了第一份报告并将其提交给 GitHub 的 HackerOne 计划。但是,你知道我的报告会发生什么“报告在 5 分钟内被机器人关闭,说这是一个先前发现的问题,正在内部跟踪”。有那么几分钟,我感到非常困惑,并认为“机器人真的是机器人,或者机器人背后有人类”。
所以,我问程序,“这个快速响应是来自 BOT 还是真人?” 。随后,GitHub 的 traiger 确认并回复道:“是的,请放心,您的报告是经过真人审核的。感谢您检查我的人性!”
我只能说“我向 GitHub 提交的第一份错误报告因重复而关闭”。
第二种利用方式或方法:
GitHub 在 24 小时内修复了该问题。
因此,我想用我之前的方法和payload重新测试该问题。而且,我发现“我无法再使用以前的方法和payload使用高级标签”。
不知何故,我设法找到了一种渲染标签的新方法。但这一次,我只能使用普通标签(例如:<div>、<span>、<section>、<input>、<label>、<button>),而不是“ <style>和<script>”数学表达式。
$<div>Test</div>{}$
$<input type=text>{}$
$<button>Click Here</button>{}$
尽管如此,我们也可以在 Markdown 文件中使用一些标签,例如“<div>、<span> 和 <section>”,而无需数学表达式。但通常情况下,我们不可能渲染“<input>和<button>”这样的标签。所以,这对我来说是一个巨大的胜利,因为我已经找到了一种方法,“我能够在 Markdown 文件中使用数学表达式来使用 <input> 和 <button> 等标签”。
不过,我没有向 GitHub 报告这一情况,因为“除了使用受限标签之外,我没有看到任何影响”。所以,我试图找到类似于上面第一种方法的东西,也许我可以修改页面的 CSS。但正如我已经说过的“修复后,我无法再使用 <style> 标签”。所以,剩下的唯一选择就是使用style 属性来修改 CSS,但又一个问题来了,“GitHub 限制了属性的使用”。
但你知道一件事吗?令人惊讶的是,我只能在数学表达式中使用“style”属性。同时,如果不使用数学表达式,就不可能在 Markdown 文件中使用“style”属性。
payload:-$$<tag style="property:value" acceptedAttribute="True"></tag>{}$$
因此,我只是创建了一个payload,使我的 Markdown 文件页面像登录页面一样。
$<div style="position:fixed;padding:10%;padding-right:100%;left:-9%;top:-20%;background:white;padding-bottom:100%;"><section style="margin-left:500px;padding:30px;"><h2 style="text-align:center;">Sign in to GitHub</h2><div><label>Username: </label><input type=text style="border-radius:5px;border:1px solid;">
<label>Password: </label><input type=password style="border-radius:5px;border:1px solid;"><div style="text-align:center;"><button style="background:#2da44e;color:white;margin:10px;border-radius:9px;border:none;font-weight:500;padding:4px;padding-right:20px;padding-left:20px;" type=submit>Sign in</button></div></section></div></div><!--{}$
但这一次,我没有创建新的报告,因为“我在第二天就发现了Bypass的方法,而且在上一份报告中,团队也表示他们正在内部处理这个问题”。因为,我想“如果团队仍在开发此功能,那么他们可能会再次将报告作为重复关闭”。
所以,我只是评论说“我刚刚找到了一个可以再次更改整个页面 CSS 的绕过方法。所以请告诉我,内部团队是否解决了这个问题?因为我无法用最后一种方法更多地重现它!如果是(问题已解决),那么我很高兴在上一份报告中创建一份新报告作为旁路……” 。
并且,GitHub 工作人员回复了以下声明,您可以在下图中看到
第二天,当我醒来时,我注意到 GitHub 团队再次修复了这个问题,因为新的payload不再工作了😶。所以,这表明“他们是对的,他们确实在 MathJax 内部工作”。
第三种利用方式或方法:
尽管如此,我还是没有阻止自己在 MathJax 功能中发现一些不寻常的东西。
我注意到在第二次修复之后,我无法使用之前的payload渲染任何高级标签。
如果您看到我上面的两种不同方法的payload,那么您可以清楚地看到“在数学表达式中使用任何标签之前,我使用了反斜杠( ),例如: ”\
\<tagName>{}
。
同样,我也注意到了这一点,并将数学表达式中的payload位置从 更改$$\<tagName>{}$$
为$$\{<tagName>}$$
。然而,标签被过滤了。但花了更多时间后,我终于找到了一种像使用 MathJax 一样渲染一些标签的方法<input>,<svg>,<button>,<textarea>
。
payload:$$\<script>{<renderTag>}$$
该payload如何工作:(详细阅读)
- 在反斜杠(
\
)之后的第一个位置,标签应该是从payload中过滤掉的恶意标签,例如\<script>
或\<style>
- 并且,我们要渲染的主标签应该位于大括号之间
{<renderTag>}
。大于和小于符号应采用 HTML 实体的形式。
所以我们的最终payload将如下所示$$\<script>{<renderTag>}$$
:由此,<script>
大括号之前写入的或任何标记将被过滤掉。并且,Mathjax 将仅渲染大括号中的标签。
我在POC 文件中使用了以下payload。test.md
$\<script>{<div><section><h2>Sign in to GitHub</h2><label>Username: </label><input><br><label>Password: </label><input><br><button>Sign in</button></section></div><!--}$<br>
## Input tag:
$\<script>{<input><!--}$<br>
## Button tag:
$\<script>{<button>Test Button</button><!--}$<br>
## Textarea tag:
$\<script>{<textarea>Write something...</textarea><!--}$<br>
虽然我试图增加这个问题的影响但失败了。
因此,我向 GitHub 报告了这个问题,严重程度为“低”。这次,GitHub 接受了该问题的严重程度,并免费向 SWAG 和 GitHub Pro 支付了 10,000 美元的赏金。
我只能说“这个新的MathJax 功能带来了一些配置错误”。
payload总结:
- 我在第一种方法或方式中使用的payload:-
$$\<style>{property:value}</style>{}$$
- 我在第二种方法或方式中使用的payload:-
$$<tag style="property:value" acceptedAttribute="True"></tag>{}$$
- 我在第三种方法或方式中使用的payload:-
$$\<script>{<renderTag>}$$
报告的时间表:
- 5月21日——向GitHub报告第一份报告
- 5 月 21 日 – 报告因重复而关闭
- 5 月 24 日 – 再次通过新的绕过方式向 GitHub 报告该问题
- 5 月 25 日 – 报告由 GitHub 分类
- 8 月 20 日 – GitHub 解决了该问题
- 8 月 20 日 – GitHub 奖励了我 10,000 美元的奖金、SWAG 和 GitHub Pro。