php小结

🎯 Pass-01:前端 JS 校验

关键函数checkFile()(JavaScript)

漏洞原因:仅在客户端用 JS 检查扩展名,可禁用 JS 或直接 Burp 改包绕过。

防御 :前端校验只做用户体验,后端必须做同等校验

🎯 Pass-02:Content-Type 绕过

关键函数$_FILES['upload_file']['type']

漏洞原因 :仅判断浏览器传来的 type 字段(image/jpeg/image/png/image/gif),该值完全可由攻击者篡改。

防御 :使用 finfo_file()exif_imagetype() 读取文件二进制头,获取真实 MIME。

🎯 Pass-03:特殊后缀绕过(黑名单不全)

关键函数in_array($file_ext, $deny_ext)

漏洞原因 :黑名单遗漏 php5phtmlpht 等可解析后缀,攻击者上传 shell.phtml 即可绕过。

防御改用白名单 ,只允许 jpg/png/gif 等业务必需后缀。

🎯 Pass-04:.htaccess 解析绕过

关键函数move_uploaded_file()

漏洞原因 :黑名单未过滤 .htaccess,上传 .htaccess 后可使目录下 .jpg 被当作 PHP 解析。

防御

  • 白名单 + 上传目录禁用脚本执行

  • Apache 配置 php_flag engine off

🎯 Pass-05:.user.ini 绕过

关键函数move_uploaded_file()

漏洞原因 :黑名单未过滤 .user.ini,通过 auto_prepend_file=shell.png 让同目录 PHP 文件自动包含图片马。

防御 :上传目录禁止 .ini.htaccess 等配置文件生效;Web 服务器层面 deny all 拦截。

🎯 Pass-06:大小写绕过

关键函数strtolower()缺失

漏洞原因 :未统一后缀大小写,shell.PhP 不在黑名单中。

防御 :提取后缀后立即 strtolower(),再比对白名单。

🎯 Pass-07:空格绕过

关键函数trim()缺失

漏洞原因 :未在 deldot() 前后做 trim()shell.php(末尾空格)绕过黑名单。

防御

php 复制代码
$file_ext = trim($file_ext);
$file_ext = strtolower($file_ext);

🎯 Pass-08:末尾点绕过

关键函数deldot()缺失

漏洞原因 :未在 deldot() 删除文件名末尾的点,shell.php. 在 Windows 保存时自动去点。

防御 :循环删除末尾的 .、、\t

php 复制代码
while (in_array(substr($file_name, -1), ['.', ' ', "\t"])) {
    $file_name = substr($file_name, 0, -1);
}

🎯 Pass-09:::$DATA 绕过

关键函数str_ireplace('::$DATA', '', $file_ext)缺失

漏洞原因 :Windows NTFS 备用数据流特性,shell.php::$DATA 实际落盘为 shell.php

防御

php 复制代码
$file_ext = str_ireplace('::$DATA', '', $file_ext);

🎯 Pass-10:点空格点绕过(你贴源码的真实关卡)

关键函数deldot() + trim() + strrchr()

漏洞原因deldot() 从右向左删点遇到空格停下,strrchr() 取到空格,trim() 后变成空字符串,不在黑名单中。

payloadshell.php. .(点+空格+点)

防御:采用循环清洗 + 白名单双保险(见 Pass-08 防御代码)。

🎯 Pass-11:双写绕过

关键函数str_ireplace($deny_ext, '', $file_ext)(替换为空但未递归检查)

漏洞原因str_ireplace() 只替换一次,pphphp 替换 php 后剩下 php

防御 :替换为空后重新校验后缀 ,或使用白名单 in_array() 直接拒绝。

🎯 Pass-12 & Pass-13:%00 截断绕过

关键函数move_uploaded_file()(PHP < 5.3.4)

漏洞原因 :路径拼接 $img_path = $_GET['save_path'].'/'.$file_namesave_path 可控,注入 shell.php%00 截断后续字符串。

防御

  • 升级 PHP 版本 ≥ 5.3.4

  • 对用户输入路径做 basename() 剥离目录信息

  • 使用白名单 + 随机文件名

🎯 Pass-14 & Pass-15:图片马 + 文件包含

关键函数getimagesize()

漏洞原因getimagesize() 只检查文件头魔术字节,攻击者在合法图片后追加 <?php ?> 代码,函数仍返回 true。需配合文件包含漏洞 include.php?file=upload/shell.jpg 执行。

防御

php 复制代码
$info = getimagesize($tmp_file);
if ($info === false) die('非法图片');
// 配合:上传目录禁执行 + 随机重命名 + 图片二次渲染

🎯 Pass-16:exif_imagetype 绕过

关键函数exif_imagetype()

漏洞原因 :与 getimagesize() 类似,仅检查文件头第一个字节,图片马仍可绕过。

防御:同 Pass-14/15,且额外做图片重编码。

🎯 Pass-17:二次渲染绕过(条件竞争前的高级关卡)

关键函数imagecreatefromjpeg() / imagecreatefromgif() / imagecreatefrompng() + imagejpeg()

漏洞原因:服务器用 GD 库重新生成图片,丢弃非像素数据。JPG 几乎无法绕过(有损压缩),但 GIF 在渲染后仍存在未变区域,可在这些区域插入 PHP 代码。

防御

php 复制代码
// 强制重编码,丢弃原始文件
$im = imagecreatefromgif($tmp_file);
imagegif($im, $new_path);
imagedestroy($im);
unlink($tmp_file);  // 删除原始上传
相关推荐
剩下了什么2 小时前
float32 与 float64 精度陷阱:如何在 Go 中避免错误使用
开发语言·后端·golang
指尖时光.2 小时前
Three.js 超全入门综合案例
开发语言·javascript·ecmascript
暴力求解2 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
吴声子夜歌3 小时前
Java面试题——基础(一)
java·开发语言
小庞在加油3 小时前
WinDbg实战:QT/跨平台项目死锁与无响应问题排查指南
开发语言·qt·windbg·工具
Vae_Mars4 小时前
C#中的delegate委托
开发语言·c#
一直走下去-明4 小时前
简单的http抓包解包完整代码
开发语言·python
caimouse4 小时前
ReactOS 图形系统分析(51):元文件子系统 — metafile.c
c语言·开发语言
学习星球5 小时前
Solid.js 实战:拆解官方 RealWorld 项目
开发语言·javascript·vue.js
OPEN-F5 小时前
Python进阶教程:正则表达式进阶与文本处理
开发语言·python·正则表达式