目录
前言:
渗透的学习,必须要心无旁骛,通过靶场实战不断总结经验,vulnhub、hackthebox......这些靶场,如果有一个知识点没有掌握就会卡着动不了,之前整理sql注入的文章有点杂,主要原因是此部分内容较多。
由于笔者个人水平有限,行文如有不当,还请各位师傅评论指正,非常感谢
(一)宽字节注入
如今有很多人在编码的时候,大多数人对程序的编码都使用unicode编码,网站都使用utf-8来一个统一国际规范。但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如gbk,作为自己默认的编码类型。也有一些cms为了考虑老用户,所以出了gbk和utf-8两个版本。一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节。
至于mysql宽字节注入的原理就是因为数据库使用了GBK编码,源于程序员设置数据库编码为非英文编码那么就有可能产生宽字节注入。
首先建议大家要有编码的基本知识,可以看这个大佬整理的常用编码
1、为什么要介绍宽字节
比如说魔术引号、addslashes()、mysql_real_escape_string() ......这些函数在预定义字符之前添加反斜杠 \ ,在这种情况下就不容易完成注入,所以出现了宽字节注入,通过宽字节绕过转义字符。
2、产生根本原因
宽字节SQL注入就是PHP发送请求到MySql时使用了语句
SET NAMES 'gbk' 或是SET character_set_client =gbk 进行了一次编码,但是又由于一些不经意的字符集转换导致了宽字节注入。
3、绕过原理
- 比如使用%df’:会被PHP当中的addslashes函数转义为“ %df\’ ”。
- “ \ ”即url里面的“ %5c ”, “ ’ ”对应的url编码是“%27”,那么也就是说,“ %df’ ”会被转义“ %df%5c%27 ”
- 倘若网站的字符集是GBK,mysql使用的编码也是GBK的话,就会认为“ %df%5c%27 ”是一个宽字节。
- “ %df%5c ”会结合(因为宽字节是占两个字节),也就是“縗” 。后面就有一个“ ’ ”。就造成了一个攻击效果
举个栗子:
这里明显是过滤了。
我们加上%df
接下来的思路就是和union正常查询一致
4、宽字节注入的修复
在调用 mysql_real_escape_string() 函数之前,先设置连接所使用的字符集为GBK ,mysql_set_charset=(‘gbk’,$conn) 。这个方法是可行的。但是还是有很多网站是使用的addslashes()函数进行过滤,我们不可能把所有的addslashes()函数都换成mysql_real_escape_string()。
所以防止宽字节注入的另一个方法就是将 character_set_client 设置为binary(二进制)。需要在所有的sql语句前指定连接的形式是binary二进制:
mysql_query("SET character_set_connection=gbk, character_set_results=gbk,character_set_client=binary", $conn);
当我们的MySQL收到客户端的请求数据后,会认为他的编码是character_set_client所对应的编码,也就是二进制。然后再将它转换成character_set_connection所对应的编码。然后进入具体表和字段后,再转换成字段对应的编码。当查询结果产生后,会从表和字段的编码转换成character_set_results所对应的编码,返回给客户端。所以,当我们将character_set_client编码设置成了binary,就不存在宽字节注入的问题了,所有的数据都是以二进制的形式传递。
(二)堆叠注入
在SQL中,分号;是用来表示一条sql语句的结束。试想一下我们在 ; 结束后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别呢?区别就在于union 或者union all执行的语句类型是有限的,只可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:root’;DROP database user;服务器端生成的sql语句为:Select * from user where name=’root’;DROP database user;当执行查询后,第一条显示查询信息,第二条则将整个user数据库删除。
1、局限性
堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
因为堆叠注入原理就是通过结束符同时执行多条sql语句,这就需要服务器在访问数据端时使用的是可同时执行多条sql语句的方法,比如php中mysqli_multi_query()函数,这个函数在支持同时执行多条sql语句,而与之对应的mysqli_query()函数一次只能执行一条sql语句,所以要想目标存在堆叠注入,在目标主机没有对堆叠注入进行黑名单过滤的情况下必须存在类似于mysqli_multi_query()这样的函数,简单总结下来就是
目标存在sql注入漏洞
目标未对";"号进行过滤
目标中间层查询数据库信息时可同时执行多条sql语句
2、各数据库实战
SQL注入-堆叠注入(堆查询注入) - 0nth3way - 博客园
Pgsql堆叠注入场景下通过`CREATE FUNCTION`来实现命令执行 - 安全客,安全资讯平台
上面二篇文章,环境我没有搭建,我现在以sqli-labs为例:
1、插入一条数据
经过测试存在union联合注入,使用联合注入爆破出users表中有id、username、password三个 字段,先看看源码。
查看一下,注意插入删除是没有回显的
2、查看插入的数据
说明目标存在堆叠注入,如果目标没有限制执行的sql语句,那就可以随心所欲的执行你想要执行的sql语句了!(非常危险)
(三)二次注入
二次注入漏洞是一种在Web应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以被发现,但是它却具有与一次注入攻击漏洞相同的攻击威力。
1、实现过程
- 黑客通过构造数据的形式,在浏览器或者其他软件中提交HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL语句或者命令。
- 服务端应用程序会将黑客提交的数据信息进行存储,通常是保存在数据库中,保存的数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响应。
- 黑客向服务端发送第二个与第一次不相同的请求数据信息。
- 服务端接收到黑客提交的第二个请求信息后,为了处理该请求,服务端会查询数据库中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的SQL语句或者命令在服务端环境中执行。
- 服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注入漏洞利用是否成功
这种方式与XSS存储型类似,下面我们来举个例子演示。
2、less24演示
这是一个登陆页面,我们是hacker没有账号,所以选择新建一个用户
我们新建的用户名为:admin'# 密码为:123456
查看数据库,发现该用户已经创建。
我们使用新建的用户名和密码登录,可以正常进去
用admin,aaaaaaaaaa登入
查看数据库,发现用户 admin’# 的密码并没有修改,而且 admin 用户的密码修改为了 aaaaaaaaaa
那么,为什么会这样呢?我们查看修改密码页面源代码,发现这里存在明显的SQL注入漏洞
当我们提交用户名 admin’# 修改密码为 aaaaaaaaaa 的时候,这条SQL语句就变成了下面的语句了。#把后面的都给注释了,所以就是修改了admin用户的密码为 aaaaaaaaaa
$sql = "UPDATE users SET PASSWORD='aaaaaaaaaa' where username='admin'#' and password='$curr_pass' ";