【Java 代码审计入门-04】SSRF 漏洞原理与实际案例介绍
字数 1263 2025-08-25 22:59:03
Java代码审计入门:SSRF漏洞原理与实际案例
0x00 前言
本教程是Java代码审计入门系列的第四篇,专注于SSRF(Server-Side Request Forgery)漏洞的原理分析和实际案例。SSRF是OWASP TOP 10中的常见漏洞,攻击者通过构造恶意请求,利用服务端发起非预期的网络请求,通常用于探测或攻击内网服务。
0x01 环境准备
测试源码可从GitHub获取:
https://github.com/cn-panda/JavaCodeAudit
项目结构是一个简单模拟HTTP请求的实现,可用于SSRF漏洞测试。
0x02 SSRF漏洞原理
基本概念
SSRF是攻击者构造恶意payload传给服务端,服务端执行后造成的漏洞。Java中网络请求支持多种协议:
- http
- https
- file
- ftp
- mailto
- jar
- netdoc
相比PHP,Java中的SSRF利用有一定局限性,常见利用方式:
- 使用http/https协议探测端口、暴力穷举
- 使用file协议读取/下载任意文件
Java网络请求流程
典型的有漏洞代码示例:
String url = request.getParameter("url");
String htmlContent;
try {
URL u = new URL(url);
URLConnection urlConnection = u.openConnection();
HttpURLConnection httpUrl = (HttpURLConnection)urlConnection;
BufferedReader base = new BufferedReader(new InputStreamReader(httpUrl.getInputStream(), "UTF-8"));
StringBuffer html = new StringBuffer();
while ((htmlContent = base.readLine()) != null) {
html.append(htmlContent);
}
base.close();
print.println("<b>端口探测</b></br>");
print.println("<b>url:" + url + "</b></br>");
print.println(html.toString());
print.flush();
} catch (Exception e) {
e.printStackTrace();
print.println("ERROR!");
print.flush();
}
代码解析:
URL对象用openConnection()打开连接,获得URLConnection类对象- 用
getInputStream()获取字节流 InputStreamReader()将字节流转化成字符流BufferedReader()将字符流以缓存形式输出,快速获取网络数据流- 最终输出到浏览器
0x03 SSRF漏洞利用
1. 端口探测
测试环境:
- 本机:127.0.0.1 (Java+Tomcat)
- 虚拟机:192.168.159.134 (PHP+Apache)
攻击场景:
假设外网可以访问本机地址,但不能直接访问虚拟机地址。利用本机的SSRF漏洞探测虚拟机开放的端口。
结果分析:
- 如果端口开放http/https服务,返回正常内容
- 如果端口未开放http/https服务,返回错误信息
通过不同的返回结果,可以判断目标端口是否开放。
2. 任意文件读取/下载
修改上述代码,移除HttpURLConnection的强制转换:
String url = request.getParameter("url");
String htmlContent;
try {
URL u = new URL(url);
URLConnection urlConnection = u.openConnection();
BufferedReader base = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer html = new StringBuffer();
while ((htmlContent = base.readLine()) != null) {
html.append(htmlContent);
}
base.close();
print.println(html.toString());
print.flush();
} catch (Exception e) {
e.printStackTrace();
print.println("ERROR!");
print.flush();
}
利用方式:
使用file协议读取任意文件,例如:
file:///etc/passwd
0x04 实际案例
CVE-2019-9827
参考链接:
0x05 防御措施
-
输入验证:
- 对用户输入的URL进行严格校验
- 使用白名单机制限制允许的协议和域名
-
网络层防护:
- 禁止访问内网IP段
- 限制请求的目标端口
-
代码层防护:
- 避免直接使用用户输入构造URL
- 使用安全的网络请求库
-
环境加固:
- 配置Java安全策略
- 限制应用程序的网络访问权限
0x06 总结
SSRF漏洞在Java应用中危害严重,特别是能够访问内网资源的应用。审计时应重点关注:
- 直接使用用户输入构造URL的地方
- 网络请求是否有限制和过滤
- 是否使用了不安全的协议(如file)
- 是否有对内网地址的访问控制
通过本教程的学习,您应该掌握了Java中SSRF漏洞的基本原理、利用方式和防御措施,能够在代码审计中识别此类漏洞。