From b810a96dacfbc0aaa311e097a38639116a903961 Mon Sep 17 00:00:00 2001 From: Roberto Soares Date: Sat, 25 Apr 2015 04:41:33 -0300 Subject: [PATCH 1/5] Add Module for Enum on InfluxDB database. --- .../auxiliary/scanner/http/influxdb_enum.rb | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 modules/auxiliary/scanner/http/influxdb_enum.rb diff --git a/modules/auxiliary/scanner/http/influxdb_enum.rb b/modules/auxiliary/scanner/http/influxdb_enum.rb new file mode 100644 index 0000000000..7490f3d86c --- /dev/null +++ b/modules/auxiliary/scanner/http/influxdb_enum.rb @@ -0,0 +1,78 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'InfluxDB Enum Utility', + 'Description' => %q{ + This module enumerates databases on InfluxDB using the REST API + (using default authentication - root:root). + }, + 'References' => + [ + ['URL', 'http://influxdb.com/docs/v0.9/concepts/reading_and_writing_data.html'] + ], + 'Author' => [ 'Roberto Soares Espreto ' ], + 'License' => MSF_LICENSE + )) + + register_options( + [ + Opt::RPORT(8086), + OptString.new('TARGETURI', [true, 'Path to list all the databases', '/db']), + OptString.new('USERNAME', [true, 'The username to login as', 'root']), + OptString.new('PASSWORD', [true, 'The password to login with', 'root']) + ], self.class) + end + + def run + username = datastore['USERNAME'] + password = datastore['PASSWORD'] + + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path), + 'method' => 'GET', + 'authorization' => basic_auth(username, password) + ) + + if res && res.code == 401 + print_error("#{peer} - Failed to authenticate. Invalid username/password.") + return + end + + if res.code == 200 && res.headers['X-Influxdb-Version'].include?('InfluxDB') && res.body.length > 0 + print_status('Enumerating...') + begin + temp = JSON.parse(res.body) + results = JSON.pretty_generate(temp) + rescue JSON::ParserError + print_error('Unable to parse JSON data for the response.') + end + + print_good("Found:\n\n#{results}\n") + + path = store_loot( + 'influxdb.enum', + 'text/plain', + rhost, + results, + 'InfluxDB Enum' + ) + + print_good("#{peer} - File saved in: #{path}") + else + print_error("#{peer} - Unable to enum, received \"#{res.code}\".") + end + rescue => e + print_error("#{peer} - The following Error was encountered: #{e.class}") + end +end From 3a84396f3224e8dd6b104f307556eb90beb1ffde Mon Sep 17 00:00:00 2001 From: Roberto Soares Date: Sat, 25 Apr 2015 14:30:21 -0300 Subject: [PATCH 2/5] Removed authorization header. --- modules/auxiliary/scanner/http/influxdb_enum.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/auxiliary/scanner/http/influxdb_enum.rb b/modules/auxiliary/scanner/http/influxdb_enum.rb index 7490f3d86c..ec7c9d1688 100644 --- a/modules/auxiliary/scanner/http/influxdb_enum.rb +++ b/modules/auxiliary/scanner/http/influxdb_enum.rb @@ -35,13 +35,9 @@ class Metasploit3 < Msf::Auxiliary end def run - username = datastore['USERNAME'] - password = datastore['PASSWORD'] - res = send_request_cgi( 'uri' => normalize_uri(target_uri.path), - 'method' => 'GET', - 'authorization' => basic_auth(username, password) + 'method' => 'GET' ) if res && res.code == 401 From d01da0c522eac44a88b58eb742ba7823d42b93c4 Mon Sep 17 00:00:00 2001 From: Roberto Soares Date: Sat, 25 Apr 2015 15:08:36 -0300 Subject: [PATCH 3/5] Changed if conditions and exception handling --- .../auxiliary/scanner/http/influxdb_enum.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/auxiliary/scanner/http/influxdb_enum.rb b/modules/auxiliary/scanner/http/influxdb_enum.rb index ec7c9d1688..7591528bb6 100644 --- a/modules/auxiliary/scanner/http/influxdb_enum.rb +++ b/modules/auxiliary/scanner/http/influxdb_enum.rb @@ -35,23 +35,29 @@ class Metasploit3 < Msf::Auxiliary end def run - res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path), - 'method' => 'GET' - ) + begin + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path), + 'method' => 'GET' + ) + rescue ::Errno::EPIPE, ::Timeout::Error, ::EOFError, ::IOError => e + print_error("#{peer} - The following Error was encountered: #{e.class}") + return + end if res && res.code == 401 print_error("#{peer} - Failed to authenticate. Invalid username/password.") return end - if res.code == 200 && res.headers['X-Influxdb-Version'].include?('InfluxDB') && res.body.length > 0 + if res && res.code == 200 && res.headers['X-Influxdb-Version'].include?('InfluxDB') && res.body.length > 0 print_status('Enumerating...') begin temp = JSON.parse(res.body) results = JSON.pretty_generate(temp) rescue JSON::ParserError print_error('Unable to parse JSON data for the response.') + return end print_good("Found:\n\n#{results}\n") @@ -68,7 +74,5 @@ class Metasploit3 < Msf::Auxiliary else print_error("#{peer} - Unable to enum, received \"#{res.code}\".") end - rescue => e - print_error("#{peer} - The following Error was encountered: #{e.class}") end end From c41c7a1ba2bbee4c9349b7b30923bf794dde8e78 Mon Sep 17 00:00:00 2001 From: Roberto Soares Date: Sat, 25 Apr 2015 17:18:38 -0300 Subject: [PATCH 4/5] Rewrote the conditions of res. --- modules/auxiliary/scanner/http/influxdb_enum.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/auxiliary/scanner/http/influxdb_enum.rb b/modules/auxiliary/scanner/http/influxdb_enum.rb index 7591528bb6..356eae7940 100644 --- a/modules/auxiliary/scanner/http/influxdb_enum.rb +++ b/modules/auxiliary/scanner/http/influxdb_enum.rb @@ -45,23 +45,24 @@ class Metasploit3 < Msf::Auxiliary return end - if res && res.code == 401 - print_error("#{peer} - Failed to authenticate. Invalid username/password.") + unless res + print_error("#{peer} - Server did not respond in an expected way.") return end - if res && res.code == 200 && res.headers['X-Influxdb-Version'].include?('InfluxDB') && res.body.length > 0 + if res.code == 401 && res.body =~ /Invalid username\/password/ + print_error("#{peer} - Failed to authenticate. Invalid username/password.") + return + elsif res.code == 200 && res.headers.include?('X-Influxdb-Version') && res.body.length > 0 print_status('Enumerating...') begin temp = JSON.parse(res.body) results = JSON.pretty_generate(temp) rescue JSON::ParserError - print_error('Unable to parse JSON data for the response.') + print_error('Unable to parse JSON data.') return end - print_good("Found:\n\n#{results}\n") - path = store_loot( 'influxdb.enum', 'text/plain', @@ -69,10 +70,9 @@ class Metasploit3 < Msf::Auxiliary results, 'InfluxDB Enum' ) - print_good("#{peer} - File saved in: #{path}") else - print_error("#{peer} - Unable to enum, received \"#{res.code}\".") + print_error("#{peer} - Unable to enum, received \"#{res.code}\"") end end end From 005c36b2a60fd5b57303853c904c15e8e0afbcbb Mon Sep 17 00:00:00 2001 From: wchen-r7 Date: Thu, 14 May 2015 11:22:10 -0500 Subject: [PATCH 5/5] If data is empty, don't save (or even continue) --- modules/auxiliary/scanner/http/influxdb_enum.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/http/influxdb_enum.rb b/modules/auxiliary/scanner/http/influxdb_enum.rb index 356eae7940..c42f044c57 100644 --- a/modules/auxiliary/scanner/http/influxdb_enum.rb +++ b/modules/auxiliary/scanner/http/influxdb_enum.rb @@ -54,12 +54,16 @@ class Metasploit3 < Msf::Auxiliary print_error("#{peer} - Failed to authenticate. Invalid username/password.") return elsif res.code == 200 && res.headers.include?('X-Influxdb-Version') && res.body.length > 0 - print_status('Enumerating...') + print_status("#{peer} - Enumerating...") begin temp = JSON.parse(res.body) + if temp.blank? + print_status("#{peer} - Json data is empty") + return + end results = JSON.pretty_generate(temp) rescue JSON::ParserError - print_error('Unable to parse JSON data.') + print_error("#{peer} - Unable to parse JSON data.") return end print_good("Found:\n\n#{results}\n")