自己在学习过程中的一点总结
在一些Web网页中,会允许用户传入参数,并将这些参数带入数据库中进行查询,这就产生了一些注入漏洞
SQL注入漏洞需要满足以下两个条件:
在众多库中有一个最重要的:information_schema(系统自带库)
在这个库中有三张表更重要:
select
:从表里查询所有内容【查询基本语句】
select 1,2,3
:显示1,2,3
select database()
:显示当前库名
where
:有条件的从表中选取数据
and/or
:有多个条件时用and和or连接
order by
:根据制定的结果集/指定的列进行正序排序(order by 1 :根据第一列进行排序,当指定的列不存在时会直接报错)
order by 1 desc
:倒序排列
length(str)
: 计算长度
substr(str,pos,length)
:截取指定位置指定长度的字符串
ascii(substr(database(),1,1) =107
: 查询ascii码中对应的值
substring(str FROM pos FOR length)
:防止逗号截断
substring_index(str,delim,count)
:返回查找字段出现次数的前一个位置
mid(str,pos,length)
:截取函数
right(str,length)
:从右边开始截取
left(str,length)
:从左边开始截取
limit 0,1
: 从第一行起显示一条记录(从第几行起,显示多少行的记录)
union select
:将多个表拼在一起(字段数要一致)
#/-- //**/
:注释形式
/*!code*/
:内联注释
顾名思义利用sql语句中的union语句,将想要查询的数据连接在前面的查询语句后。
id=1’ 在1后面加上单引号,页面出错
id=1 and 1=1 正常 id=1 and 1=2 错误
出现这种状况就说明我们写入的参数被放入了数据库中,但由于输入的字符于数据库所需要的参数不同,或者是判断后为假,导致无法正常查询,而出现了页面错误。在这时候我们可以知道自己的写入到参数可控并且被放入数据库中运行,也就出现了sql注入漏洞。
但这种漏洞的判断往往需要很多方式,需要我们做过很多尝试才能确定,我们后面会介绍一种工具sqlmap,用于判断简单的sql注入漏洞。
构造测试 | 预期结果 | 变种 |
---|---|---|
a’ | //触发错误,返回数据库错误 | NULL |
a’ or ‘1’='1 | //永真条件,返回所有记录 | a’) or (‘1’=1 |
a’ or ‘1’='2 | //空条件,返回原来相同结果 | a’) or (‘1’=2 |
a’ and ‘1’='2 | //永假条件,不返回记录 | a’) and (‘1’='2 |
order by 1,2 | 返回正常页面
order by 1,2,3 | 返回错误页面
说明在此表中一共有两列
id=1 and 1=2 --保证前面的数据无法正常返回
union select 1,2,3
我们想要得到的是1,2,3这三个数字,可以看到在login name和password的位置得到了我们想要的数据,说明我们的回显点在这两个位置,我们可以把3这个位置换成获得要想数据的sql语句。
id=1 and 1=2
union select 1,2,
(select table_name from information_schema.tables where table_schema=database() limit 0,1)
因为在这种回显报错中只能返回其中一行数据所以要利用limit0,1或者group_concat()
这些步骤几乎是所有sql注入的基本步骤,不同的注入方式只是在sql语句的运用上稍加改变,有些可能是运用不同的sql语句,有些事将sql语句注入到不同的位置中。
盲注也是在sql注入中比较常见的一种,因为页面不能直接显示我们想要看到的数据只能利用猜测的方式确定想要的数据。
这种注入方式是因为页面只有两种,一种是返回的正确页面,另一种则是返回的错误页面。基本步骤和union注入一致,只是只能利用length(database())>1
这种办法来猜测想要数据的长度和具体数字。大多数时间都是利用burpsuite的Intruder来一位一位爆破。
这种页面是完全没有差别,只能利用sleep(),改变网页的响应时间,来判断自己的猜测是否正确。
sleep()
根据睡眠时间判断BENCHMARK(count,expr)
重复执行count次执行表达式expr。可以被用于计算MYSQL处理表达式的速度,结果值通常为0GET_LOCK(str,timeout)
:设法使用字符串str给定的名字得到一个锁,超时为timeout秒(长链接,且可以开两个会话)select * from table where id=1 and if(database()=' ',sleep(4),NULL)
case when condition then result
类似于if/else语句select case when username='admin'THEN 'aaa' ELSE(sleep(3)) end from user;
在sql语句中是可以利用分号结束上一句话然后开始下一个增删查改语句,也就是在同一时间执行了多条语句。
这种方法和union注入有相似之处,当union这个关键词被过滤的时候就可以用到堆叠注入的方法,也可以配合盲注的两种方法一起。
当我们传入的参数发生错误的时候,页面直接把报错的信息返回到页面上,这种时候就可以用到报错注入。在我的另一篇文章中比较详细的介绍了报错注入常使用的三种函数。
传送门
这种攻击方式运用在有两个页面需要同时被使用,比如第一个页面需要我们注册一个用户,返回给我们一个id,然后我们利用这个id进入到另外一个登录页面,在登录页面中可以看到或者反映出我们想要看到的数据。
这种攻击也是需要结合前面的几种注入方法,根据页面的返回情况不同,选择不同的注入方法配合使用。
这种是利用gbk的编码方式,在gbk中认为两个十六进制放在一起为一个汉字,我们就是利用这种方法来将引号或者任何符号逃逸出来,进而继续我们想要进行的攻击
这种注入方式主要是利用响应头中的UA、IP、Cookie等等位置进行注入攻击,目前具体的判断方法还没有发现
我们将注入的语句利用base64编码,从而逃过过滤等行为
在sql注入方面的题目中,往往会设置许多过滤危险字符的方式,所有就出现了一些利用sql漏洞的字符绕过方法。
推荐一个个人感觉很实用的sqlmap教程,主要用于一般形式的sql注入,但是有些header头注入的还没有总结
传送门
感谢Kal1博主)
其实这么整理下来,我还是感觉只写出了很小的一部分,sql注入很大一部分都是需要自己去不断地整理、不断地尝试,就是一个试错的过程,而且有时候自己试了很久最后发现根本不是sql注入的类型,前面的功夫钱都白费。有耐心一切都好。