关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客
0x01:加解密注入 —— 理论篇
当我们尝试寻找 SQL 注入漏洞时,有时会发现服务器会对某些数据字段进行编码或加密处理。这看起来像是服务器在有意保护这些数据,不让它们被轻易读懂或篡改。但是,如果我们有能力修改这些加密的数据,那么这些被加密的内容实际上就可能成为我们进行 SQL 注入的新入口。
而且,这里还有一个有趣的点:很多用来保护网站免受攻击的系统(我们称之为 WAF,也就是 Web应用防火墙)其实并不能识别服务器端业务中的加密信息。这是因为 WAF 通常是第三方开发的,它并不完全了解每个网站的业务逻辑和数据加密方式。所以,当我们传递加密后的信息给服务器时,WAF 可能只会看到一串乱码,而无法判断这是否是一个危险的攻击行为。
这就意味着,如果我们能够巧妙地利用加解密注入,就有可能绕过 WAF 的防御,让 SQL 注入攻击变得更加难以防范。
所以,当我们进行 SQL 注入漏洞挖掘时,不仅要关注那些直接可见的注入点,还要留意那些可能被加密的数据字段。因为只要我们能够修改这些数据,它们就可能成为我们进行 SQL 注入的新机会。
0x02:加解密注入 —— 实战篇
本节重点在于熟悉加解密注入的注入流程,以及注入原理。练习靶场为 Sqli-labs Less-21 Cookie Injection - Base64 Encoded - Single Quotes And Parenthesis,靶场的配套资源如下(附安装教程):
实验工具准备
PHP 运行环境:phpstudy_x64_8.1.1.3.zip(PHP 7.X + Apache + MySQL)
SQLI LABS 靶场:sqli-labs-php7.zip(安装教程:SQLI LABS 靶场安装)
0x0201:第一阶段 — 判断注入点
进入靶场,是一个登录框,本关的名称中包含 Cookie Injection
证明注入点是在 Cookie 中。所以这里我们先开个挂,先使用一个合法的用户进行登录,等获取了 Cookie 的命名规则后再进行进一步的测试
笔者这里使用的用户名和密码是 Dumb : Dumb
,登陆后的页面如下所示:
如此,我们成功获取了目标后端所需要的 Cookie 的样式:
uname = RHVtYg==
从 Cookie 的样式可以看出,uname
字段的值其实是被 Base64 编码过了的,我们可以直接利用工具对其进行解码:
拓展阅读:Base64 编码
Base64 编码是一种基于 64 个可打印字符来表示二进制数据的表示方法。它主要用于在需要处理文本数据的场合(如电子邮件、URL、网页等)中嵌入二进制数据。
Base 64 的基本原理如下:
字符集: Base64 使用一个包含 64 个字符的集合,这些字符由 A-Z,a-z,0-9,+,/,以及一个填充字符 = 号组成。
编码过程:
将输入的二进制数据每 3 个字节分成一组(24 位)。
将这 24 位数据分成 4 个 6 位段。
将每个 6 位段转换为一个在 0 到 63 之间的整数。
使用 Base64 字符集中的对应字符表示每个整数。
填充: 如果输入的二进制数据长度不是 3 的倍数,那么最后会剩下一或两个字节。为了保持 Base64 编码后的数据长度为 4 的倍数,会使用
=
字符进行填充。
解码后发现,uname
字段的值,其实就是 Base64 编码后的用户名,既然如此,接下来,我们就开始尝试对 Cookie 进行加解密注入(Base64 只能算是一种编码,并不算加密,不过流程一致)。
打开浏览器的 ”开发者工具“,然后输入下面的内容,修改我们的 Cookie 并刷新页面,看看页面变化:
document.cookie='uname=' + btoa('Blue17'); // btoa() 函数用于进行 base64 编码
可以看到,服务端成功接收了我们的 Cookie,并且回显出来了。虽然没能爆出数据库,但起码证明了,上述的方法可行。
接下来,开始我们针对 Cookie 进行注入点测试,Payload 如下(每次控制台执行后,都需要刷新页面,让浏览器重新携带我们修改后的 Cookie 向服务端进行请求):
测试 Payload 01: document.cookie='uname=' + btoa("1'"); 结果: 报错
既然能报错,就已经证明其存在 SQL 注入漏洞了。根据报错返回的信息(它直接爆出了部分的后端源码),我们可以推测其后端的 SQL 模板如下:
select * from users where cookie=('$_COOKIE["uname"]') LIMIT 0,1;
0x0202:第二阶段 — 加解密注入漏洞利用
加解密注入漏洞的利用流程和普通的 SQL 注入利用流程一致,只不过多了一步,需要将我们构造的 Payload 按照服务端的加密规则进行加密后再传递,仅此而已。
针对上面的 SQL 语句模板,笔者给出一个漏洞利用的示例,即,爆出服务器后端当前正在使用的数据库的名称:
攻击 Payload : document.cookie='uname=' + btoa("1') and updatexml(1,concat(0x7e,database(),0x7e),1)#");
至此,SQL 注入的加解密注入已讲解完毕。笔者将其归纳到了 ”常见注入点“ 系列,这个系列的目的就是帮助大家开阔眼界,看到那些经常容易被忽略的注入点。