upload-labs通关笔记-第7关 文件上传之空格绕过
目录
一、空格绕过方法
二、trim函数
三、源码分析
四、渗透实战
1、构建脚本test7.php
2、打开靶场
3、bp开启拦截
4、点击上传
5、bp拦截
6、后缀名增加空格
7、发包并获取脚本地址
8、访问脚本
本文通过《upload-labs靶场通关笔记系列》来进行upload-labs靶场的渗透实战,本文讲解upload-labs靶场第7关文件空格绕过渗透实战。
一、空格绕过方法
文件上传攻击中的的 空格绕过方法(Space Bypass) 是一种利用文件命名规则或校验逻辑缺陷的攻击方式,攻击者通过在文件名中插入 空格(Space) 或 特殊空白字符,绕过服务器的安全校验(如黑名单过滤、扩展名检测等),从而渗透成功上传恶意文件。
假设目前服务器过滤".php"后缀,但是没有过滤".php "后缀,就是在原有php后缀的尾部加一个空格的情况,可以使用如下方法进行渗透利用,计划上传pass7.php文件,但是由于服务器过滤了"php"后缀,故而无法直接上传该脚本。于是可以通过在将上传脚本的后缀改为“.php ”(末尾带空格)的文件,即改名后的文件名为"pass7.php ",可能被系统存储为 “pass7.php” 并执行。
-
Windows 系统:默认会自动去除文件名末尾的空格,“pass7
.php ”
→ “pass7.php”
。 -
Linux/Unix 系统:保留空格,但某些校验逻辑可能忽略空格
二、trim函数
trim() 是 PHP 中用于 去除字符串首尾空白字符(或其他指定字符) 的内置函数,常用于数据清洗、文件名校验等场景。函数原型如下所示。
string trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] )
-
参数:
- $str:要处理的字符串。
- $character_mask(可选):指定要删除的字符列表(默认去除空白符)。
-
返回值:
-
返回处理后的字符串,不修改原字符串。
-
trim() 默认会删除如下字符,具体如下所示。
字符 | 描述 |
---|---|
" " | 普通空格 |
"\t" | 制表符(Tab) |
"\n" | 换行符(LF) |
"\r" | 回车符(CR) |
"\0" | 空字符(NULL byte) |
"\x0B" | 垂直制表符(Vertical Tab) |
三、源码分析
接下来对upload-labs 第 7 关的源码进行审计,很明显这一关卡又是黑名单过滤,与第6关卡一样,相对于第四关和第五关,将“.htacess和.ini”后缀均过滤了,故而无法用第四关和第五关的方法进行渗透。经过详细注释的代码如下所示。
<?php
// 初始化上传状态和消息变量
$is_upload = false; // 布尔值,标记文件是否上传成功
$msg = null; // 字符串,用于存储上传过程中的错误信息// 检查用户是否通过POST方法提交了表单(submit按钮被点击)
if (isset($_POST['submit'])) {// 检查上传目录是否存在if (file_exists(UPLOAD_PATH)) {// 定义禁止上传的文件扩展名黑名单(包含常见服务端脚本文件及其变体)$deny_ext = array(// PHP相关扩展名及大小写变体".php", ".php5", ".php4", ".php3", ".php2",".phtml", ".pht", ".pHp", ".pHp5", ".pHp4", ".pHp3", ".pHp2",// HTML相关扩展名及变体".html", ".htm",".Html", ".Htm", ".pHtml",// JSP相关扩展名及变体".jsp", ".jspa", ".jspx", ".jsw", ".jsv", ".jspf", ".jtml",".jSp", ".jSpx", ".jSpa", ".jSw", ".jSv", ".jSpf", ".jHtml",// ASP相关扩展名及变体".asp", ".aspx", ".asa", ".asax", ".ascx", ".ashx", ".asmx", ".cer",".aSp", ".aSpx", ".aSa", ".aSax", ".aScx", ".aShx", ".aSmx", ".cEr",// 其他危险文件类型".sWf", ".swf", // Flash文件".htaccess", // Apache配置文件".ini" // 配置文件);// 获取上传文件的原始名称$file_name = $_FILES['upload_file']['name'];// 调用deldot函数删除文件名末尾的点(防御类似"evil.php."的绕过攻击)$file_name = deldot($file_name);// 获取文件扩展名(从最后一个点开始截取)$file_ext = strrchr($file_name, '.');// 将扩展名转换为小写(统一比较,避免大小写绕过)$file_ext = strtolower($file_ext);// 去除Windows NTFS备用数据流::$DATA(防御特殊绕过)$file_ext = str_ireplace('::$DATA', '', $file_ext);// 检查扩展名是否在黑名单中if (!in_array($file_ext, $deny_ext)) {// 获取上传文件的临时路径$temp_file = $_FILES['upload_file']['tmp_name'];// 生成目标文件名:当前日期时间+随机数+原扩展名(避免文件名冲突)$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;// 将临时文件移动到目标路径if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true; // 标记上传成功} else {$msg = '上传出错!'; // 文件移动失败(可能权限不足或磁盘已满)}} else {$msg = '此文件不允许上传'; // 文件类型被禁止}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; // 上传目录不存在}
}
?>
与第6关对比,增加了strtolower故而无法使用大小写绕过方法,但是缺少了函数trim的处理。 正因为源码中没有$file_ext = trim($file_ext);//该语句可以将文件前后的空格过滤,所以可以在文件末尾添加一个空格,这样就可以绕过黑名单的限制。
例如:上传test.php文件,抓包后在文件名后添加一个空格。上传到服务器的时候,得到的后缀就是.php空格,从而绕过黑名单的限制,又因为.php空格不符合windows文件的命名规则,所以服务器存储的时候会将末尾的空格去掉,文件末尾就变回了.php(尾部无空格),这样文件名又恢复成为test.php,可以成功渗透。
四、渗透实战
1、构建脚本test7.php
<?php
phpinfo();
?>
2、打开靶场
打开靶场第7关,浏览选择该脚本,但不点击上传。
3、bp开启拦截
4、点击上传
5、bp拦截
bp捕获到上传报文,下图红框的部分即为需要修改的文件名,需要将".php"后缀改为".php ",截图如下所示。
6、后缀名增加空格
test7.php后添加一个空格,修改后效果如下所示。
7、发包并获取脚本地址
将bp的inception设置为off,此时修改后的报文发送成功。
回到靶场的Pass07关卡,图片已经上传成功,右键图片获取图片地址。
如下所示获取到图片URL。
http://127.0.0.1/upload-labs/upload/202111191557116954.php
8、访问脚本
如下所示访问脚本获取到服务器的php信息,证明文件上传成功。