Bonitasoft Platform 越权RCE(CVE-2022-25237)分析
漏洞分析
权限绕过
该漏洞的原理是由于权限绕过,导致攻击者可以未授权通过api端口上传恶意文件,从而命令执行。
在bonita\BonitaCommunity-2021.2-u0\server\webapps\bonita\WEB-INF\web.xml
配置文件中,自定义了filter,并且对参数excludePatterns进行了赋值。
有两个Filter类RestAPIAuthorizationFilter
、TokenValidatorFilter
中的参数excludePattern都被指定为i18ntranslation
这两个类都继承了AbstractAuthorizationFilter
类,来看一下对应的dofilter方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
MultiReadHttpServletRequest httpRequest = new MultiReadHttpServletRequest((HttpServletRequest)request);
HttpServletResponse httpResponse = (HttpServletResponse)response;
String requestURL = httpRequest.getRequestURI();
if (this.sessionIsNotNeeded(requestURL, this.excludePatterns)) {
chain.doFilter(httpRequest, httpResponse);
} else if (this.checkValidCondition(httpRequest, httpResponse)) {
chain.doFilter(httpRequest, httpResponse);
}
}
这里如果通过了sessionIsNotNeeded()
方法的检查,则将继续应用程序流程。
protected boolean sessionIsNotNeeded(String requestURL, String excludePatterns) {
boolean isMatched = false;
if (excludePatterns != null) {
String[] patterns = excludePatterns.split(",");
int i = 0;
for(int size = patterns.length; i < size; ++i) {
if (requestURL.contains(patterns[i])) {
isMatched = true;
break;
}
}
}
return isMatched;
}
如果传入的url中,包含excludePatterns的值,则返回true。而在web.xml中对RestAPIAuthorizationFilter和TokenValidatorFilter过滤器的excludePatterns参数赋值为i18ntranslation。
则URl包含/i18ntranslation/../
或;i18ntranslation
就可以绕过权限认证。
因为 /API/*
路由对应了 RestAPIAuthorizationFilter
,因此可以选择 /API/*;i18ntranslation
来绕过。
如下所示,sessionIsNotNeeded函数返回true
RCE
为实现远程命令执行,思路是上传恶意api接口,上传接口在web.xml中也定义了,为/API/pageUpload
跟进到org.bonitasoft.console.common.server.servlet.PageUploadServlet#getPermissions()
这里需要session,所以我们只需要一个普通用户来获取session,然后再通过i18ntranslation
绕过鉴权即可。最后将上传的zip的内容解析为API。
所以我们可以通过/API/pageUpload;i18ntranslation
来上传恶意API。
EXP:https://github.com/RhinoSecurityLabs/CVEs/blob/master/CVE-2022-25237/CVE-2022-25237.py
漏洞复现
创建普通用户poc/poc
通过EXP执行whomai命令
EXP分析:
-
使用install/install默认用户登录,成功则打印输出
Found default creds: install:install
,并且记录session -
然后使用自己传入的普通用户的user/passwd登录,并且记录session
-
upload_api_extension()上传恶意接口,并返回临时路径
-
activate_api_extension()通过临时路径获取id
-
delete_api_extension()在命令执行结束后,通过id删除恶意API
-
run_cmd()执行命令