Java FTP CRLF Injection
字数 1471 2025-08-29 08:31:47
Java FTP CRLF注入漏洞分析与利用
0x00 漏洞概述
Java在处理FTP协议流时存在CRLF(回车换行)注入漏洞,类似于Python urllib库的头注入漏洞(CVE-2016-5699)。攻击者可以利用此漏洞在多种场景下实施攻击,其中最经典的应用是欺骗防火墙规则。
0x01 FTP基础知识
FTP连接模式
FTP协议使用两种连接:
- 控制连接(Control Connection):默认端口21,用于传输命令
- 数据连接(Data Connection):默认端口20,用于实际数据传输
工作模式
-
主动模式(Active Mode):
- 客户端从任意端口N(≥1024)连接服务端21端口建立控制连接
- 客户端发送PORT指令,通知服务端自己监听的数据连接端口为N+1
- 服务端从20端口连接客户端的N+1端口建立数据连接
-
被动模式(Passive Mode):
- 客户端从任意端口N(≥1024)连接服务端21端口建立控制连接
- 客户端发送PASV指令,通知服务端采用被动模式
- 服务端从任意端口M(≥1024)监听数据连接
- 客户端从端口N+1连接服务端M端口建立数据连接
PORT指令格式
PORT h1,h2,h3,h4,p1,p2
- h1-h4:IP地址的4个8位组(如10,1,2,4表示10.1.2.4)
- p1,p2:端口号,计算方式为
port = p1 * 256 + p2
0x02 漏洞原理
防火墙欺骗机制
在主动模式下,当客户端前面有防火墙时:
- 防火墙会跟踪FTP连接状态
- 识别出客户端监听的端口是用于FTP数据连接
- 为此临时建立NAT规则,允许FTP服务端连接客户端指定端口
攻击思路
如果攻击者能控制受害客户端发送PORT指令并指定特定端口X:
- 防火墙会被欺骗建立NAT规则
- 受害客户端的X端口将对外开放
- 如果X端口运行着未加固的敏感服务(如Redis、Memcached等),可进一步攻击
0x03 技术细节
获取内网IP地址
攻击需要知道客户端内网IP,可通过以下方式获取:
- 诱使客户端连接攻击者的FTP服务器
- 客户端首先尝试被动模式(PASV)
- 服务端拒绝PASV命令(返回非229/227状态码)
- 客户端回退到主动模式,发送PORT/EPRT指令
- 指令中包含客户端内网IP
关键代码分析(Java FTP客户端实现):
private Socket openDataConnection(String var1) throws FtpProtocolException, IOException {
try {
return this.openPassiveDataConnection(var1);
} catch (FtpProtocolException var14) {
String var4 = var14.getMessage();
if (!var4.startsWith("PASV") && !var4.startsWith("EPSV")) {
throw var14;
} else if (this.proxy != null && this.proxy.type() == Type.SOCKS) {
throw new FtpProtocolException("Passive mode failed");
} else {
ServerSocket var3 = new ServerSocket(0, 1, this.server.getLocalAddress());
Socket var2;
try {
InetAddress var15 = var3.getInetAddress(); // 获取IP地址
if (var15.isAnyLocalAddress()) {
var15 = this.server.getLocalAddress();
}
String var5 = "EPRT |" + (var15 instanceof Inet6Address ? "2" : "1") + "|" +
var15.getHostAddress() + "|" + var3.getLocalPort() + "|"; // 拼接EPRT命令
// ...省略后续代码...
}
}
}
}
报文对齐问题
FTP是基于行的同步协议,每条命令必须独占一个报文。要实现注入需要:
- 使注入的PORT命令正好位于报文的起始位置
- 两种实现方式:
- 使用足够长的路径名填充,将PORT命令"挤"到下一个报文
- 控制FTP服务端的MTU设置较小,减少所需填充量
示例注入URL:
ftp://u:p@evil.com/foodir%0APORT%2010,1,1,1,5,57/z.txt
实际发送的命令序列:
USER u
PASS p
TYPE I
CWD foodir
PORT 10,1,1,1,5,57
0x04 攻击场景
- 防火墙规则欺骗:开放内网敏感服务端口
- 内网IP泄露:获取客户端内网IP地址
- 端口扫描:探测内网开放的服务
- 服务劫持:结合其他漏洞实现完整攻击链
0x05 防御措施
- 升级Java到最新版本
- 在网络边界限制FTP协议的使用
- 防火墙配置严格规则,不信任客户端PORT指令
- 对FTP流量进行深度检测,过滤异常命令
- 内网服务实施最小权限原则和网络隔离
0x06 参考链接
- 原文博客:http://blog.blindspotsecurity.com/
- Python urllib头注入漏洞:CVE-2016-5699
- FTP协议RFC文档:RFC 959