其实之前也写过一篇java审计之XXE,虽然PHP与java XXE都大同小异但是本篇会更详细些,加入了PHP的归纳一些知识点和有关的一些函数,对之前的文章进行了整理与更新,从基础概念原理->利用->审计->防御。
XXE(XML外部实体注入、XML External Entity),在应用程序解析XML输入时,当允许引用外部实体时,可以构造恶意内容导致读取任意文件或SSRF、端口探测、DoS拒绝服务攻击、执行系统命令、攻击内部网站等。Java中的XXE支持sun.net.www.protocol里面的所有协议:http,https,file,ftp,mailto,jar,netdoc 。一般利用file协议读取文件、利用http协议探测内网,没有回显时可组合利用file协议和ftp协议来读取文件。
XML&DTD
XML(可扩展标记语言,EXtensible Markup Language ),是一种标记语言,用来传输和存储数据
DTD(文档类型定义,Document Type Definition )的作用是定义XML文档的合法构建模块。它使用一系列的合法元素来定义文档结构。
实体ENTITY
XML中的实体类型,一般有下面几种:字符实体,命名实体(或内部实体)、外部实体(包含分为:外部普通实体、外部参数实体)。除外部参数实体外,其他实体都以字符(&)开始以字符(;)结束。
DTD引用方式
a)DTD 内部声明
<!DOCTYPE 根元素 [元素声明]>
b)DTD 外部引用
<!DOCTYPE 根元素名称 SYSTEM “外部DTD的URI">
c)引用公共DTD
<!DOCTYPE 根元素名称 PUBLIC “DTD标识名" “公用DTD的URI">
0x1:字符实体
字符实体类似html的实体编码,形如a(十进制)或者a(十六进制)。
0x2:命名实体(内部实体)
内部实体又叫命名实体。命名实体可以说成是变量声明,命名实体只能生命在DTD或者XML文件开始部分(<!DOCTYPE>语句中)。
命名实体(或内部实体语法):
`<!ENTITY 实体名称 "实体的值">`
如:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root [ <!ENTITY x "First Param!"> <!ENTITY y "Second Param!"> ]> <root><x>&x;</x><y>&y;</y></root>
说明:
定义一个实体名称x 值为First Param!
&x; 引用实体x
知道以上语法后,可以使用名为foo的数据类型定义(DTD)构造如下请求:
request:
POST http://example.com/xml HTTP/1.1
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY bar "World">
]>
<foo>
Hello &bar;
</foo>
respone:
HTTP/1.0 200 OK Hello World
bar元素是单词“World”的别名 。看起来这样的内部实体似乎无害,但攻击者可以使用XML实体通过在实体内的实体内嵌入实体来导致拒绝服务攻击。通常被称为“ (Billion Laughs attack)十亿笑攻击 ”。某些XML解析器会自动限制它们可以使用的内存量。
如:
request:
POST http://example.com/xml HTTP/1.1
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY bar "World ">
<!ENTITY t1 "&bar;&bar;">
<!ENTITY t2 "&t1;&t1;&t1;&t1;">
<!ENTITY t3 "&t2;&t2;&t2;&t2;&t2;">
]>
<foo>
Hello &t3;
</foo>
response:
HTTP/1.0 200 OK
Hello World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World World
0x3):外部普通实体
外部实体用于加载外部文件的内容。(显示XXE攻击主要利用普通实体)
外部普通实体语法:
<!ENTITY 实体名称 SYSTEM "URI/URL"
如:
<!DOCTYPE foo [<!ELEMENT foo ANY> <!ENTITY xxe SYSTEM "file:///etc/passwd">]>