PageRenderTime 35ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/post/windows/gather/enum_ad_mssql_srv.rb

https://github.com/darkoperator/Meterpreter-Scripts
Ruby | 151 lines | 129 code | 16 blank | 6 comment | 4 complexity | 93c5046779464330e74c023c9acc70aa MD5 | raw file
  1. # encoding: UTF-8
  2. require 'rex'
  3. require 'msf/core'
  4. class MetasploitModule < Msf::Post
  5. include Msf::Auxiliary::Report
  6. include Msf::Post::Windows::Registry
  7. include Msf::Post::Windows::ExtAPI
  8. def initialize(info = {})
  9. super( update_info(
  10. info,
  11. 'Name' => 'Windows Gather Active Directory MS SQL Servers',
  12. 'Description' => %Q{
  13. This module will enumerate MS SQL Server in the domain the host is
  14. a member of.
  15. },
  16. 'License' => BSD_LICENSE,
  17. 'Author' => 'Carlos Perez <carlos_perez[at]darkoperator.com>',
  18. 'Platform' => ['win'],
  19. 'SessionTypes' => ['meterpreter']
  20. ))
  21. register_options([
  22. OptString.new('DOMAIN_DN', [false, 'DN of the domain to enumerate.', nil]),
  23. OptBool.new('STORE_LOOT', [true, 'Store file in loot.', false]),
  24. OptInt.new('MAX_SEARCH', [false, 'Maximum values to retrieve, 0 for all.', 100])
  25. ], self.class)
  26. end
  27. def run
  28. print_status("Running module against #{sysinfo['Computer']}")
  29. if load_extapi
  30. domain_dn = get_default_naming_context
  31. unless domain_dn.nil?
  32. unless datastore['DOMAIN_DN'].nil?
  33. domain_dn = datastore['DOMAIN_DN']
  34. end
  35. table = Rex::Ui::Text::Table.new(
  36. 'Indent' => 4,
  37. 'SortIndex' => -1,
  38. 'Width' => 80,
  39. 'Columns' =>
  40. [
  41. 'Name',
  42. 'Distinguished Name',
  43. 'FQDN',
  44. 'Operating System',
  45. 'Service Pack',
  46. 'Address'
  47. ]
  48. )
  49. domain = domain_dn
  50. filter = '(&(objectCategory=computer)(servicePrincipalName=MSSQLSvc*))'
  51. query_result = session.extapi.adsi.domain_query(
  52. domain,
  53. filter,
  54. datastore['MAX_SEARCH'],
  55. datastore['MAX_SEARCH'],
  56. ['name',
  57. 'distinguishedname',
  58. 'dnshostname',
  59. 'operatingsystem',
  60. 'operatingSystemServicePack',
  61. 'servicePrincipalName'
  62. ]
  63. )
  64. if query_result[:results].length > 0
  65. query_result[:results].each do |obj|
  66. # Resolve IPv4 address
  67. begin
  68. ipv4_info = session.net.resolve.resolve_host(obj[2][:value], AF_INET)
  69. table << [obj[0][:value], obj[1][:value], obj[2][:value], obj[3][:value],obj[4][:value],ipv4_info[:ip]]
  70. service_pack = obj[4][:value].gsub('Service Pack', 'SP')
  71. # Save found DC in the database
  72. report_host(
  73. :host => ipv4_info[:ip],
  74. :os_name => 'Windows',
  75. :os_flavor => obj[3][:value],
  76. :name => obj[0][:value],
  77. :purpose => 'server',
  78. :comments => 'MS SQL Server',
  79. :os_sp => service_pack
  80. )
  81. rescue
  82. vprint_status 'Could not resolve IPv4 Address for Domain Controller'
  83. end
  84. # Resolve IPv6 address
  85. begin
  86. ipv6_info = session.net.resolve.resolve_host(obj[2][:value], AF_INET6)
  87. table << [obj[0][:value], obj[1][:value], obj[2][:value], obj[3][:value],obj[4][:value],ipv4_info[:ip]]
  88. service_pack = obj[4][:value].gsub('Service Pack', 'SP')
  89. # Save found DC in the database
  90. report_host(
  91. :host => ipv6_info[:ip],
  92. :os_name => 'Windows',
  93. :os_flavor => obj[3][:value],
  94. :name => obj[0][:value],
  95. :purpose => 'server',
  96. :comments => 'MS SQL Server',
  97. :os_sp => service_pack
  98. )
  99. rescue
  100. vprint_status 'Could not resolve IPv6 Address for Domain Controller'
  101. end
  102. end
  103. table.print
  104. print_line
  105. if datastore['STORE_LOOT']
  106. stored_path = store_loot('ad.mssql.servers', 'text/plain', session, table.to_csv)
  107. print_status("Results saved to: #{stored_path}")
  108. end
  109. else
  110. print_status("No MS SQL Servers found.")
  111. end
  112. end
  113. end
  114. end
  115. def get_dn
  116. dn = nil
  117. begin
  118. subkey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History'
  119. v_name = 'DCName'
  120. key_vals = registry_enumvals(subkey)
  121. if key_vals.include?(v_name)
  122. domain_dc = registry_getvaldata(subkey, v_name)
  123. # lets parse the information
  124. dom_info = domain_dc.split('.')
  125. dn = "DC=#{dom_info[1,dom_info.length].join(',DC=')}"
  126. else
  127. print_status 'Host is not part of a domain.'
  128. end
  129. rescue
  130. print_error('Could not determine if the host is part of a domain.')
  131. return nil
  132. end
  133. dn
  134. end
  135. end