Skip to content

Instantly share code, notes, and snippets.

@rxwx
Created August 13, 2019 09:04
Show Gist options
  • Select an option

  • Save rxwx/d07495f790d62029b12065c38ac2a86a to your computer and use it in GitHub Desktop.

Select an option

Save rxwx/d07495f790d62029b12065c38ac2a86a to your computer and use it in GitHub Desktop.
Pulse Secure Version Scanner
import requests
import sys
import re
HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0"}
if len(sys.argv) != 2:
print " Usage: python pulseversion.py <target ip/domain>"
sys.exit(1)
r = requests.get("https://%s/dana-na/nc/nc_gina_ver.txt" % sys.argv[1], verify=False, allow_redirects=False)
if r.status_code != 200:
print "[!] Couldn't find target file"
sys.exit(1)
reg = re.compile(r'<PARAM NAME="ProductVersion" VALUE="([\d.]*?)"')
result = reg.search(r.text)
if result:
print "[+] %s, version: %s" % (sys.argv[1], result.group(1))
else:
print "[!] Unable to detect version"
@rxwx
Copy link
Copy Markdown
Author

rxwx commented Apr 22, 2021

Alternative version:

import requests
import sys
import re

HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0"}

if len(sys.argv) != 2:
    print (" Usage: python pulseversion.py <target ip/domain>")
    sys.exit(1)

r = requests.get("https://%s/dana-cached/hc/HostCheckerInstaller.osx" % sys.argv[1], verify=False, allow_redirects=False)

if r.status_code != 200:
    print ("[!] Couldn't find target file")
    sys.exit(1)

reg = re.compile(r'<key>version</key>\n<string>([\d.]*?)</string>')
result = reg.search(r.text)

if result:
    print ("[+] %s, version: %s" % (sys.argv[1], result.group(1)))
else:
    print ("[!] Unable to detect version")

@sei-vsarvepalli
Copy link
Copy Markdown

Hello @rvwx

A little improvement on your version scanner to detect if Pulse Server at an IP address is likely unpatched to the latest advisories https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44784/ . Happy to give you credit and put it out for other defenders to use. As always these can give some false/positives.

#!/usr/bin/python3

import requests
import sys
import re
import semver


HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0"}

fixed = "9.1.11.12173"

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
if len(sys.argv) != 2:
    print (" Usage: python pulseversion.py <target ip/domain>")
    sys.exit(1)

r = requests.get("https://%s/dana-cached/hc/HostCheckerInstaller.osx" % sys.argv[1], verify=False, allow_redirects=False)

if r.status_code != 200:
    print ("[!] Couldn't find Host Checker ")
    sys.exit(1)

pattern = re.compile("<key>version</key>[^<]*<string>([^>]+)<")
result = pattern.findall(str(r.content))

if len(result) == 1:
    print ("[+] %s, version: %s" % (sys.argv[1], result[0]))
    if compare(fixed,result[0]) > -1:
        print("Your version: %s is likely vulnerable to VU#213092 and vendor advisory SA44784 vulnerability" %(result[0]))
        print("Please update your PCS immediately learn more at ")
        print("https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44784/")
        print("https://kb.cert.org/vuls/id/213092")
    else:
        print("Your version %s is patched" %(result[0]))
else:
    print ("[!] Unable to detect version")

@RedTeamMagic
Copy link
Copy Markdown

@sei-vsarvepalli you're the man!

For anyone else who wants to do a quick/simple/dirty manual check

wget https://x.x.x.x/dana-cached/hc/HostCheckerInstaller.osx --no-check-certificate
cat HostCheckerInstaller.osx | grep -a "<key>version</key>" -A 1 

@ihebski
Copy link
Copy Markdown

ihebski commented Feb 4, 2022

Thanks a lot, awesome work!

  • For a faster check
# Pulse secure version <= R8
curl -k https://IP/dana-na/nc/nc_gina_ver.txt | grep '<PARAM NAME="ProductVersion" VALUE="'

# Pulse secure version > R8 (R9 >>)
curl -k https://IP/dana-cached/hc/HostCheckerInstaller.osx -o version && strings version | grep '<string>'

@S4lt5
Copy link
Copy Markdown

S4lt5 commented Nov 9, 2022

Very useful, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment