-
-
Save sei-vsarvepalli/5dd121cbff653a13c43e5eabefc81c20 to your computer and use it in GitHub Desktop.
Pulse Secure Version Scanner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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