记某系统有趣的文件上传
字数 1486 2025-08-06 08:35:00

Windows环境下PHP文件上传漏洞分析与利用

漏洞概述

本文记录了一个基于Windows系统的PHP文件上传漏洞,该漏洞利用了Windows文件命名规则和PHP在Windows环境下的特殊特性,成功绕过了文件上传限制,实现了任意文件上传。

环境搭建

  • 系统环境:Windows
  • 服务器环境:phpstudy集成环境
  • 目标系统:SEMCMS(具体版本未明确)

漏洞分析

初始黑盒测试

  1. 使用默认凭证进入后台
  2. 在图库管理功能中发现文件上传点
  3. 尝试上传PHP文件时发现系统自动添加.jpg后缀

源码分析

关键文件:/Admin/SEMCMS_Upfile.php

文件上传处理流程

  1. filename获取文件类型并截取后缀
  2. 使用正则表达式进行白名单校验:
    preg_match("/jpg|jpeg|gif|png|doc|xls|pdf|rar|zip|bmp|ico/i", $file_ext)
    
  3. 从POST参数wname获取文件名并与后缀拼接
  4. 使用test_input()函数进行过滤(去除空格、反斜杠,HTML实体编码)
  5. 使用move_uploaded_file()写入文件

漏洞利用技术

第一阶段:Windows文件命名规则利用

Windows系统中,文件名中的冒号(:)会导致:

  • 文件名被截断
  • 生成空文件

利用方法

  • 构造wname参数为test.php:
  • 系统会生成test.php空文件

局限性

  • 只能创建空文件,无法写入内容

第二阶段:PHP在Windows下的特殊特性

PHP在Windows环境下对某些字符有特殊处理:

  • >:相当于通配符?(匹配单个字符)
  • <<:相当于通配符*(匹配多个字符)
  • ":相当于字符.(点)

利用步骤

  1. 首先上传一个空PHP文件:

    • 设置wnametest.jpg.php:
    • 生成文件:test.jpg.php(空文件)
  2. 然后写入内容:

    • 设置wnametestfilenametest.jpg<<
    • 由于<<的通配符特性,会匹配到test.jpg.php文件并写入内容

其他有效payload

  • test123.jpg\">>p
  • test123.jpg\"php

技术验证

编写测试代码验证通配符特性:

<?php
$file = @$_REQUEST['filename'];
$file_contents = @file_get_contents($file);
echo "匹配到的文件为:".$file_contents;

测试结果:

  • test.jpg<<:依次匹配test.jpgtest.jpg.jpgtest.jpg.php
  • >:匹配单个字符(类似?
  • ":匹配点字符(.)

影响范围

该特性在PHP5、PHP7和PHP8的Windows环境下均存在,影响以下函数:

  • include()/include_once()
  • require()/require_once()
  • fopen()
  • copy()
  • file_get_contents()
  • readfile()
  • file_put_contents()
  • mkdir()
  • opendir()
  • readdir()
  • move_uploaded_file()
  • getimagesize()

防御建议

  1. 严格校验文件扩展名,使用白名单机制
  2. 在保存文件时重命名文件(如使用随机文件名)
  3. 禁用危险字符在文件名中的使用
  4. 在Linux环境下部署PHP应用
  5. 对上传文件内容进行严格校验

参考资源

总结

该漏洞巧妙利用了Windows文件系统和PHP在Windows环境下的特殊特性,通过多阶段攻击最终实现了任意文件上传。理解这些底层特性对于攻防双方都具有重要意义,既可以帮助安全人员发现更多潜在漏洞,也能帮助开发人员编写更安全的代码。

Windows环境下PHP文件上传漏洞分析与利用 漏洞概述 本文记录了一个基于Windows系统的PHP文件上传漏洞,该漏洞利用了Windows文件命名规则和PHP在Windows环境下的特殊特性,成功绕过了文件上传限制,实现了任意文件上传。 环境搭建 系统环境:Windows 服务器环境:phpstudy集成环境 目标系统:SEMCMS(具体版本未明确) 漏洞分析 初始黑盒测试 使用默认凭证进入后台 在图库管理功能中发现文件上传点 尝试上传PHP文件时发现系统自动添加.jpg后缀 源码分析 关键文件: /Admin/SEMCMS_Upfile.php 文件上传处理流程 从 filename 获取文件类型并截取后缀 使用正则表达式进行白名单校验: 从POST参数 wname 获取文件名并与后缀拼接 使用 test_input() 函数进行过滤(去除空格、反斜杠,HTML实体编码) 使用 move_uploaded_file() 写入文件 漏洞利用技术 第一阶段:Windows文件命名规则利用 Windows系统中,文件名中的冒号( : )会导致: 文件名被截断 生成空文件 利用方法 : 构造 wname 参数为 test.php: 系统会生成 test.php 空文件 局限性 : 只能创建空文件,无法写入内容 第二阶段:PHP在Windows下的特殊特性 PHP在Windows环境下对某些字符有特殊处理: > :相当于通配符 ? (匹配单个字符) << :相当于通配符 * (匹配多个字符) " :相当于字符 . (点) 利用步骤 : 首先上传一个空PHP文件: 设置 wname 为 test.jpg.php: 生成文件: test.jpg.php (空文件) 然后写入内容: 设置 wname 为 test , filename 为 test.jpg<< 由于 << 的通配符特性,会匹配到 test.jpg.php 文件并写入内容 其他有效payload : test123.jpg\">>p test123.jpg\"php 技术验证 编写测试代码验证通配符特性: 测试结果: test.jpg<< :依次匹配 test.jpg 、 test.jpg.jpg 、 test.jpg.php > :匹配单个字符(类似 ? ) " :匹配点字符( . ) 影响范围 该特性在PHP5、PHP7和PHP8的Windows环境下均存在,影响以下函数: include() / include_once() require() / require_once() fopen() copy() file_get_contents() readfile() file_put_contents() mkdir() opendir() readdir() move_uploaded_file() getimagesize() 防御建议 严格校验文件扩展名,使用白名单机制 在保存文件时重命名文件(如使用随机文件名) 禁用危险字符在文件名中的使用 在Linux环境下部署PHP应用 对上传文件内容进行严格校验 参考资源 PHP源码调试之Windows文件通配符分析 PHP官方文档中关于Windows文件系统处理的说明 总结 该漏洞巧妙利用了Windows文件系统和PHP在Windows环境下的特殊特性,通过多阶段攻击最终实现了任意文件上传。理解这些底层特性对于攻防双方都具有重要意义,既可以帮助安全人员发现更多潜在漏洞,也能帮助开发人员编写更安全的代码。