Add arch/platform detection for Postgres

This commit is contained in:
cgranleese-r7
2024-04-12 11:43:30 +01:00
parent 53efed1606
commit 3f2e32ef6a
6 changed files with 135 additions and 5 deletions
+2
View File
@@ -9,6 +9,8 @@ class Msf::Sessions::PostgreSQL < Msf::Sessions::Sql
# @param opts [Msf::Db::PostgresPR::Connection] :client
def initialize(rstream, opts = {})
@client = opts.fetch(:client)
self.platform = opts.fetch(:platform)
self.arch = opts.fetch(:arch)
@console = ::Rex::Post::PostgreSQL::Ui::Console.new(self)
super(rstream, opts)
end
+87 -2
View File
@@ -129,12 +129,97 @@ class Connection
@conn.peerport
end
def peerinfo
"#{peerhost}:#{peerport}"
end
def current_database
@params['database']
end
def peerinfo
"#{peerhost}:#{peerport}"
# List of supported PostgreSQL platforms & architectures:
# https://postgrespro.com/docs/postgresql/16/supported-platforms
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?(/(darwin|mac|osx)/)
platform = Msf::Platform::OSX
elsif compile_os.match?('win')
platform = Msf::Platform::Windows
elsif compile_os.match?('free')
platform = Msf::Platform::FreeBSD
elsif compile_os.match?('net')
platform = Msf::Platform::NetBSD
elsif compile_os.match?('open')
platform = Msf::Platform::OpenBSD
elsif compile_os.match?('solaris')
platform = Msf::Platform::Solaris
elsif compile_os.match?('aix')
platform = Msf::Platform::AIX
elsif compile_os.match?('hpux')
platform = Msf::Platform::HPUX
elsif compile_os.match?('irix')
platform = Msf::Platform::Irix
else
# Return the query result if the value can't be mapped
return compile_os
end
platform.realname
end
# List of supported PostgreSQL platforms & architectures:
# https://postgrespro.com/docs/postgresql/16/supported-platforms
def map_compile_arch_to_architecture(compile_arch)
return '' if compile_arch.blank?
compile_arch = compile_arch.downcase.encode(::Encoding::BINARY)
if compile_arch.match?('sparc')
if compile_arch.include?('64')
arch = ARCH_SPARC64
else
arch = ARCH_SPARC
end
elsif compile_arch.include?('mips')
arch = ARCH_MIPS
elsif compile_arch.include?('ppc')
arch = ARCH_PPC
elsif compile_arch.match?('arm')
arch = ARCH_AARCH64
elsif compile_arch.match?('64')
arch = ARCH_X86_64
elsif compile_arch.match?('86') || compile_arch.match?('i686')
arch = ARCH_X86
else
# Return the query result if the value can't be mapped
arch = compile_arch
end
arch
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 = {}
query_result = query('select version()').rows.join.match(/.*on (\w+-\w+-\w+-\w+)/).captures
server_var = query_result.join.split('-', 2)
server_vars = {
'version_compile_machine' => server_var[0],
'version_compile_os' => server_var[1]
}
result[:arch] = map_compile_arch_to_architecture(server_vars['version_compile_machine'])
result[:platform] = map_compile_os_to_platform(server_vars['version_compile_os'])
result
end
def close
@@ -147,7 +147,7 @@ class MetasploitModule < Msf::Auxiliary
def session_setup(result)
return unless (result.connection && result.proof)
my_session = Msf::Sessions::PostgreSQL.new(result.connection, { client: result.proof })
my_session = Msf::Sessions::PostgreSQL.new(result.connection, { client: result.proof, **result.proof.detect_platform_and_arch })
merge_me = {
'USERPASS_FILE' => nil,
'USER_FILE' => nil,
@@ -5,7 +5,7 @@ require 'postgres/postgres-pr/connection'
RSpec.describe Msf::Sessions::PostgreSQL do
let(:client) { instance_double(Msf::Db::PostgresPR::Connection) }
let(:opts) { { client: client } }
let(:opts) { { client: client, platform: Msf::Platform::Linux.realname, arch: ARCH_X86_64 } }
let(:console_class) { Rex::Post::PostgreSQL::Ui::Console }
let(:user_input) { instance_double(Rex::Ui::Text::Input::Readline) }
let(:user_output) { instance_double(Rex::Ui::Text::Output::Stdio) }
@@ -10,7 +10,7 @@ RSpec.describe Rex::Post::PostgreSQL::Ui::Console::CommandDispatcher::Core do
let(:port) { '5432' }
let(:current_database) { 'template1' }
let(:peer_info) { "#{address}:#{port}" }
let(:session) { Msf::Sessions::PostgreSQL.new(nil, { client: client }) }
let(:session) { Msf::Sessions::PostgreSQL.new(nil, { client: client, platform: Msf::Platform::Linux.realname, arch: ARCH_X86_64 }) }
let(:console) do
console = Rex::Post::PostgreSQL::Ui::Console.new(session)
console.disable_output = true
@@ -20,4 +20,47 @@ RSpec.describe Msf::Db::PostgresPR::Connection do
end
it_behaves_like 'session compatible SQL client'
describe '#map_compile_os_to_platform' do
[
{ info: 'linux', expected: Msf::Platform::Linux.realname },
{ info: 'linux2.6', expected: Msf::Platform::Linux.realname },
{ info: 'debian-linux-gnu', expected: Msf::Platform::Linux.realname },
{ info: 'win', expected: Msf::Platform::Windows.realname },
{ info: 'windows', expected: Msf::Platform::Windows.realname },
{ info: 'darwin', expected: Msf::Platform::OSX.realname },
{ info: 'osx', expected: Msf::Platform::OSX.realname },
{ info: 'macos', expected: Msf::Platform::OSX.realname },
{ info: 'solaris', expected: Msf::Platform::Solaris.realname },
{ info: 'aix', expected: Msf::Platform::AIX.realname },
{ info: 'hpux', expected: Msf::Platform::HPUX.realname },
{ info: 'irix', expected: Msf::Platform::Irix.realname },
].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
describe '#map_compile_arch_to_architecture' do
[
{ info: 'x86_64', expected: ARCH_X86_64 },
{ info: 'x86_x64', expected: ARCH_X86_64 },
{ info: 'x64', expected: ARCH_X86_64 },
{ info: '64', expected: ARCH_X86_64 },
{ info: 'x86', expected: ARCH_X86 },
{ info: '86', expected: ARCH_X86 },
{ info: 'i686', expected: ARCH_X86 },
{ info: 'arm64', expected: ARCH_AARCH64 },
{ info: 'arm', expected: ARCH_AARCH64 },
{ info: 'sparc', expected: ARCH_SPARC },
{ info: 'sparc64', expected: ARCH_SPARC64 },
{ info: 'ppc', expected: ARCH_PPC },
{ info: 'mips', expected: ARCH_MIPS },
].each do |test|
it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do
expect(subject.map_compile_arch_to_architecture(test[:info])).to eq(test[:expected])
end
end
end
end