目录
小调整
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 中测试一下文中的说法是否正确。
创建一个测试数据库。
创建一张表。
使用 .schema
查看 sqlite_master
表,可以看到 sql
列。
查看 sql
列的内容,就是 COMPANY
表的建表语句。
再创建一张 COMPANY_2
表,此时 sql
列就会包含两张表的建表语句,也就印证了,只要获取到 sql
列的内容,就可以复制整个数据库结构。