Skip to content

Instantly share code, notes, and snippets.

@sei-vsarvepalli
Forked from rxwx/pulseversion.py
Last active January 6, 2022 05:46
Show Gist options
  • Save sei-vsarvepalli/5dd121cbff653a13c43e5eabefc81c20 to your computer and use it in GitHub Desktop.
Save sei-vsarvepalli/5dd121cbff653a13c43e5eabefc81c20 to your computer and use it in GitHub Desktop.
Pulse Secure Version Scanner
import requests
import sys
import re
import semver
import json
import signal
import warnings
warnings.filterwarnings("ignore")
HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0"}
patched = "9.1.11.12173"
minsecure = "9.1.9.0"
def compare(a,b):
""" The PCS version numbers do not follow semver convention
so ignore anything more than 3 levels down for basic comparision
"""
a = re.sub('[^0-9\.]','',a)
b = re.sub('[^0-9\.]','',b)
fa = a.split(".")
fb = b.split(".")
aver = ".".join(fa[0:3])
bver = ".".join(fb[0:3])
if semver.compare(aver,bver) > 0:
return 1
elif len(fa) > 3:
av = float("0."+".".join(fa[3:]))
bv = float("0."+".".join(fb[3:]))
if av > bv:
return 1
return -1
def print_exit(info,code):
print(json.dumps(info))
sys.exit(code)
if len(sys.argv) != 2:
print (" Usage: python pulseversion.py <target ip/domain>")
sys.exit(1)
ip = sys.argv[1]
info = {"ip": ip}
signal.signal(signal.SIGALRM,lambda a,b:
print_exit({"error":"Timeout","ip":ip},255))
#Exception("Timed out connecting to server %s" %(sys.argv[1])))
try:
signal.alarm(5)
r = requests.get("https://%s/dana-cached/hc/HostCheckerInstaller.osx" % ip, verify=False, allow_redirects=False, timeout = 10)
except Exception as e:
print("Unable to connect to your VPN server %s" %(ip))
print("Error returned %s" %(str(e)))
info["error"] = str(e)
print_exit(info,255)
if r.status_code != 200:
print ("[!] Couldn't find Host Checker ")
info["error"] = "No host checker found"
print_exit(info,254)
pattern = re.compile("<key>version</key>[^<]*<string>([^>]+)<")
result = pattern.findall(str(r.content))
if len(result) == 1:
print ("[+] %s, version: %s" % (ip, result[0]))
info["version"] = result[0]
if compare(patched,result[0]) > -1:
info["status"] = "unpatched"
if compare(minsecure,result[0]) > -1:
print("Your Pulse VPN server version: %s is vulnerable multiple security advisories"%(result[0]))
print("Please upgrade to latest stable 9.1R11.4, learn more at:")
print("https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44784/")
print("https://kb.cert.org/vuls/id/213092")
print_exit(info,0)
rm = requests.get("https://%s/dana-ws/namedusers" %(ip), verify=False, allow_redirects=False)
print("Your version: %s is likely vulnerable to VU#213092 and vendor advisory SA44784 vulnerability" %(result[0]))
print("It is highly recommended that you update your Pulse VPN server immediately, learn more at:")
print("https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44784/")
print("https://kb.cert.org/vuls/id/213092")
if rm.status_code == 403:
info["work_around"] = "installed"
print("Your Pulse VPN Server may have the workaround Workaround-2104.xml to block malicious requests")
else:
info["work_around"] = "unknown"
print("Your Pulse VPN Server does not seem to have any workaround, please upgrade")
else:
info["status"] = "patched"
print("Your version %s is patched" %(result[0]))
else:
print ("[!] Unable to detect version")
info["error"] = "Unable to detect version"
print_exit(info,0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment