前言
看了先知YzmCMS 5.4 后台getshell的文章分析感觉该漏洞颇具学习价值,所以自已下载下来审计一波,学习学习其中的思路。
缓存文件Getshell
我们看看缓存文件的写入函数_fileputcontents
,文件位于yzmphp/core/class/cache_file.class.php
。
1 | protected function _fileputcontents($file, $contents){ |
这里我们可以看到只有config['mode']=1
进入序列化代码我们写入任意代码才有意义,否则在前面添加上<?php \nreturn
就算能够写入webshell也无法运行。
在common/config/config.php
配置文件中我们可以看mode默认是2。所以该漏洞比较鸡肋需要mode修改为1可以利用。这里我们手工把它修改为1.
我们继续看看哪里调用该方法,最终发现在本文件下的set
方法调用了该方法:
1 | public function set($id, $data, $cachelife = 0){ |
这里并没有什么特别的操作,这里主要看一下_file
是如何处理文件名的:
1 | protected function _file($id){ |
继续看一下_idtofilename
方法
1 | protected function _idtofilename($id){ |
config['suffix']
默认为.cache.php,所以最终的文件名为$id.cache.php
返回去看看哪里调用了set方法:
在yzmphp/core/function/global.func.php
的setcache
方法可以看到其调用该方法:
继续看看哪里调用setcache
方法来写入缓存。
调用倒是很多,但是实际可以利用点没几个。其中在文件commom/function/system.func.php
中可以利用:
1 | function get_config($key = ''){ |
setcache
的第二个参数是从数据库中config
表读取的,因此找到一个写入该表的接口,再使得get_config
函数被调用即可。所以我们的重点就在于找到写入点。
在文件application/admin/controller/system_manage.class.php
中就有一个可用的接口
1 | if(isset($_POST['dosubmit'])){ |
可以看到post过来的值被直接insert到了config
表(如果insert的第二个参数为true则会进行过滤),所以这个接口就可以用于写入代码。
漏洞复现
修改配置文件中的mode为1,然后再自定义配置处修改配置值为我们的一句话木马。
成功Getshell:
保存配置造成的Getshell
后台在修改配置的时候常常会把一些配置信息写入配置文件中,如果对输入过滤不够的严格就会容易造成Getshell。
我们这里看一下对写入配置过滤函数:
yzmphp/core/function/global.func.php
文件中safe_replace方法:
1 | function safe_replace($string) { |
过滤的比较严格把单引号也该过滤掉了正常情况我们无法闭合单引号是无法Getshell的。但问题代码出现在:
application/admin/common/function/function.php
d 的set_config方法中
1 | function set_config($config) { |
注意这里preg_replace函数中使用了${1}
这样的形式来指定上文匹配到的'
,虽然{}
被过滤了,但是$1
实际上是与${1}
等价的,因此我们通过这种方式闭合单引号,然后,
也没有被过滤,所以我们可以在键值对的后面插入别的代码,可惜的是>
是被过滤的,所以我们无法插入key => value
这样的形式来修改项。不过可以直接插入函数,像array(0=>1,func())
的形式中,func
是会被执行的,并且将返回值作为value成为array的一部分。
漏洞复现
系统设置->附加设置处
使用$1或者$2都可以充当'
的作用。使用base64进行编码绕过特殊字符的检测:
最终payload:
``mark.png$1,eval(base64_decode($1c3lzdGVtKCdlY2hvIDEyMycpOw==$1)),$1`
最终执行的语句为system('echo 123');
保存好刷新页面:
- 本文作者: EASY
- 本文链接: http://example.com/2020/11/22/yzmcms5-4后台Getshell分析/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!