一、SQL Inject 漏洞原理概述
1.1 什么是数据库注入漏洞
数据库注入漏洞,主要是开发人员在构建代码的时候,没有对用户输入的值的边界进行安全的考虑,导致攻击者可以通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄漏的一种漏洞。
1.2 SQL Inject漏洞的攻击流程
(1)第一步:注入点检测
自动方式:使用web漏洞扫描工具,自动进行注入点发现
手动方式:手工构造SQL Inject测试语句进行注入点发现
(2)第二步:信息获取-通过注入点取期望得到的数据
环境信息:数据库的类型、版本,操作系统的版本,用户信息等;
数据库信息:数据库名称,表,字段,字段内容(加密内容的破解)
(3)第三步:获取权限
获取操作系统的权限,通过数据库执行shell,上传木马程序。
1.3注入点类型及常见注入类型讲解
(1)数字型:user_id=$id
(2)字符型:user_id='$id'
(3)搜索型:text LIKE '%{$_GET['search']}%'"
1.4 演示:SQL Inject-数字型注入
1、来到pikachu平台数字型注入(post)模块,先测试一下页面的功能,我们在下拉框内选择1,点击查询。
2、我们猜想整个页面的逻辑是什么样的?
3、我们可以通过PHP Study 打开我们的数据库终端。执行命令:show databases;
显示我们所有的数据库。
4、在数据库命令行工具内执行:show tables;查看pikachu数据库内的所有表
5、在命令内执行:select username,email from member where id=1; 查询id=1的用户名和对应的邮箱。
6、通过上边在命令行里边的一同操作,我们猜想:如果系统后台正如我们所想象一样,将获取的id的值直接拼接到查询语句后边而不加处理,那么我们是不是可以通过抓包、数据重放的方式获取所有的用户名和对应的邮箱?下边我们先去看一下后台代码。
7、我们先打开burp suite,然后选择一次id值,查询。将抓到的数据包发送到重放模块。
1.5 演示:SQL Inject-字符型注入
1、来到pikachu平台字符型注入(get)模块,我们先看一下整个模块的功能。
2、现在我们猜想一下后台的处理逻辑。
3、现在我们构造闭合语句
lucy' or 1=1-- '
首先在lucy后边加一个单引号进行闭合,然后加上or 1=1,后边的单引号我们用注释符—注释掉。
4、将构造语句复制到查询框,点击查询。就会拿到我们所有的信息。
5、最后我们来看一下代码
1.6 演示:SQL Inject-搜索型注入
1、我们先来看源码
2、将构造语句填入搜索框
1.7 演示:SQL Inject-xx型注入
1、我们来看源码:
2、将构造的源码输入到查询框
1.8 总结
到现在为止,可能会有人疑问,我们做的演示都是在知道源码的情况下构造语句,那么在真实的环境里我们是不知道源码的,那么我们该如何构造语句呢?
- 第一种是我们可以根据报错的办法,例如:lucy',如果这个时候报错,说明存在单引号包裹;
- 第二种是我们可以利用and or 等,判定我们的构造语句是否参与了运算。
- 总之,还是要有经验,这个是一个积累的过程~~大家加油!
二、注入方式get&post的区别
GET方式中使用URL提交注入数据;
POST方式中使用抓包工具修改POST数据部分提交注入。
不管是GET还是POST,都有可能出现SQL注入漏洞,本质上是一样的!
三、SQL Inject漏洞手工测试
3.1 基于union联合查询的信息获取(select)
1、我们使用pikachu的字符型注入模块。
首先使用构造语句:lucy' order by [number]判断表存在几列。
2、然后使用union关键字查询信息
说明:user() database() 都是SQL语句里边的函数,具体的讲解可以参考我的关于sqli-libs 的博客。在这里我就不多说了。
3.2基于报错的信息获取(select/delete/update/insert)
由于我在我关于sqli-labs的博客中对报错查询做了详细的讲解。这里只是粗略的讲一下,如想深层次了解,请移步我的关于sqli-labs的博客。
在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。常用的报错函数有:
updatexml():对XML文档数据进行查询和修改的XPATH函数
extractvalue():对XML文档数据进行查询的XPATH函数
floor():用来取整的函数
注意:select/insert/update/delete都可以使用报错来获取信息。
条件:后台没有屏蔽数据库的报错,在语法发生错误时会输出在前端。
我们同样利用字符型注入(get)来进行演示
(1)、select 语句:
(2)、insert 语句
构造语句:xxx' or updatexml(1,concat(0x7e,database()),0) or '
(3)、update 语句:
和insert是一模一样的,大家可以试一下。
(4)、delete语句:
构造闭合语句:1 or updatexml(1,concat(0x7e,database()),0)
3.3操作系统权限获取
这里我们讲"一句话木马"这个概念
1、一句话木马是一种短小而精悍的木马客户端,隐蔽性好,且功能强大
2、我们可以通过SQL注入漏洞写入恶意代码
例如我们结合into outfile向后台写入:select 1,2 into outfile "/var/www/html/1.txt"
3、写入的前提条件:
(1)需要知道远程目录,我们作为测试者是一开始是不知道的
(2)需要走远程目录有写入的权限
(3)需要数据库开启了secure_file_priv
4、请看到这里的童鞋移步我的关于sqli-labs的博客,对于一句话配合中国菜刀工具控制操作系统有着详细的介绍。
四、SQL注入漏洞-盲注
在有些情况下,后台使用了错误消息屏蔽的方法(例如@)屏蔽了报错,那么此时无法再根据报错信息进行注入的判断。
这种情况下的注入,称为"盲注"。
4.1(boolian base)类型的盲注
我们直接来看构造语句:
kobe' and ascii(substr(database(),1,1))>113--
布尔类型的回显结果只有两种,正确还是错误。
我们首先用substr()函数取出database()的第一个字母,然后进行ascii编码,最后采用二分法判断,知道找到一个值可以使之输出正确的结果,得到第一个字母到底是什么,然后取出database()里边的第二个字母,以此类推……
4.2(time base)类型的盲注
布尔盲注还有正确和错误两种情况输出,但是在时间盲注类型下,就一种输出,无论正确与否,都是一种输出。
我们直接来看构造语句:
kobe ' and if((substr(database(),1,1))='p',sleep(5),null)--
这个构造语句的作用是,首先判断数据库的第一个字母是不是p,如果是就延迟5秒,表现出来就是网页一直显示在等待加载的状态,五秒后在返回结果页面,如果不是,就立即返回结果页面。
五、基于 http header的注入
有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等。然后会客户端的http header信息进行获取并且用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于http header的SQL Inject漏洞。
下面就这个场景下的SQL注入做演示。
1、我们来到pikachu的"http header"注入模块,打开burp suite抓包工具,开启浏览器代理,执行下图中的操作。
2、打开burp suite,将截取到的数据包发送到重放模块。
3、构造报错注入语句:firefox' or updatexml(1,concat(0x7e,database()),0) or '
4、除了在user agent处存在注入点,我们还猜想系统是否会对http header当中的cookie进行分析,验证用户名和密码。
5、我们执行上图的操作后,会在右侧的输出栏的底部发现报错,说明我们的猜想是正确的。我们同样构造注入语句:admin ' and updatexml(1,concat(0x7e,database()),0)—
六、SQL注入表列名猜解-暴力破解在SQLI上的应用
当我们没有权限读information_schema这个数据库的时候,或者我们面对的数据库不是MySQL的时候,那么我该如何获得列名和表名?
这个时候我们考虑采用暴力破解的方式。
首先我们得有一个构造好的语句:kobe' and exists(select * from aa)#
这个语句的作用是,aa作为变量,用exists()函数判断我们要查询的数据库是否存在,若存在就会返回一个正确的结果。
1、我们利用pikachu字符注入模块,开启burp suite,然后将构造好的语句输入。
2、来到burp suite将抓到的数据发送到暴力破解模块。
3、执行破解后,我们来看结果
七、使用SQL-map进行SQL Inject漏洞测试
1、我们利用布尔类型的盲注模块做演示:在模块里边的查询框内随便输入一个值,点击查询。
2、打开sqlmap工具
-D pikachu -T users –columns查询users表内的字段
-D pikachu -T users -C username,password –dump查询字段内容
这里就不展示了。
八、SQL注入漏洞常见的防控措施
1、代码层面
(1)对输入进行严格的转义和过滤
(2)使用预处理和参数化(Parameterized)
实例:
2、网络层面
(1)通过WAF设备启用防SQL注入策略(类似的防护系统)
(2)云端防护(360网站卫士,阿里云盾等等)