diff --git a/lib/msf/base/sessions/mysql.rb b/lib/msf/base/sessions/mysql.rb index 13353c4192f37..c3268772c5764 100644 --- a/lib/msf/base/sessions/mysql.rb +++ b/lib/msf/base/sessions/mysql.rb @@ -8,6 +8,8 @@ class Msf::Sessions::MySQL < Msf::Sessions::Sql # @param [Hash] opts def initialize(rstream, opts = {}) @client = opts.fetch(:client) + self.platform = opts.fetch(:platform) + self.arch = opts.fetch(:arch) self.console = ::Rex::Post::MySQL::Ui::Console.new(self) super(rstream, opts) end diff --git a/lib/rex/proto/mysql/client.rb b/lib/rex/proto/mysql/client.rb index 31ac3311e927b..b68924e879b0e 100644 --- a/lib/rex/proto/mysql/client.rb +++ b/lib/rex/proto/mysql/client.rb @@ -28,6 +28,39 @@ def current_database # Current database is stored as an array under the type 1 key. session_track.fetch(1, ['']).first end + + def map_compile_os_to_platform(compile_os) + return Msf::Platform::Unknown.realname if compile_os.blank? + + compile_os = compile_os.downcase.encode(::Encoding::BINARY) + + if compile_os.match?('linux') + platform = Msf::Platform::Linux + elsif compile_os.match?('unix') + platform = Msf::Platform::Unix + elsif compile_os.match?(/(darwin|mac|osx)/) + platform = Msf::Platform::OSX + elsif compile_os.match?('win') + platform = Msf::Platform::Windows + else + platform = Msf::Platform::Unknown + end + + platform.realname + end + + # @return [Hash] Detect the platform and architecture of the MySQL server: + # * :arch [String] The server architecture. + # * :platform [String] The server platform. + def detect_platform_and_arch + result = {} + + server_vars = query("show variables where variable_name in ('version_compile_machine', 'version_compile_os')").entries.to_h + result[:arch] = server_vars['version_compile_machine'] + result[:platform] = map_compile_os_to_platform(server_vars['version_compile_os']) + + result + end end end end diff --git a/modules/auxiliary/scanner/mysql/mysql_login.rb b/modules/auxiliary/scanner/mysql/mysql_login.rb index 0c9486965b9c9..ccaf698ae7946 100644 --- a/modules/auxiliary/scanner/mysql/mysql_login.rb +++ b/modules/auxiliary/scanner/mysql/mysql_login.rb @@ -198,7 +198,7 @@ def int_version(str) def session_setup(result) return unless (result.connection && result.proof) - my_session = Msf::Sessions::MySQL.new(result.connection, { client: result.proof }) + my_session = Msf::Sessions::MySQL.new(result.connection, { client: result.proof, **result.proof.detect_platform_and_arch }) merge_me = { 'USERPASS_FILE' => nil, 'USER_FILE' => nil, diff --git a/spec/lib/msf/base/sessions/mysql_spec.rb b/spec/lib/msf/base/sessions/mysql_spec.rb index 48a46ecc02a61..03013b56aabac 100644 --- a/spec/lib/msf/base/sessions/mysql_spec.rb +++ b/spec/lib/msf/base/sessions/mysql_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Msf::Sessions::MySQL do let(:client) { instance_double(::Rex::Proto::MySQL::Client) } - let(:opts) { { client: client } } + let(:opts) { { client: client, platform: 'Linux', arch: 'x86_64' } } let(:console_class) { Rex::Post::MySQL::Ui::Console } let(:user_input) { instance_double(Rex::Ui::Text::Input::Readline) } let(:user_output) { instance_double(Rex::Ui::Text::Output::Stdio) } diff --git a/spec/lib/rex/post/mysql/ui/console/command_dispatcher/core_spec.rb b/spec/lib/rex/post/mysql/ui/console/command_dispatcher/core_spec.rb index bb389ed81ab4a..9fbfbf43000f5 100644 --- a/spec/lib/rex/post/mysql/ui/console/command_dispatcher/core_spec.rb +++ b/spec/lib/rex/post/mysql/ui/console/command_dispatcher/core_spec.rb @@ -10,7 +10,7 @@ let(:address) { '192.0.2.1' } let(:port) { '3306' } let(:peerinfo) { "#{address}:#{port}" } - let(:session) { Msf::Sessions::MySQL.new(nil, { client: client }) } + let(:session) { Msf::Sessions::MySQL.new(nil, { client: client, platform: 'Linux', arch: 'x86_64' }) } let(:console) do console = Rex::Post::MySQL::Ui::Console.new(session) console.disable_output = true diff --git a/spec/lib/rex/proto/mysql/client_spec.rb b/spec/lib/rex/proto/mysql/client_spec.rb index 9813ef8631646..cae1a55534785 100644 --- a/spec/lib/rex/proto/mysql/client_spec.rb +++ b/spec/lib/rex/proto/mysql/client_spec.rb @@ -32,4 +32,25 @@ end end end + + describe '#map_compile_os_to_platform' do + [ + { info: 'linux', expected: 'Linux' }, + { info: 'linux2.6', expected: 'Linux' }, + { info: 'debian-linux-gnu', expected: 'Linux' }, + { info: 'win', expected: 'Windows' }, + { info: 'windows', expected: 'Windows' }, + { info: 'darwin', expected: 'OSX' }, + { info: 'osx', expected: 'OSX' }, + { info: 'macos', expected: 'OSX' }, + { info: 'unix', expected: 'Unix' }, + { info: '', expected: 'Unknown' }, + { info: 'blank', expected: 'Unknown' }, + { info: nil, expected: 'Unknown' }, + ].each do |test| + it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do + expect(subject.map_compile_os_to_platform(test[:info])).to eq(test[:expected]) + end + end + end end