Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/core/auxiliary/epmp.rb
Views: 11784
# -*- coding: binary -*-1module Msf2###3#4# This module provides methods for working with epmp5#6###78module Auxiliary::EPMP9include Msf::Exploit::Remote::HttpClient10include Msf::Auxiliary::AuthBrute11include Msf::Auxiliary::Report12include Msf::Auxiliary::Scanner1314def report_cred(opts)15service_data = {16address: opts[:ip],17port: opts[:port],18service_name: opts[:service_name],19protocol: 'tcp',20workspace_id: myworkspace_id21}2223credential_data = {24origin_type: :service,25module_fullname: fullname,26username: opts[:user],27private_data: opts[:password],28private_type: :password29}.merge(service_data)3031login_data = {32last_attempted_at: Time.now,33core: create_credential(credential_data),34status: Metasploit::Model::Login::Status::SUCCESSFUL,35proof: opts[:proof]36}.merge(service_data)3738create_credential_login(login_data)39end4041#42# Check if App is Cambium ePMP 100043#4445def is_app_epmp1000?46begin47res = send_request_cgi(48{49'uri' => '/',50'method' => 'GET'51}52)53rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError54print_error("#{rhost}:#{rport} - HTTP Connection Failed...")55return false56end5758good_response = (59res &&60res.code == 200 &&61(res.body.include?('cambium.min.css') || res.body.include?('cambiumnetworks.com') && res.body.include?('https://support.cambiumnetworks.com/files/epmp/'))62)6364if good_response65get_epmp_ver = res.body.match(/"sw_version">([^<]*)/)66if !get_epmp_ver.nil?67epmp_ver = get_epmp_ver[1]68if !epmp_ver.nil?69print_good("#{rhost}:#{rport} - Running Cambium ePMP 1000 version #{epmp_ver}...")70do_login(epmp_ver.to_s)71return true72else73print_good("#{rhost}:#{rport} - Running Cambium ePMP 1000...")74epmp_ver = ''75login(datastore['USERNAME'], datastore['PASSWORD'], epmp_ver)76return true77end78end79else80print_error("#{rhost}:#{rport} - Application does not appear to be Cambium ePMP 1000. Module will not continue.")81return false82end83end8485# run if version > 3.4.18687def login_2(user, pass, epmp_ver)88res = send_request_cgi(89{90'uri' => '/cgi-bin/luci',91'method' => 'POST',92'headers' => {93'X-Requested-With' => 'XMLHttpRequest',94'Accept' => 'application/json, text/javascript, */*; q=0.01'95},96'vars_post' =>97{98'username' => 'dashboard',99'password' => ''100}101}102)103104cookies = res.get_cookies_parsed105check_sysauth = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s106107good_response = (108res &&109res.code == 200 &&110check_sysauth.include?('sysauth')111)112113if good_response114sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s115sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)116prevsessid = res.body.match(/((?:[a-z][a-z]*[0-9]+[a-z0-9]*))/)117118res = send_request_cgi(119{120'uri' => '/cgi-bin/luci',121'method' => 'POST',122'cookie' => sysauth_value,123'headers' => {124'X-Requested-With' => 'XMLHttpRequest',125'Accept' => 'application/json, text/javascript, */*; q=0.01',126'Connection' => 'close'127},128'vars_post' =>129{130'username' => user,131'password' => pass,132'prevsess' => prevsessid133}134}135)136137good_response = (138res &&139res.code == 200 &&140!res.body.include?('auth_failed')141)142143if good_response144print_good("SUCCESSFUL LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")145report_cred(146ip: rhost,147port: rport,148service_name: "Cambium ePMP 1000 version #{epmp_ver}",149user: user,150password: pass151)152153# check if max_user_number_reached?154if !res.body.include?('max_user_number_reached')155# get the cookie now156cookies = res.get_cookies_parsed157stok_value_dirty = res.body.match(/"stok": "(.*?)"/)158stok_value = "#{stok_value_dirty}".split('"')[3]159sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s160sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)161162final_cookie = "#{sysauth_value}usernameType_#{rport}=admin; stok_#{rport}=#{stok_value}"163164# create config_uri for different modules165config_uri_dump_config = '/cgi-bin/luci/;stok=' + stok_value + '/admin/config_export?opts=json'166config_uri_reset_pass = '/cgi-bin/luci/;stok=' + stok_value + '/admin/set_param'167config_uri_get_chart = '/cgi-bin/luci/;stok=' + stok_value + '/admin/get_chart'168169return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart170else171print_error('The credentials are correct but maximum number of logged-in users reached. Try again later.')172final_cookie = 'skip'173config_uri_dump_config = 'skip'174config_uri_reset_pass = 'skip'175config_uri_get_chart = 'skip'176return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart177end178else179print_error("FAILED LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")180final_cookie = 'skip'181config_uri_dump_config = 'skip'182config_uri_reset_pass = 'skip'183config_uri_get_chart = 'skip'184return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart185end186end187end188189# run if version < 3.4.1190def login_1(user, pass, epmp_ver)191res = send_request_cgi(192{193'uri' => '/cgi-bin/luci',194'method' => 'POST',195'headers' => {196'X-Requested-With' => 'XMLHttpRequest',197'Accept' => 'application/json, text/javascript, */*; q=0.01'198},199'vars_post' =>200{201'username' => 'dashboard',202'password' => ''203}204}205)206207cookies = res.get_cookies_parsed208check_sysauth = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s209210good_response = (211res &&212res.code == 200 &&213check_sysauth.include?('sysauth')214)215216if good_response217sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s218sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)219220cookie1 = "#{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"221222res = send_request_cgi(223{224'uri' => '/cgi-bin/luci',225'method' => 'POST',226'cookie' => cookie1,227'headers' => {228'X-Requested-With' => 'XMLHttpRequest',229'Accept' => 'application/json, text/javascript, */*; q=0.01',230'Connection' => 'close'231},232'vars_post' =>233{234'username' => user,235'password' => pass236}237}238)239240cookies = res.get_cookies_parsed241242good_response = (243res &&244res.code == 200 &&245!res.body.include?('auth_failed')246)247248if good_response249print_good("SUCCESSFUL LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")250report_cred(251ip: rhost,252port: rport,253service_name: "Cambium ePMP 1000 version #{epmp_ver}",254user: user,255password: pass256)257258# check if max_user_number_reached?259if !res.body.include?('max_user_number_reached')260# get the final cookie now261cookies = res.get_cookies_parsed262stok_value = cookies.has_key?('stok') && cookies['stok'].first263sysauth_dirty = cookies.values.select { |v| v.to_s =~ /sysauth_/ }.first.to_s264sysauth_value = sysauth_dirty.match(/((.*)[$ ])/)265266final_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_value267268# create config_uri for different modules269config_uri_dump_config = '/cgi-bin/luci/;stok=' + stok_value + '/admin/config_export?opts=json'270config_uri_reset_pass = '/cgi-bin/luci/;stok=' + stok_value + '/admin/set_param'271config_uri_get_chart = '/cgi-bin/luci/;stok=' + stok_value + '/admin/get_chart'272config_uri_ping = '/cgi-bin/luci/;stok=' + stok_value + '/admin/ping'273274return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart, config_uri_ping275else276print_error('The credentials are correct but maximum number of logged-in users reached. Try again later.')277final_cookie = 'skip'278config_uri_dump_config = 'skip'279config_uri_reset_pass = 'skip'280config_uri_get_chart = 'skip'281config_uri_ping = 'skip'282return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart, config_uri_ping283end284else285print_error("FAILED LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")286final_cookie = 'skip'287config_uri_dump_config = 'skip'288config_uri_reset_pass = 'skip'289config_uri_get_chart = 'skip'290config_uri_ping = 'skip'291return final_cookie, config_uri_dump_config, config_uri_reset_pass, config_uri_get_chart, config_uri_ping292end293end294end295end296end297298299