YzmCMS-V5.4 后台Getshell

代码审计

漏洞文件:yzmphp\core\class\cache_file.class.php

  • 代码171-179行,使用了file_put_contents(),其中$file$contents可控
protected function _fileputcontents($file, $contents){
    if($this->config['mode'] == 1){
        $contents = serialize($contents);
    }else{
        $contents = "<?php\nreturn ".var_export($contents, true).";\n?>";
    }

    $filesize = file_put_contents($file, $contents, LOCK_EX);
    return $filesize ? $filesize : false;
}
  • 我们继续跟进_fileputcontents(),在同一文件代码62-75行调用了该方法,我们继续跟进set()

img

漏洞文件:yzmphp\core\function\global.func.php

  • global.func.php的1017-1021中的setcache()方法疑似调用了set()方法,并且$name, $data, $timeout均可控,我们跟进load_sys_class('cache_factory','',0);看看get_instance()->get_cache_instances()到底调用了哪个文件。

img

漏洞文件:\yzmphp\core\class\cache_factory.class.php

  • 很明显C('cache_type')决定了他调用哪个文件中的set()方法,我们跟进cache_type

img

  • 跟进发现在common\config\config.php做了定义,cache_type默认使用filemode存在两种模式,我们选择1-序列化看看或许可能读取缓存存在反序列化的可能。那么回头看他默认使用file也就是调用了cache_file.class.php所以我们的猜测没错。同时这里还是用了file_config这个参数,我们继续跟进setcache()方法

img

漏洞文件:\common\function\system.func.php

  • 这里$modelinfo是从数据库中得到所以可控,$filename指定了名称modelinfo或者modelinfo_all。我们继续跟进get_modelinfo()会发现都不传入参数,所以默认$typeall = 0,也就是说文件名称固定modelinfo

img

  • 我们再回到yzmphp\core\class\cache_file.class.php,发现文件名称和路径由_file()方法决定。而$id正是我们传入的。我们跟进_file()方法

img

  • 我们可以得知filename是由config[‘cache_dir’] 和传入的$idconfig['suffix']拼接而成。我们再看config['suffix']'cache_dir'是什么?

img

  • 我们在审计common\config\config.php时候已经发现这里定义了file_config,这样我们就完整知道缓存文件写在cache/chche_file/modelinfo.cache.php

img

  • 而且这里是模型的缓存,我们直接到后台写入一个php代码看看。

img

  • 需要访问前台让其生成新的缓存文件。我们打开:cache/chche_file/modelinfo.cache.php看看

img

  • 我们访问http://域名/cache/chche_file/modelinfo.cache.php看看,成功getshell
    img

后记

  • 如果mode选择的模式是2的话是无法getshell的,由于var_export()进行了转义,暂时没有找到方法,但是该cms默认的是选择2导致这个漏洞有点鸡肋。
本文总阅读量
× 文章目录
  1. 1. 代码审计
  2. 2. 后记