靶场PHP函数与漏洞防御总结
·
靶场 PHP 函数整理与漏洞防御方式总结
第一部分 靶场中用到的 PHP 函数
一、一句话木马 / 代码执行相关
| 函数 / 语句 | 作用 | 靶场中的用法 |
|---|---|---|
eval($code) |
把字符串当作 PHP 代码执行 | 一句话木马核心:<?php @eval($_POST['cmd']); ?> |
assert($code) |
断言,传入字符串时也会执行 PHP 代码 | 一句话木马变体 |
call_user_func($func, $arg) |
回调方式动态调用函数 | call_user_func('system', $_GET['cmd']),常用于绕过对 system 关键字的过滤 |
call_user_func_array() |
同上,参数以数组形式传递 | 回调绕过变体 |
preg_replace() |
正则替换;PHP<5.5 时 /e 修饰符会执行替换结果中的代码 |
历史代码执行点(面试常考) |
create_function() |
动态创建函数(PHP<7.2),可注入代码 | 历史代码执行点 |
区别要点(7.27 课堂重点):eval 执行的是 PHP 代码,system 执行的是操作系统命令。
二、命令执行相关
| 函数 | 作用 | 特点 |
|---|---|---|
system($cmd) |
执行系统命令并直接输出结果 | 页面直接显示命令结果(如 whoami → www-data) |
exec($cmd, $output) |
执行命令,结果放入数组,只返回最后一行 | 不自动输出,需配合 echo |
shell_exec($cmd) |
执行命令,返回完整输出字符串 | 无回显时需 echo shell_exec(...) |
passthru($cmd) |
执行命令并原样输出(含二进制) | 适合输出原始数据 |
popen() / proc_open() |
以进程方式执行命令,返回句柄 | 进阶/绕过场景 |
三、文件包含相关
1. 四个包含函数
| 函数 | 文件找不到时 | 重复包含 |
|---|---|---|
include |
警告(Warning),继续执行 | 允许 |
include_once |
警告,继续执行 | 同一文件仅一次 |
require |
致命错误,程序终止 | 允许 |
require_once |
致命错误,程序终止 | 同一文件仅一次 |
典型漏洞代码:include $_GET['page'];
2. 相关 php.ini 配置项
allow_url_include:是否允许包含远程 URL(RFI、php://input、data:// 的前提)allow_url_fopen:是否允许 URL 方式的文件操作open_basedir:限制 PHP 可访问的目录范围
第二部分 各类型漏洞的防御方式
一、文件上传漏洞
成因: 对上传文件的类型、后缀、内容校验不严,或校验逻辑存在时序/逻辑缺陷,导致可执行脚本落地服务器。
| 缺陷类型 | 典型绕过 | 防御方式 |
|---|---|---|
| 仅前端 JS 校验 | 禁用 JS / Burp 改包 | 服务端必须重新校验,前端校验只做体验 |
| 仅校验 Content-Type | Burp 改 MIME | MIME 可被伪造,只能作为辅助,不能作为唯一依据 |
| 黑名单 | php3/php5/大小写/双写/末尾点/::$DATA | 改用白名单(只允许 jpg/png/gif 等) |
| 单次替换 | pphphp 双写 |
白名单;或循环替换至无匹配 |
| 路径参数可控 | save_path + %00 截断 | 过滤 ../、%00,用 basename() 取纯文件名,保存路径由服务端写死 |
| 文件内容检测 | 图片马 + 文件包含 | 二次渲染(GD 重编码);上传目录与包含白名单隔离 |
| 先保存后校验 | 条件竞争 | 先校验后保存;使用临时随机名,校验通过再改名(原子化) |
| 用户可控文件名 | save_name 大小写/末尾点/数组 | is_string() 强制类型检查;服务端统一重命名 |
通用加固清单:
- 扩展名、MIME、文件内容(图片二次渲染)三重校验,以白名单为准;
- 服务端随机重命名,攻击者无法预测路径与文件名;
- 上传目录禁止脚本解析(Apache/Nginx 配置关闭该目录 PHP 执行),最好存放到 Web 根目录之外或独立域名/对象存储;
- 完整清理链且顺序正确:
trim → deldot → strtolower → 去::$DATA,先清理再检查; - 限制文件大小,Web 服务低权限运行。
二、文件包含漏洞
成因: include/require 的参数来自用户输入且未严格限制,导致包含预期外文件(敏感文件、日志、Session、上传的图片马、远程恶意文件)。
- 首选:白名单映射——用户只提交业务标识,真实路径由服务端决定:
$pages = ['home'=>__DIR__.'/pages/home.php', 'news'=>__DIR__.'/pages/news.php']; $key = $_GET['page'] ?? 'home'; if (!isset($pages[$key])) { http_response_code(404); exit('页面不存在'); } include $pages[$key]; - 必须传路径时做规范化校验:
realpath()解析../和符号链接后,确认最终路径仍在允许目录内(strpos($target, $base)===0)。 - 配置加固:生产环境关闭
allow_url_include;按需评估关闭allow_url_fopen;配置open_basedir限制访问范围。 - 切断组合利用链:上传、日志、Session 目录不可被包含;上传目录禁止 PHP 解析。
- 最小权限 + 不泄露信息:Web 进程低权限运行;关闭
display_errors,错误页不泄露绝对路径。 - 不用字符串替换黑名单(过滤
../、php://易被变形绕过)。
三、代码执行 / 命令执行漏洞
成因: 用户可控数据进入 eval、system、exec、shell_exec、passthru、call_user_func 等函数。
- 删除危险用法:生产代码不使用
eval()执行用户输入;不把用户输入传给命令执行函数。 - 白名单替代动态调用:用固定业务逻辑/白名单映射,不让用户提供函数名或代码:
$actions = ['show_user' => function(){ /* 固定业务代码 */ }]; if (isset($actions[$action])) { echo $actions[$action](); } - 必须执行系统命令时:参数用
escapeshellarg()/escapeshellcmd()转义,命令白名单化。 - 纵深防御:Web 服务低权限账户运行;结合容器、SELinux/AppArmor 限制影响范围;在
php.ini中用disable_functions禁用system,exec,shell_exec,passthru,eval等高危函数。
四、CSRF 跨站请求伪造
成因: 服务端只验证 Cookie 中的登录状态,不验证请求是否由用户本人主动发起,攻击者诱导已登录用户访问恶意页面,以其身份执行非预期操作。
- CSRF Token:表单/请求中嵌入服务端生成的随机 Token,提交时校验(攻击者无法预知 Token)——最有效;
- 校验 Referer / Origin:确认请求来源是本站点;
- SameSite Cookie:设置
SameSite=Strict/Lax,阻止跨站携带 Cookie; - 二次验证:敏感操作(改密、转账)要求重新输入密码、短信/图形验证码;
- 关键操作使用 POST 而非 GET,并配合自定义请求头(如
X-Requested-With)。
五、越权攻击
成因: 服务端只判断"是否登录",不判断"该用户是否有权操作这条数据/这个功能"。
| 类型 | 说明 | 防御 |
|---|---|---|
| 水平越权 | 同等级用户间越权访问数据(改 id 看他人信息) | 服务端对每个请求校验数据归属:操作对象必须与当前会话用户绑定;不使用可猜测的连续 ID(用随机/加密 ID) |
| 垂直越权 | 普通用户执行管理员功能 | 基于角色的访问控制(RBAC);服务端对每个接口做权限等级校验;管理接口不对普通用户开放;前端隐藏按钮不算防御 |
核心原则:所有权限判断必须在服务端完成,前端隐藏、参数信任都不可靠。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)