首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

ECShop 注入&命令执行

ECshop 漏洞分析

0x01 前言

这两天出来一个ECshop的全版本RCE漏洞。先感慨一下,自己怎么这么菜,当时审计的时候没发现。最近事情又多,又开始懒了,所以这里补一下这个坑。

漏洞环境

ECshop_v2.7.3

nginx

php

0x02 分析

漏洞的触发点在于ECShop系统的user.php文件中,display函数的参数可控,可以配合注入可达到远程代码执行的效果。

由于是可以不登陆的前台RCE,所以这个漏洞危害还是很高的感觉,利用成本感觉也相当的低。所以分析的时候分两部分,第一部分是SQL注入分析,第二部分是RCE分析。

SQL注入

首先漏洞的触发点在user.php文件中的Referer字段里,我们截取部分相关代码看一下。第8行中的$back_act变量从server数组中的Referer字段获取数据,众所周知,Referer字段是可控的。然后代码中的第20行assign方法处理$back_act变量的值。第21行display方法处理user_passport.dwr

跟进一下assign方法,这个函数位置在/includes/cls_template.php文件中,我们截取部分相关代码,从代码中来看assign方法的作用是把可控变量传递给模版函数。

我们继续跟进一下display方法,该方法出现在/includes/cls_template.php文件中,截取部分相关代码。这里的display方法的作用应该是将模版内容展现在页面上。

而我们刚刚user.php中的代码是这样的。

所以这里display方法的使用就是读取user_passport.dwt文件的内容,然后解析变量展示为html,并且在第18行中交由_echash进行分割处理,得到的$k变量的值交由insert_mod方法进行处理。这里实际上insert_mod方法中的$val是可控的。我们跟进一下insert_mod方法。

该方法出现在/includes/cls_template.php文件中,截取部分相关代码。这个insert_mod方法在第三行以字符分割传入的内容,第四行反序列化传输入的$para,然后第五行通过字符串拼接的方式动态调用函数,最后在第7行返回调用函数处理$para变量的结果。

所以这里insert_mod方法里的函数与参数均可以被控制,我们知道注入点在/includes/lib_insert.php中的insert_ads方法,我们看一下相关代码。

这里很明显第21行第22行$arr[‘id’]\$arr[‘num’]存在SQL注入。我们来验证一下漏洞。我们看一下正常的登陆过程中的序列化字符串

然后我们看看我们的sql注入的payload

远程代码执行

漏洞触发流程还是通过user.php文件中的Referer字段传递参数,然后通过display方法处理user_passport.dwr。跟进display方法,该方法在/includes/cls_template.php文件中,这次的触发点是在第16行的fetch方法。

跟进fetch方法,相关代码/includes/cls_template.php文件。这里第20行_eval函数引起了我的主意。跟进一下_eval函数。

_eval函数出现在/includes/cls_template.php文件,我们看看相关代码,eval函数里的可控,那么就会造成RCE的问题了。

所以这里需要找一下哪里调用了这个fetch方法,回过头来,我们想想,我们的SQL注入通过动态函数调用,找到存在注入点insert_ads的函数。那么我们在找找这个函数,我们发现这个方法也存在fetch方法的调用,相关代码出现在/includes/lib_insert.php文件中。

我们看到第7行有这样一样代码,

跟进一下$position_style,该变量的取值过程也在/includes/lib_insert.php文件中写好了。该$position_style变量是从数据库中获取数据,假设这个字段可控,那么就会有RCE问题产生了。

这里我们就需要配合刚刚说的SQL注入漏洞。我们知道注入点有两处,一个是$arr[‘id’],另一个是$[‘num’]$arr[‘id’]的位置在and后,可以构造union联合查询。而$[‘num’]位置在order by后面,所以这里可能没办法使用,我们可以截断它。

这里针对$row[‘position_id’]做了判断,所以首先我们需要绕过这里判断。

这里我们可以在id处传入这里的作用就是闭合前面的单引号,然后配合num的值注释掉。

在数据库里运行之后

这里我们前面分析过,我们可控的字段是$row[position_style],因此这里需要将payload的位置填写在$row[position_style]

这里我们在回过头来看看fetch方法,相关代码/includes/cls_template.php文件。主要是查看是否有做一些过滤。我们看到第20行调用fetch_str函数处理传入的数据,跟进fetch_str函数。

该函数出现在/includes/cls_template.php文件中,截取相关代码,关键代码在第13行

这个函数处理之后最终会return回一个数据,而这部代码主要的作用是假如,那么经过这行代码处理后就是返回的值。

这里继续跟进一下select函数,该函数位置也在/includes/cls_template.php文件中。我们看到第21行,出现的时候,会调用get_val函数进行处理。

跟进get_val函数,该函数位置也在/includes/cls_template.php文件中。代码第14行当我们的\$val参数没有会在第26行调用make_var函数进行处理。

跟进一下make_var函数,该函数位置也在/includes/cls_template.php文件中。这里我们的$val变量最后处理的结果实际上是个字符串。

所以这里我们下个断点看看。

这里的对应的值是

因此这里实际上,我们需要闭合这个单引号和反括号,逃逸出来然后执行我们想执行的东西。

最后会在根目录下生成一个马。

0x03 修复方式

我们可以看到最新版在$arr[‘num’]\$arr[‘id’]中加入了intval,强制类型转换来修复。

0x04 思考

PHP下这种模板引起的RCE好像不少见了,seacms的那个好像也是因为这个引起的,但是吧,这个问题为啥自己没审计到呢,归根到底还是太菜了。

0x05 参考文章

ECShop全系列版本远程代码执行高危漏洞分析

ecshop2.x代码执行

新年快乐

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190125G0AS5Q00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券