Webug4.0靶场通关笔记16- 第20关文件上传(截断上传)

#王者杯·14天创作挑战营·第1期#

目录

第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";

 这段代码主要是处理文件上传操作,在服务端进行校验,具体逻辑如下所示。

  1. 登录验证:检查用户是否已登录,如果未登录则重定向到登录页面。
  2. 错误检查:检查上传文件是否出现错误,如果有错误则终止脚本。
  3. 扩展名验证:获取上传文件的扩展名,并进行白名单校验,检查其是否在允许的扩展名数组 $filter 中。如果不在,则提示错误并终止脚本。
  4. 文件存在性检查:检查目标上传目录中是否已经存在同名文件,如果存在则提示用户。
  5. 文件上传:如果文件不存在且扩展名验证通过,则将上传文件移动到指定的目标路径,并输出文件的完整路径。
  6. 页面引入:最后引入上传文件的 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

### Web 安全靶场 Webug 4.0 中越权修改密码的解决方案 在 Web 应用程序的安全测试中,“越权访问”是一种常见的漏洞,指的是未经授权的用户能够执行超出其权限范围的操作。对于 Webug 4.0 靶场中的越权修改密码场景,以下是详细的分析与解决方法。 #### 背景描述 在 Webug 4.0 的设计中,存在一种典型的越权行为模式:攻击者可以通过篡改 HTTP 请求参数(如 `id` 字段),从而冒充其他用户的身份并修改目标用户的密码[^4]。这种漏洞通常源于应用程序未对操作对象的有效性和当前登录用户的权限进行严格验证。 --- #### 技术原理剖析 越权漏洞的核心原因在于服务器端缺乏有效的身份校验机制。具体表现为以下几点: 1. **请求参数未经验证** 当前用户发送的请求可能携带了非法的目标用户 ID 参数(例如 `id=0` 表示管理员)。如果服务端仅依赖前端传递的数据而未进一步确认该数据的真实性,则可能导致越权。 2. **缺少细粒度授权控制** 如果应用未能区分不同角色之间的权限边界,就容易让低权限用户获得高权限功能的使用权。 3. **会话管理不当** 即使实现了基于会话的身份认证,但如果会话状态没有绑定到具体的资源访问上下文中,也可能引发类似的越权问题。 --- #### 解决方案实现 针对上述问题,可以从以下几个方面入手来修复此漏洞: ##### 1. 强化后端逻辑校验 每次接收到涉及敏感操作(如更改密码)的请求时,应强制核对该操作是否由合法主体发起。这可通过比较当前已登录账户的信息与待处理记录所属实体的一致性完成。例如,在 PHP 或 Python 后端代码中加入如下片段以确保只有本人能重置自己的密码: ```php <?php // 假设 $_SESSION['user_id'] 存储着当前登录者的唯一标识符 if ($_POST['target_user_id'] != $_SESSION['user_id']) { die('Access Denied'); // 若两者不符则拒绝继续运行后续脚本 } ?> ``` 或者采用更现代化的语言框架编写类似防护措施: ```python from flask import session, request, abort def change_password(): target_user_id = int(request.form.get('target_user_id')) current_user_id = session.get('user_id') if target_user_id != current_user_id: abort(403) # 返回HTTP Forbidden响应码表示无权访问 # 正常业务流程... ``` 以上两段伪代码均体现了只允许用户对自己账号实施特定变更的原则。 ##### 2. 实施严格的 RBAC (Role-Based Access Control) 引入基于角色的访问控制系统有助于细化各类人员所能触及的功能模块及其内部细节。通过预先定义好的策略组合判定谁可以在何时何地做什么事情,进而减少因疏忽造成的安全隐患。 例如,在 MySQL 数据库表结构层面增加字段用于标记每条记录联的角色类别,并据此调整查询语句条件部分的内容以便筛选出符合条件的结果集之前先过滤掉不符合要求的部分。 ##### 3. 利用 CSRF Token 提升安全性 为了防止恶意站点诱导受害者提交伪造跨站请求(CSRF),建议结合随机生成且难以预测的一次性令牌(Token)一同嵌入至 HTML 表单之中并与对应 Session 绑定起来共同参与最终判断过程。这样即使黑客截获到了原始 POST 请求也无法轻易复制粘贴成功模拟真实交互动作。 --- #### 总结说明 综上所述,要彻底杜绝此类越权现象的发生除了加强开发阶段的设计考量之外还需要持续注最新威胁情报动态及时修补发现的新缺陷。同时也要提醒广大开发者时刻牢记安全第一的理念贯穿整个软件开发生命周期始终。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mooyuan天天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值