0x00 前言
回炉重造,这一次骨头都给他啃碎。
0x01 NiuShop 相关
印象中这款CMS有个任意下载getshell的漏洞,找了一下网上老版本,扒到了v2.1版本。
环境:
php 7.3.4
mysql 5.7.26
apache 2.4.39
0x02 代码分析
入口点:
TP框架二次开发,所以可以简单看入口就行,访问路由跟原生没啥区别,回头再写一篇TP路由相关的做记录。
访问方式:
1 | index.php?s=/controller/func |
类似这种控制器/方法。具体可以去看**/application/route.php** 中的代码。
漏洞分析:
这篇先简单提一嘴,TP的目录结构,像对外访问目录,应用目录,扩展类库目录等,看源码的具体使用情况,就拿这套来说,用到了extend中的upgrade才造成了该漏洞,在审计的时候需要注意看具体的功能点的调用。
那么我这里就直接去看应用目录的控制器,看到前台用户界面和后台admin界面,都创建了自定义类BaseController来做鉴权,如果其他控制器继承了BaseController,就不能直接访问到该控制器,如果没有继承BaseController,那么就可以直接访问到,这里先不去管登录鉴权能不能绕过,粗略的看一遍所有控制器。
然后在寻找的过程中看到控制器application/admin/controller/Upgradeonline.php继承的权限是Controller基类,而不是自定义的鉴权类BaseController,所以这里是可以直接未授权访问的。看到里面的方法都是public,可以直接调用,算是一个未授权。
在第31-37行的downloadPatchZip方法中,可以看到是一个实现下载的方法,传入的参数可控。继续去跟调用的方法实例化UpgradeExtend类调用的方法update_file_download。
CTRL+B来到data/extend/upgrade/Upgrade.php 中,重点看到第123行和第136行,第123行if语句判断数据长度是否大于500,第136行file_put_contents创建文件写入数据到$download_zip_path。过程中没有处理文件后缀,也没有删除下载的文件,没有改变文件名称,所以原样落地。
所以我们可以构造一个数据长度大于500的文件,让他下载,最后这里调的时候遇到点小问题,剩下的就是访问写死的路径马就可以连上了。测试一下:
1 | POST /index.php?s=/admin/upgradeonline/downloadPatchZip HTTP/1.1 |
用D盾尝试监控目录变化:
连接成功。