[红日安全]代码审计Day10 - 程序未恰当exit导致的问题
字数 992 2025-08-18 11:37:33

PHP代码审计:程序未恰当exit导致的安全问题

1. 问题概述

本文讨论的是一种常见但容易被忽视的安全问题:当程序检测到攻击或非法操作时,虽然进行了防御操作(如记录日志、重定向等),但由于没有立即终止程序执行,导致后续代码仍然被执行,从而产生安全漏洞。

2. 示例代码分析

2.1 基础示例

extract($_POST);

if (!is_numeric($pi) || !isset($pi)) {
    goAway(); // 记录错误并重定向到/error/页面
    // 这里缺少exit或die
}

assert($pi);

漏洞点分析:

  1. 使用extract($_POST)将POST数据注册为变量,存在变量覆盖风险
  2. $pi变量进行检查,但检查后未立即退出程序
  3. 后续的assert($pi)语句可被利用执行任意代码

攻击Payload:

POST数据:pi=phpinfo()

2.2 漏洞原理

虽然程序在检测到非法输入时会调用goAway()函数进行防御(记录日志并重定向),但由于没有立即退出,程序会继续执行到assert语句。由于$pi完全可控,导致远程代码执行漏洞。

3. 真实案例分析

3.1 FengCms 1.32 网站重装漏洞

漏洞代码逻辑:

// 检查是否已安装
if (file_exists('../upload/INSTALL')) {
    echo '<script>alert("请删除upload/INSTALL文件后再安装");</script>';
    // 缺少exit/die
}

// 继续执行安装流程

漏洞利用:

  1. 直接访问install/index.php
  2. 无视弹出的警告信息
  3. 继续完成重装流程

3.2 Simple-Log 1.6 网站重装漏洞

漏洞代码逻辑:

$setup = $_GET['step']; // 用户完全可控

// 安装完成后
if ($setup == 'setup_ok') {
    header('Location: ../'); // 仅重定向,未退出
    // 安装逻辑继续执行
}

漏洞利用:

POST /install/index.php?step=setup_ok

4. 漏洞修复方案

4.1 基础修复方法

在检测到非法操作后,应立即终止程序执行:

if (!is_numeric($pi) || !isset($pi)) {
    goAway();
    exit; // 或die
}

4.2 修复建议总结

  1. 在重定向后立即退出:

    header('Location: /error/');
    exit;
    
  2. 使用die()exit()函数确保程序终止

  3. 对于安装检查,应使用不可绕过的机制:

    if (file_exists('install.lock')) {
        die('系统已安装,如需重新安装请删除install.lock文件');
    }
    

5. CTF题目分析

5.1 题目代码

// index.php
include 'config.php';

function stophack($string) {
    // 过滤处理
    if($raw!=$string){
        error_log("Hacking attempt.");
        header('Location: /error/');
        // 缺少exit
    }
    return trim($string);
}

$conn = new mysqli($servername, $username, $password, $dbname);

if(isset($_GET['id'])) {
    $id = stophack($_GET['id']);
    $sql = "SELECT * FROM students WHERE id=$id";
    $result = $conn->query($sql);
    // 显示查询结果
}

5.2 漏洞点

  1. stophack()函数检测到攻击后仅重定向未退出
  2. SQL查询直接拼接用户输入的$id,存在SQL注入
  3. 过滤函数可被绕过(如大小写、编码等)

5.3 解题思路

  1. 利用未退出的漏洞,使过滤后的SQL注入payload仍能执行
  2. 使用时间盲注技术(题目提示flag为HRCTF{tim3_blind_Sql}
  3. 绕过过滤函数的限制

6. 总结

  1. 核心问题:安全检测后未立即终止程序是常见但危险的设计缺陷
  2. 影响范围:可导致RCE、SQL注入、网站重装等多种高危漏洞
  3. 修复关键:在所有安全检测点后添加exitdie
  4. 审计要点:检查所有安全控制点是否确保程序终止

7. 扩展思考

  1. 防御深度原则:多层防御,每层都应确保安全
  2. 失败安全原则:安全检查失败时应进入安全状态
  3. 最小意外原则:安全控制行为应明确且可预测
PHP代码审计:程序未恰当exit导致的安全问题 1. 问题概述 本文讨论的是一种常见但容易被忽视的安全问题:当程序检测到攻击或非法操作时,虽然进行了防御操作(如记录日志、重定向等),但由于没有立即终止程序执行,导致后续代码仍然被执行,从而产生安全漏洞。 2. 示例代码分析 2.1 基础示例 漏洞点分析: 使用 extract($_POST) 将POST数据注册为变量,存在变量覆盖风险 对 $pi 变量进行检查,但检查后未立即退出程序 后续的 assert($pi) 语句可被利用执行任意代码 攻击Payload: 2.2 漏洞原理 虽然程序在检测到非法输入时会调用 goAway() 函数进行防御(记录日志并重定向),但由于没有立即退出,程序会继续执行到 assert 语句。由于 $pi 完全可控,导致远程代码执行漏洞。 3. 真实案例分析 3.1 FengCms 1.32 网站重装漏洞 漏洞代码逻辑: 漏洞利用: 直接访问 install/index.php 无视弹出的警告信息 继续完成重装流程 3.2 Simple-Log 1.6 网站重装漏洞 漏洞代码逻辑: 漏洞利用: 4. 漏洞修复方案 4.1 基础修复方法 在检测到非法操作后,应立即终止程序执行: 4.2 修复建议总结 在重定向后立即退出: 使用 die() 或 exit() 函数确保程序终止 对于安装检查,应使用不可绕过的机制: 5. CTF题目分析 5.1 题目代码 5.2 漏洞点 stophack() 函数检测到攻击后仅重定向未退出 SQL查询直接拼接用户输入的 $id ,存在SQL注入 过滤函数可被绕过(如大小写、编码等) 5.3 解题思路 利用未退出的漏洞,使过滤后的SQL注入payload仍能执行 使用时间盲注技术(题目提示flag为 HRCTF{tim3_blind_Sql} ) 绕过过滤函数的限制 6. 总结 核心问题 :安全检测后未立即终止程序是常见但危险的设计缺陷 影响范围 :可导致RCE、SQL注入、网站重装等多种高危漏洞 修复关键 :在所有安全检测点后添加 exit 或 die 审计要点 :检查所有安全控制点是否确保程序终止 7. 扩展思考 防御深度原则:多层防御,每层都应确保安全 失败安全原则:安全检查失败时应进入安全状态 最小意外原则:安全控制行为应明确且可预测