Undefsafe模块原型链污染(CVE-2019-10795)
undefsafe模块简介
https://www.npmjs.com/package/undefsafe
在低版本( < 2.0.3 )存在原型链污染漏洞
npm安装存在漏洞的低版本
1 | npm install --save undefsafe@2.0.0 |
解决报错
1 | var object = { |
当我们访问一个对象不存在的属性时,会报错然后退出程序,undefsafe帮我们解决了这个问题
1 | var undefsafe = require("undefsafe"); |
赋值操作
为一个不存在的属性赋值时,会在其上层赋值
1 | var undefsafe = require("undefsafe"); |
漏洞分析
当我们进行赋值操作,控制了第二个和第三个参数,便可以对对象的属性进行污染
1 | var undefsafe = require("undefsafe"); |
但这还不够,通过这里的污染可以进一步攻击
污染Object的toString方法
1 | var undefsafe = require("undefsafe"); |
JavaScript中,其实对象中的方法也就是一个属性,所以这里undefsafe在object中没有toStr
ing方法,他就会往object.__proto__
,也就是Object中查找,然后污染了Object对象中本来的toString函数。
污染前:
污染后:
调试分析
接下来下断点调试,还是使用上面的demo调试
一开始初始化了一些变量
用filter遍历数组parts,这里判断为false,赋值给star
判断type,45行得知type就是传入的对象类型,而这里两个判断都不满足
对part进行遍历
中间的判断,key不为*所以跳过
这里key为__proto__
,obj为object对象,就获取到了object.__proto__
第二次就是object.__proto__.toString
,也就是Object对象的toString方法。
然后就是赋值操作,这里对Object对象的属性进行了赋值,污染了原型属性
修复分析
getOwnPropertyNames判断对象自己所有的属性
Object.getOwnPropertyNames()
方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
返回到上面一张图:
此时key为__proto__
,obj为object对象
1 | var i = Object.getOwnPropertyNames(object).indexOf('__proto__'); |
更新之后会返回undefined
[网鼎杯 2020 青龙组]notes
构造函数Note中的方法edit_note
,存在原型链污染漏洞,通过控制第二个和第三个参数我们似乎可以进行原型链污染
找到edit_note路由,发现参数是可以控制的。
下面就要找利用点,这里通过for in,来遍历commands里的命令然后作为exec的参数执行并返回结果
可以看到,我们通过遍历输出了恶意命令输入
for…in 循环只遍历可枚举属性(包括它的原型链上的可枚举属性)。像 Array和 Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性,例如 String 的 indexOf() 方法或 Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
同样数组也适用
所以说得多调试,多调试,多调试
至此问题迎刃而解,直接反弹shell就行