Webug4.0靶场通关笔记16- 第20关文件上传(截断上传)
目录
第20关 文件上传(截断上传)
1.打开靶场
2.源码分析
(1)右键查看前端源码
(2)服务端源码分析
(3)渗透思路
3.渗透实战
(1)构建脚本
(2)bp抓包
(3)生僻字过滤绕过
本文通过《webug4.0靶场第19文件上传之截断上传》对客户端前端和服务端的代码进行审计,基于代码审计来分析渗透思路并进行渗透实战。
第20关 文件上传(截断上传)
1.打开靶场
进入webug4.0靶场的第20关卡文件上传(截断上传),完整URL地址如下所示。
http://192.168.71.1/webug4/control/upload_file/upload_file_4.php
进入靶场后发现这是一个注册账号的页面,包含文件上传的功能,具体如下图所示。
2.源码分析
(1)右键查看前端源码
如下所示右键查看源码,发现本关卡依旧存在客户端js绕过,在前端通过js脚本使用白名单校验文件的后缀,具体如下所示。
(2)服务端源码分析
查看upload_file_4.php代码,这段代码的主要功能是处理文件上传操作,具体如下所示。
<?php
// 引入公共配置文件,该文件可能包含了一些全局的常量、函数或配置信息
require_once "../../common/common.php";// 检查会话中是否存在 'user' 变量
// 如果不存在,说明用户未登录,将用户重定向到登录页面
if (!isset($_SESSION['user'])) {header("Location:../login.php");
}// 定义允许上传的文件扩展名数组
$filter = array(".jpg", '.png', '.gif');// 检查上传文件是否出现错误
// 如果存在错误,直接终止脚本执行
if ($_FILES['file']['error']) {die();
}// 检查是否有文件上传
if ($_FILES['file']) {// 将上传文件的相关信息存储在 $arr 数组中$arr = $_FILES['file'];// 获取上传文件的扩展名,并转换为小写// strrchr 函数用于返回文件名中从最后一个点开始的部分// trim 函数用于去除字符串首尾的空白字符$file_ext = trim(strtolower(strrchr($arr['name'], ".")));// 检查文件扩展名是否在允许的数组中if (!in_array($file_ext, $filter)) {// 如果扩展名不在允许数组中,弹出提示框并终止脚本echo "<script>alert('error')</script>";die();}// 检查目标上传目录中是否已经存在同名文件// TPMELATE 可能是一个定义在公共配置文件中的常量,表示模板目录路径if (file_exists(TPMELATE."/upload/".$arr['name'])) {// 如果文件已存在,弹出提示框告知用户echo "<script>alert('该文件已经存在')</script>";} else {// 如果文件不存在,将上传文件移动到指定的目标路径// iconv 函数用于将文件名从 UTF-8 编码转换为 gb2312 编码$filename = iconv("UTF-8", "gb2312", TPMELATE."/upload/".$arr['name']);move_uploaded_file($arr["tmp_name"], $filename);// 输出上传文件的完整路径,并终止脚本执行echo $filename;die();}
}// 引入上传文件的 HTML 页面
require_once TPMELATE."/upload_file_1.html";
这段代码主要是处理文件上传操作,在服务端进行校验,具体逻辑如下所示。
- 登录验证:检查用户是否已登录,如果未登录则重定向到登录页面。
- 错误检查:检查上传文件是否出现错误,如果有错误则终止脚本。
- 扩展名验证:获取上传文件的扩展名,并进行白名单校验,检查其是否在允许的扩展名数组
$filter
中。如果不在,则提示错误并终止脚本。 - 文件存在性检查:检查目标上传目录中是否已经存在同名文件,如果存在则提示用户。
- 文件上传:如果文件不存在且扩展名验证通过,则将上传文件移动到指定的目标路径,并输出文件的完整路径。
- 页面引入:最后引入上传文件的 HTML 页面。
(3)渗透思路
本关卡服务器在处理文件时,调用了 iconv 函数,具体如下所示。
// iconv 函数用于将文件名从 UTF-8 编码转换为 gb2312 编码
$filename = iconv("UTF-8", "gb2312", TPMELATE."/upload/".$arr['name']);
使用 iconv 函数将文件名从 UTF8 编码转换为GB2312 编码,这可能会导致文件名被截断或出现乱码。攻击者可以利用这一点构造特殊的文件名,使得在转换编码后,文件名看起来符合要求,但实际上包含恶意代码。
UT8 是一种可变长度的字符编码,它可以表示世界上几乎所有的字符,使用 1 到 4 个字节来编码一个字符。而 GB2312 是中国国家标准的简体中文字符集,它只支持部分中文字符和一些符号,使用 2 个字节编码一个字符。当使用 iconv
函数将 UTF - 8 编码的文件名转换为 GB2312 编码时,如果 UTF8 文件名中包含 GB2312 字符集不支持的字符,iconv
函数可能会将这些字符截断或者替换为乱码。
基于如上原理,攻击者可以通过构造文件名进行渗透。攻击者可以构造一个包含特殊字符的 UTF8 文件名,这些特殊字符在 UTF8 编码下可以正常表示,但在转换为GB2312 编码时会被截断或转换为其他字符。服务器在处理文件名时,可能会根据截断或乱码后的文件名来判断文件类型和执行权限。
3.渗透实战
由于对文件的检查是客户端处理,故而可以在客户端上传图片,绕过客户端的前端检查然后在bp中修改报文并将报文后缀改为info2.php 发送到服务器。
(1)构建脚本
将info.php修改为info.jpg,这样可以绕过客户端js脚本的前端检查,如下所示。
(2)bp抓包
bp开启拦截功能,firefox浏览器开启代理,如下图所示。
将info.jpg上传,并使用bp抓包,同时将报文发送给repeater,如下图所示。
(3)生僻字过滤绕过
将报文名进行修改,后缀改为jpg,中间加上生僻字,如下图所示。
info.php龘.jpg
访问脚本后显示服务器的php信息,渗透成功,webshell文件完整URL地址如下所示。
D:/web/phpstudy_pro/WWW/webug4/template/upload/info.php