前言:本人刚接触代码审计不久,此系列主要为记录自己的练习成果,同时也希望尽可能地分享一些东西给和我一样正在学习代码审计或者漏洞挖掘的师傅。
本次是拿niushop开源电商系统1.2.1作为靶机来练手的,该系统也是非常经典的渗透测试靶机,已经公开出多个sql注入,xss,逻辑漏洞等漏洞。不过,我这次通过代码审计挖出了一个rce漏洞,目前在网上是找不到公开记录的,应该算是个0day,不过因为系统版本太老了也不准备上交平台了,而且原创性也不够,因为是thinkphp的组件漏洞。所以,通过这种方式公开出来,也算是一种证明吧。
正题:
漏洞介绍:NiuShop商城系统是一款免费的开源商城系统,支持多商户、多平台、多功能的电商解决方案。NiuShop商城系统提供了海量的促销功能模块,如直播带货、拼团、优惠券、积分等,帮助商家提升销量和用户粘性。该系统1.2.1及以下版本存在rce(远程代码执行漏洞),攻击者可利用该漏洞执行恶意代码获取服务器权限。
思路:在这次代码审计中,我的思路大概如下:通过寻找系统的版本号来在网上寻找系统的开发组件,发现使用的是thinkphpv5来开发的。所以,自然地去寻找thinkphpv5的公开漏洞,然后利用poc进行测试,同时对系统的源代码进行审计,看看是否有对thinkphp框架进行改写来修复漏洞。进过多次黑白盒结合的测试后,发现了该漏洞。
漏洞复现:
- 漏洞成因介绍:
该漏洞的成因是由于niushop采用了thinkphpv5框架进行开发,而thinkphpv5存在多处rce漏洞。由于在开发过程中配置不当,开启了thinkphp的debug模式,导致出现rce漏洞。
- thinkphp远程代码执行漏洞介绍
漏洞简介:
ThinkPHP5.0在核心代码中实现了表单请求类型伪装的功能,该功能利用$_POST['_method']变量来传递真实的请求方法,当攻击者设置$_POST['_method']=__construct时,Request类的method方法便会将该类的变量进行覆盖,攻击者利用该方式将filter变量覆盖为system等函数名,当内部进行参数过滤时便会进行执行任意命令。
漏洞分析:
1.method方法
在method方法中,默认$method=false和config配置文件的伪装变量 'var_method'='_methd'会跳到第二个if代码块$_POST['_method']将被赋值给 this->method,中间并没有做过滤,
然后是一个动态调用的结构,$_POST的值直接被传入到动态函数$_this->{$_POST['_method']}()中
我们发现可以method的传入参数是可控的,所以我们就要思考如何通过method方法来调用其他的函数。所以,就要使用到我们的关键函数:__construct()
__construct():该函数通过 property_exists()判断传入的参数是否为该类中存在的属性,如果是,则赋值
函数源码:
所以,我们目前的思路是通过post传参控制 method方法调用__construct()方法可以改变类中属性的值。
既然可以通过 method()方法能调用Request类中任意方法,那我们要找到Request类中存在的敏感函数。所以,我们在filterValue()方法找到了call_user_func()函数。
主要参数为:$value, $fileters
当 $fileter为一个回调函数时,将通过 call_user_func()调用
在寻找一下 filterValue()的调用情况,在 input()方法中
函数逻辑:在满足条件的情况下 input()会调用 filterValue()。参数$data, $filter传入input()再传入filterValue()。参数$filter在其中会经过Filter处理, $data无论是否为数组都会调用filterValue()方法
Filter相关代码:
默认传入的 $filter为空'',将会跳到else语句块,此时 $filter将会为$this->filter,即为类属性的值,我们便可以通过 __construct()来控制$this->filter的值,,input()将被 param()调用,后面发现其实是param()中的get()或toute()传参调用。$mergeParam默认为false,那么 empty($this->mergeParam)将会为true,将会进入第一个 if 代码块。我们关注传入 input()的参数是 $this->param, $filter。$filter默认为空,没有经过特殊处理,$this->param将由以下数据一起合并成数组:
原来的 $this->param
$this->get(false)
$vars将会为空数组,不考虑
this->route(false)
Param方法:
Get方法:
get()将会调用 input()方法,关注传入input()方法的参数$filter,$this->get。其中$filter为空''无变化。$this->get可以通过 __contruct控制
route()方法:
传入input()的值主要由$_this->route决定,我们也可以通过 __contruct控制
流程图:
- 漏洞复现:
在本地通过phpstudy部署niushop v1.2.1
打开主页面:http://local.niushop.com/index.php
利用hackbar传参
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)