Lodash原型链污染
本文最后更新于 17 天前,其中的信息可能已经过时,如有 错误/失效 请发送邮件到xiaoc1737938763@gmail.com或留言。

Lodash这个前端框架的历史漏洞大多均为原型链污染,在渗透中如果碰到存在漏洞的版本,可以测试一下。

这里通过js加载不同版本的lodash来进行测试,需要哪个版本修改src中的版本即可


<!DOCTYPE html>
<html lang="zh-CN">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Lodash原型链污染</title>
</head>
<body>
   <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.12/lodash.min.js"></script>
   <script>
       console.log('Lodash版本:', _.VERSION);
       console.log('页面已加载,可以进行功能测试');
   </script>
</body>
</html>

CVE-2018-3721

版本影响:lodash < 4.17.5

漏洞描述:攻击者可以通过 mergedefaultsDeepmergeWith等函数将恶意属性注入到对象的原型上,导致全局对象被篡改。

poc

以merge为例

_.merge({}, JSON.parse('{"__proto__": {"polluted": "yes"}}'));
console.log({}.polluted);

原理

merge函数的作用是递归地把源对象的属性赋值给目标对象,poc中将该属性__proto__.polluted===yes赋给了目标对象{},即{}.__proto__.polluted===yes,成功将顶层对象Object污染了polluted属性。

CVE-2019-10744

  • 版本影响:lodash < 4.17.12
  • 漏洞描述defaultsDeep 函数未正确校验 prototype以及constructor,可以被利用污染原型。

poc

_.defaultsDeep({}, JSON.parse('{"constructor": {"prototype": {"vuln": true}}}'))
console.log({}.vuln)

如果输出true说明污染成功,存在漏洞。查看Object.prototype可以看到的确存在vuln属性

原理

{"constructor": {"prototype": {"vuln": true}}}这段json很容易就能看出来是一个原型链污染的payload,就是给constructor.prototype对象加上一个属性值"vuln": true

_.defaultsDeep函数的作用同样是递归地把源对象的属性赋值给目标对象,但不会赋值目标对象已经存在的属性。_.defaultsDeep(目标对象, 源对象)poc中的目标对象为Object空对象,源对象经过JSON.prase解析后变为constructor.prototype.vuln===true,赋值后即Object.constructor.prototype.vuln===true

首先Object.constructor拿到Object对象的构造函数Object(),Object.prototype意为构造函数的原型,即顶层Object对象,最后给顶层Object对象赋属性vuln===true,从而污染了Object对象。此时任意对象访问vuln属性都会向上查找,直到找到Object.vuln属性。

CVE-2020-8203

  • 版本影响:lodash < 4.17.20
  • 漏洞描述zipObjectDeep 存在原型链污染风险。

poc

const paths = ['({}).constructor.prototype.polluted'];
const values = ['yes!'];
_.zipObjectDeep(paths, values);
console.log({}.polluted);

NVD以及其他很多漏洞通报都说的是小于4.17.20存在,但是我经过测试发现只有<4.17.15才能成功复现。

chatgpt回答的是现代v8的安全防御机制,只有在特定老版本 Node 或浏览器里才生效。但我使用ie浏览器同样无法复现,就很疑惑。

原理

漏洞出在zipObjectDeep函数,该函数的作用是给数组路径赋值,zipObjectDeep(paths, value),支持对象解析,例如

_.zipObjectDeep(['a.b.c'], [1])
{
 a: { b: { c: 1 } }
}

poc中({}).constructor.prototype.polluted将顶层Object对象污染了polluted属性

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇