2019-03-19 14:48:2222734人阅读
前言
PHPSHE商城系统是一套开源的B2C商城系统,可以快速让用户建立独立个性化的网上商店,为用户提供了一个低成本、高效率的网上商城建设方案。2018年9月,PHPSHE更新到了1.7版本,是官方网站目前提供的最新版。近日,笔者在对PHPSHE1.7版本最新版进行代码审计时,发现了两处无需登录的高危漏洞分别为XXE漏洞(CVE-2019-9761)和SQL注入漏洞(CVE-2019-9762),攻击者可获取网站任意数据、读取系统中的文件等。
利用条件
PHPSHE 1.7版本
无需登录
XXE漏洞(libxml <2.9.0)
漏洞分析
3.1 XXE漏洞分析(CVE-2019-9761)
漏洞位于include/plugin/payment/wechat/notify_url.php 第8行,调用了wechat_getxml()函数。
而wechat_getxml定义在hook/wechat.hook.php 35行,此处直接返回了pe_getxml()函数的返回值。
跟踪到include/function/global.func.php 909行pe_getxml()函数定义处,先是获取了php://input输入的内容赋值给$xml,随后直接调用simplexml_load_string()函数解析$xml,没有做过滤也没有禁用外部实体,存在XXE漏洞。
此处没有回显,因此可以采用盲注的方式读取任意文件,POC如下:
test.dtd的内容如下:
可以通过DNS log的方式获取到读取到的任意文件,同样也可以进行内网探测和扫描。
3.2 无限制SQL注入分析(CVE-2019-9762)
我们先分析一下PHPSHE的输入和安全函数。几乎所有入口页面都会包含common.php,在37-49行对GPC、Session变量进行注册,但是调用extract()函数时会对注册的变量名称加上前缀,例$_GET['id']会注册为$_g_id,前缀和数组键名之见会自动加一个下换线。
PHPSHE中防SQL注入的函数为pe_dbhold(),定义在include/function/global.func.php中;pe_dbhold()会对字符串或者数组调用addslashes()转义,如果想要突破安全函数常见的有如下几种情况:1. 不需要单引号的注入点 2. 数组的键名带入SQL语句中 3. 宽字节等可吃掉反斜线。
回归到漏洞本身,入口文件位于include/plugin/payment/alipay/pay.php,$_GET['id']经过pe_dbhold()函数处理后赋值给$order_id,随后$order_id被带入order_table()函数。
order_table函数定义在hook/order.hook.php,如果$id包含下划线,则将order_和下划线之前的部分拼接返回,如果不包含下划线则直接返回order,这里函数的返回值部分可控。
再跟进到SQL查询函数pe_select(),函数定义位于include/class/db.class.php,可以看到order_table()函数的返回值是作为表名拼接到SQL语句中,而表名拼接的地方是没有单引号的
此时表名部分可控,为了使SQL语句不产生语法错误,在数据库找了一圈发现只有pe_order_pay表符合表名规则,那么可以构造参数id为:
对应在数据库中执行的语句为
此处是由于SQL语句中表名可控导致的SQL注入,一部分原因是order_table()获取表名不当导致,代码中搜索了一下类似用法,存在多处可利用点。
在多处利用点中,include/plugin/payment/alipay/pay.php入口的注入漏洞有回显位置,POC如下:
修复建议
笔者已经将漏洞提交给代码作者,目前官方暂时没有补丁放出。暂时的缓解措施如下:
对于XXE漏洞,可以升级libxml2库至2.9.0或以上版本,或者在 pe_getxml()函数中加上libxml_disable_entity_loader(true);
对于SQL注入漏洞,可以在order_table()函数中限制$id只为数字、字母和下划线。
参考内容https://gitee.com/koyshe/phpshe/issues/ITC0C
本文来自百度安全SiemPent Team,转载需注明出处及本文链接