0x04-OWASPJuiceShop-Injection-XmasSpecial

目录

今日目标

Christmas Special. 正式进入 4 星俱乐部 😀

在这里插入图片描述

可以学到什么?

SQL 盲注

本篇的主题,是 SQL 盲注。先了解一下 SQL 盲注是什么,再学习如何进行模糊测试,最后获取到想要的数据。

什么是 SQL 盲注?

这个系列的前几篇,如果大家还记得的话,在我们构造 SQL 表达式去试探服务端的时候,服务端会直接将 SQL 数据库的错误返回给我们。我们可以清楚地看到后端使用的是什么数据库,我们构造的 SQL 语句哪里有问题,是语法有误?还是 UNION 的时候列数不对。

在这里插入图片描述

SQL 盲注,相反的就是服务端的错误处理是统一的页面,诸如最简单的,只给我们返回一个 500 Internal Server Error,无从知道后端数据库的任何信息。这样的情况下,做 SQL 注入仍然是可行的,只是困难一些。我们必须要构造一些 true or false 的问题去问数据库,根据数据库的返回结果,进一步判断下一步操作。

只要目标是可以被注入的,那么只要加以一定的耐心,仔细观察返回结果,以及一点点的运气,就可以完成盲注。

如何询问数据库?

基于返回内容

考虑有这样一种情形,我想要获取数据库中 user_id = 1 的用户的密码。由于前端做了错误的统一处理,我无法知道我注入的 SQL 语句执行成功与否。

虽然说错误是统一处理了,如果我的 SQL 执行出错,我将得不到任何有用的信息。那我要做的,就是构造能够正确执行的 SQL 即可。只要后端没有返回错误,说明我的 SQL 执行成功。

可以构造如下的 SQL 去探测数据库返回。

xyz' UNION SELECT CASE WHEN (user_id= '1' and SUBSTRING(user_password, 1, 1)  == CHAR(50)) THEN NULL ELSE 1/0 END FROM users--

拆解说明一下:

  • CASE 打开一个条件,如果条件为 true,返回 then 的内容,否则返回 else 的内容 CASE Function 文档
  • SUBSTRING 方法三个参数分别是 string, start_pos, len,取出来的子字符串包含 start_pos SUBSTRING Function 文档
  • CHAR(50) 是可打印字符 '2' 在 SQL 数据库中可以使用 print CHAR(50) 的方式打印 ASCII 字符 详见文档CHAR Function 手册
  • 如果截取的第一个字符等于字符 '2',那么什么都不执行 (null)一切正常,页面不会变动;反之,则执行 1/0,服务端报错

这就是基于返回内容的盲注操作方式。就像前面所说,盲注需要耐心,这个 SQL 表达式中,还需要我们猜测 user 表名。如果管理员使用了非默认列名,比如 id 一列叫 customer_id, password 一列叫 customer_pass,那么这个 SQL 照样都不成功。

原理才是最重要的。

基于返回时间

另一种情形,错误处理很绝,如果是 SQL 错误,一律什么返回都没有,那么就连执行正确或者错误都不知道。

这样的情况下可以采用另一种基于返回时间的方式。

原理是如果条件成立,执行某个操作一定的次数,这个次数要足够大,能让数据库处理上一定的时间,让我们可以感知到页面返回的时间差异。

看下面这个 SQL。

xyz’ UNION SELECT IF(SUBSTRING(user_password,1,1) = CHAR(50),BENCHMARK(5000000,ENCODE('MSG','by 5 seconds')),null) FROM users WHERE user_id = 1;

拆解说明一下:

这就是基于返回时间的盲注操作方式。

最后建议大家一定阅读一下 OWASP 和 Portswigger 关于 Blind SQL Injection 的文章,也别是 Portswigger 那篇,十分详细。

OWASP Blind SQL Injection

Portswigger Blind SQL Injection

这里还有一篇 SQL Injection Chettsheet

如何利用这个漏洞?

本次练习中,我们要完成的挑战是订购已经被删除的产品。也就是页面上怎么也不会出现的产品。

首先,顶部搜索产品的输入框是有注入漏洞的,也就是 URL 上的 q 参数。

在这里插入图片描述

其实这是个半盲注的练习,后端还是会返回错误信息的,而且很详细。

用 Burp Suite 拦截搜索请求,发送到 Repeater。测试一下常规的注入。

'--

后端报错

在这里插入图片描述

看右边红框中的 SQL 语句,有两个括号。那就构造一个 SQL 让后端返回所有的产品,这所有的产品,也就包括了被删除的商品。

尝试如下 SQL

'))--

后端返回了所有产品,包括有 deletedAt 属性的被删除产品。

在这里插入图片描述

已经找到被删除的商品了,下一步就是怎么添加到购物车。

用任何用户身份,登陆到应用。拦截一下添加正常商品到购物车的请求。将这个请求发送到 Repeater。

在这里插入图片描述

记住这里的 BasketId,后面做一次请求,修改 ProductId 为被删除的商品,即可完成添加。这里我的 BasketId1

找到 id10 的商品,该商品是被删除商品。

在这里插入图片描述

添加商品到购物车。修改 ProductId10,在再次发送请求即可。

在这里插入图片描述

这是被删除商品。

在这里插入图片描述

点击 Checkout 即可完成挑战。

在这里插入图片描述

在这里插入图片描述


参考链接: