Java xxe oob 读取多行文件失败的原因
一. java xxe oob 支持的协议
根据 src.zip!\java\net\URL.java
中的以下代码
if (protocol.equalsIgnoreCase(GOPHER) &&
packagePrefix.equals(JDK_PACKAGE_PREFIX) &&
!enableGopher) {
continue;
}
try {
String clsName = packagePrefix + "." + protocol +
".Handler";
Class cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
if (cls != null) {
handler =
(URLStreamHandler)cls.newInstance();
}
} catch (Exception e) {
// any number of exceptions can get thrown here
}
可以看出来支持的几种协议都在 rt.jar!\sun\net\www\protocol
目录下,通过反射调用每个协议目录下的 Handler
来实例化。
所以寻找 sun.net.www.protocol
包下有Handler.java
文件的
即可定位支持的协议主要有以下 8 种(Oracle JDK 1.7.0_75):
file
ftp
gopher
http
https
jar
mailto
netdoc
但在 src.zip!\java\net\URL.java
中,可以发现 gopher
协议默认从系统环境变量
中读取 jdk.net.registerGopherProtocol
来判断是否启用 gopher
协议的支持。
而默认取出的值为 null
,是不支持启用 gopher
协议的。
private static final String GOPHER = "gopher";
private static final String ENABLE_GOPHER_PROP = "jdk.net.registerGopherProtocol";
private static final boolean enableGopher = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
String prop = System.getProperty(ENABLE_GOPHER_PROP);
return prop == null ? false :
(prop.equalsIgnoreCase("false") ? false : true);
}
});
引用 此文章 的一段描述来讲:
其中从2012年9月开始,Oracle JDK版本中删除了对gopher方案的支持,后来又支持的版本是 Oracle JDK 1.7 update 7 和 Oracle JDK 1.6 update 35
像本地的 Oracle JDK 1.8.0_181 版本,原生就没有gopher
协议的相关代码,天生就不支持 gopher
协议。
在仅有的几个支持的协议中,支持oob的协议,除了比较低版本JDK默认支持并且启用gopher
协议外,可以外连的协议只有 http/https
和 ftp
协议。
二. 特殊字符
xml 相关的特殊字符
参考 该文章 ,如果读取的文件中含有 xml
相关的特殊字符
%
&
同时包含 " 和 '
程序在拼接结果时处理 xml
会报错
FTP协议相关的特殊字符
以下字符可能会破坏FTP指令,导致发送字符串被截断或者失败
/
?
\n
HTTP协议相关的特殊字符
以下字符可能会导致HTTP请求无法发送或者发送数据被截断,因为 \r\n 的原因,导致无法 通过http 协议接受多行文件
\n
\r
#
三. 源码层面解析
HTTP 协议
jdk1.7.0_75\jre\lib\rt.jar!\sun\net\www\http\HttpClient.class
:
public String getURLFile() throws IOException {
...... 省略
if (var1.indexOf(10) == -1) {
return var1;
} else {
throw new MalformedURLException("Illegal character in URL");
}
}
一旦发送的 URL 中发现 chr(10)
即 \n
,就会抛出 Illegal character in URL
,所以导致使用 HTTP 协议不能发送多行的文本。
jdk1.8.0_181\jre\lib\rt.jar!\sun\net\www\protocol\http\HttpURLConnection.class
,不一样的 JDK 版本也有类似代码:
private static URL checkURL(URL var0) throws IOException {
if (var0 != null && var0.toExternalForm().indexOf(10) > -1) {
throw new MalformedURLException("Illegal character in URL");
} else {
return var0;
}
}
FTP 协议
jdk1.8.0_181\jre\lib\rt.jar!\sun\net\ftp\impl\FtpClient.class
中,对于发送命令中遇到 \n
字符时 FTP 会报错Illegal FTP command
,导致 FTP 发送多行文本会失败:
private boolean issueCommand(String var1) throws IOException, FtpProtocolException {
{
...... 省略
if (var1.indexOf(10) != -1) {
FtpProtocolException var2 = new FtpProtocolException("Illegal FTP command");
var2.initCause(new IllegalArgumentException("Illegal carriage return"));
throw var2;
} else {
this.sendServer(var1 + "\r\n");
return this.readReply();
}
}
}
已经 有人研究过 关于Java xxe oob 使用 FTP 协议读取多行文本失败的 JDK 版本:
使用ftp 进行 oob 时,对版本有限制, <7u141 和 <8u162 才可以读取整个文件
四. xxe ftp oob server
一条龙利用方法:
评论