pikachu SQL-inject模块
注入漏洞一直是危害排名第一的,其中主要指SQl Inject漏洞
1.数字型注入
打开pikachu数字注入单元,我们查询一用brup suite抓包发送到repeater模块分析,发现这是个post提交,我们没法使用url注入
我们直接修改包的参数注入,修改id=1 为 id = 1 or 1=1 返回的包http值为200 页面正常
输入后发现所有的值都已经列出来了。
2.字符型注入(get)
随便输入1,发现由于是get型的,所以参数直接就在url里面了,输入名字试试lucy(前面实验用到过)发现返回了id 和email
我们去猜想他的内部结构 $uname=$_GET['username']
select id,email from 表名 where username = '$uname' 大致应该是这样的 我们可以构造一个闭合去尝试一下 既然猜测到了语句 我们输入111' or 1 = 1#
发现所有的结果都已经爆了出来。
3.搜索型注入
搜索型注入,我们继续猜想逻辑 既然是能通过部分查询就可以想到sql中的like的用法 比如
select id email from 表名 where username like '%$uname%' 这里面的$uname其实就是我们输入的部分,我们继续尝试构造闭合 111%' or 1=1# 其中%'闭合前面的'% #直接将后面的字符注释掉
输入后发现结果已经爆出来了。
4.xx型注入
我们打开xx型注入 发现他的功能和之前字符型的一样,重新输入原来的闭合发现没有爆出结果,我们猜测这应该是一种其他方式的闭合,我们查看源码,发现他的闭合又多了一层括号,我们再次构造闭合
111') or 1=1 # 原理一致,')来闭合前面对应部分 #注释后面的字符
输入后发现所有值已经爆出来了,这里由于我们是练习,所以直接查看了源码,实战的时候就要靠我们的经验与猜测来测试了。
5.insert/update型注入
insert 在数据库的用法一般是 insert into 表名(username,pw,sex,add,number) values('str',111,2,333,4)
updatexml函数 updatexml函数具有查询功能 并且会在xpath处查询 你将语法构造错误 然后它就会将他查询的结果已报错的形式显示出来
concat(ss,dsa,dd)作用是将字符串拼接
既然我们已经知道了插入的语句 我们就可以构造闭合了 xxx' or updatexml(1,concat(0x7e,database()),0) or ' 然后将我们构造的这个payload 输入到插入框中实验
结果我们查询的database()显示出来了,同理update也是一样的,我们用相同的payload在update中测试
我们先随便注册登录个账号,然后修改信息,将我们的payload输出进去
结果再一次在错误信息中显示出来,当然在我们实战过程里,把database()换成 我们需要的数据就ok了。
6.delete注入
打开delete注入页面,我们先随意删除一条留言,然后抓包查看
我们猜测应该是通过查询id的方式,来删除对应的留言,是数字型的注入,我们写一个payload尝试 既然是数字型的注入就不需要单引号了,我们是在url里提交的,所以需要有编码这一步,如图所示 brup suite里面有这个工具
我们的payload和之前原理样,通过让其报错查询结果 payload: 1 or updatexml(1,concat(0x7e,database()),0)
如图右下,我们需要的数据库名称已经显示出来。
7.Http Header注入
登录后我们发现他记录了我们的一些信息, ip地址,user agent等,猜测他可能记录了我们的http头,我们还是用brup suite查看一下包,
根据我们的猜想后台是记录我们的http信息,我们用User-Agent来做测试,首先我们先输入单引号尝试
发现确实界面报错,说明这里存在注入,我们将字符型payload输入实验,结果确实返回了我们查询的信息。
8.布尔盲注(基于错误)
这个很好理解,盲注就是数据库不会像之前那样返回其他信息,而只会根据我们输入的正确与否返回正确与错误两种结果,我们这里第一次输入 kobe‘and 1=1#正确,返回信息,错误则返回不存在,我们就可以根据这个来进行注入。
输入payload为 kobe' and ascii(substr(database()),1,1) = 112#
substr()函数就是选取字符,后面的1 1代表从第一个字符开始,取一个字符串 而ascii()函数是转换为ascii码 这样我们通过判断ascii码的值 来一步步确定每一个字符,然后获取最后的值,这里我们输入payload查询后返回结果正确,说明数据库第一个字符就是ascii 的 112 也就是 p 对应 数据库 pikachu
9.盲注(基于时间)
基于时间的盲注,由于无论我们输入什么,他只返回一个结果,我们就没办法判断正误,所以就有了基于时间的盲注,mysql中有个sleep()函数,我理解为休息多少时间,如果执行这个函数,我们的页面上就会处于正在连接状态,所以我们通过页面的连接时间,来判断是否执行了这个函数。 我们输入这个payload kobe' and if(ascii(subsrt(database,1,1))=112,sleep(5),null) # 这个payload的意思就是判断数据库第一个字符的ascii码是否等于112,是则休息五秒,否则正常返回。通过这样我们来依次判断字符。
输入后 确实休息五秒 说明第一个字符为ASCII码的112 也就是 字符p。
SQL Injection注入漏洞防范
一般通过两个维度来防范
1.代码层面:
①对输入进行严格的过滤和转义
②使用预处理和参数化(Parameterized)
2.网络层面:
①通过WAF设备启用防SQL Injection注入策略
②云端防护(360,阿里云盾)
转义+过滤:mysqli_real_escape_string()转义过滤单双引号等
str_replace("%","",$_POST['username']),把post里面的数据含有的%替换为空
预处理:使用PDO的prepare预处理(预处理+参数化)
平常SQL注入的时候是直接将payload和参数进行拼接,而prepare
先不传参数,先做预处理,比如下面的?就是一个参数化的占位符
当传参的时候都会把我们输入的语句当作一个整体去处理,而不像
我们之前那样可以进行闭合拼接。PDO默认情况会有两次交互,先
将带有占位符的参数华语句传给后台,之后再传语句。这样基本杜绝
了SQL注入的漏洞