DTD(Document Type Definition)即文档类型定义,用来为XML文档定义语义约束。

# <!--声明xml的版本号-->
<?xml version="1.0" ?>
# <!--定义此文档是note类型的文档-->
<!DOCTYPE note [
    <!ENTITY entity-name SYSTEM "URI/URL">
]>

# <!--文档元素-->
<note>
<head>Reminder</head>
<body>You are a good person</body>
</note>

代码审计

前端将$_post['xml']传入给变量$xml,由于后台没有对此变量进行安全判断就直接使用simplexml_load_string()函数进行xml解析,从而导致xxe漏洞。

$html='';
//考虑到目前很多版本里面libxml的版本都>=2.9.0了,所以这里添加了LIBXML_NOENT参数开启了外部实体解析
if(isset($_POST['submit']) and $_POST['xml'] != null){
    $xml = $_POST['xml'];
    // $xml =$test;
 $data=@simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOENT);
    if($data){
        $html.="<pre>{$data}</pre>";
    }else{
        $html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";    }
}
?>

因此可以构造恶意xml通过post请求提交给后台,以此实现xml外部实体注入,这里先构建简单的xml提交试试,页面成功回显“hello world”

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY test "hello world">
]>
<name>&test;</name>

成功回显