0x03-OWASPJuiceShop-Injection-DatabaseSchema

目录

小调整

Heroku 的部署方式有一些问题。第一,需要科学上网,那么需要 Burp Suite 抓包的时候就比较麻烦。第二,XXE的练习在 Heroku 上做不了。

那么就部署到本机吧。kali 是在虚拟机上,有必要的时候只需要回到上一个快照就可以了。

kali 是自带 10.20.1 版本 node 的,不需要另外安装。

在这里插入图片描述

但是在按照 From Source安装的时候碰到一些问题,启动的时候总是抛出这样的错误

在这里插入图片描述

最后是通过 Packaged Distributions 安装。这是下载编译好的包的地址

在这里插入图片描述

注意,下载对应的 node 版本的包文件。

在这里插入图片描述

解压之后按照流程 npm start 即可。浏览器访问 localhost:3000

今日目标

Database Schema.

在这里插入图片描述

可以学到什么?

因为同属一个注入漏洞的范畴,不再写漏洞的原理。需要了解 SQL 注入漏洞原理的小伙伴可以参看这个系列的第一篇文章

关于 Database Schema 这个挑战,可以学到如下要点:

  • 如何使用 union select 模糊测试目标 table 有多少列
  • 如何 union select 合并显示想要的数据
  • SQLite 及 MySQL 的 schema 概述

什么是 UNION ?

看一下 W3C 对于 UNION 操作的解释

在这里插入图片描述

UNION 可以用来合并两个及以上 SELECT 表达式的结果,一起展示。

三个小要求:

  • 每个在 UNION 操作符中的 SELECT 表达式必须有相同的列数
  • 选择的每一列数据类型必须一致 (文档中居然用的 similar,相似,有点不解,后期会查询补正)
  • 选择的每一列数据的顺序必须一致

这里不举例了,实例参见 W3C 对于 UNION 操作的解释

如何使用带有空格的请求头?

首先用 Burp 截取一下请求。可以看到是一个 GET 请求。

在这里插入图片描述

那么如果想在参数 q 后面放入一段恶意的 SQL 请求,如

test')) UNION SELECT * FROM TEST -- 

该怎么做呢?

要做的是在使用空格的地方输入加号 +,才能使恶意代码正常执行。其他的例如直接输入空格,或者使用 %20 URL encode,都是不行的。大家可以尝试一下。

如何使用 UNION 模糊测试数据表有多少列?

首先,找到可以注入的点。然后,构造恶意 SQL 表达式,使用如下代码尝试获取一张表的列数

UNION SELECT [1,[2,[3,[4]]]] FROM table_name

当然不要忘了之前讲过的,在空格的地方输入加号 +

在本次练习中的测试方式如下

在这里插入图片描述

只要看到右边的报错,说明列数不正确。

那么就继续增加选择的列数,直到没有错误返回,说明列数正确

在这里插入图片描述

SQLite 及 SQL 的 schema

这是 Wiki 对于什么是 Database Schema 的解释。

这翻译过来太多术语,还需要大家自行阅读理解。简单来说,通过查看 schema,可以了解一个数据库的数据是如何组织的,以及很多其他诸如权限等的重要敏感信息。

这里 SQLite System Schema 有获取 SQLite 数据库Schema 的方式。

这里 MySQL System Schema 有获取 MySQL 数据库 Schema 的方式。

关于 Schema,后面会用整篇的篇幅来讲一下 MySQL 的 Schema,在渗透测试中十分重要。

如何利用这个漏洞?

这个练习中,如何知道是这个搜索请求有漏洞并不重要,重要的是明白背后的原理。这个漏洞在应用最上方的搜索栏,这个 URL 中的参数 q 可以被注入。

在这里插入图片描述

记住我们的目标是,导出数据库所有的 Schema。

用 Burp 拦截请求,转到 Repeater。随意插入一端恶意代码,服务端报错。

在这里插入图片描述

可以肯定这个 q 参数可以被注入。

可以看到后台的 SQL 请求是这样的:

SELECT * FROM Products WHERE ((name LIKE '%';%' OR description LIKE '%';%') AND deletedAt IS NULL) ORDER BY name

我会做的第一步,是构造一个语法 SQL 请求,注释掉第一个条件之后的部分,也就是 name LIKE 之后的部分。这个 SQL 请求是这样的:

# 这里的 asdf 随意,也可以为空
asdf')) -- 

执行之后服务端正常返回。

在这里插入图片描述

下一步,就是要确定 SQLite 的 Schema 在什么地方。

上文提到的这篇文章,给出了答案。

文中提到,所有的 SQLite 数据库都有一张系统表 SQLITE_MASTER,里面包含了表名和索引名。那么,只要导出这张表中的

在这里插入图片描述

另外,文中还提到了,SQLITE_MASTER 中的 sql 一切,包含了建表时的原始表达式。也意味着,只要获取到 sql 列的内容,就可以完整复制整个数据库。

在这里插入图片描述

确定了 Schema 就在 SQLITE_MASTER 表中,那么就可以使用 UNION 先模糊测试一下该表有多少列。参照本文之前的方法,可以看到该表有 9 列。

在这里插入图片描述

因为其中一列为 sql,所以,最终的 SQL 请求为:

# sql 放在任意位置都可以
')) UNION SELECT sql,2,3,4,5,6,7,8,9 FROM SQL_MASTER -- 

数据库 Schema 导出完成。

在这里插入图片描述

SQLite 验证

实践中学习是最好的方式。在本地 SQLite3 中测试一下文中的说法是否正确。

这里有 SQLite 数据库的操作文档

创建一个测试数据库。

在这里插入图片描述

创建一张表。

在这里插入图片描述

使用 .schema 查看 sqlite_master 表,可以看到 sql 列。

在这里插入图片描述

查看 sql 列的内容,就是 COMPANY 表的建表语句。

在这里插入图片描述

再创建一张 COMPANY_2 表,此时 sql 列就会包含两张表的建表语句,也就印证了,只要获取到 sql 列的内容,就可以复制整个数据库结构。

在这里插入图片描述


参考链接: