Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

enum_ad_groups.rb 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ##
  2. # This module requires Metasploit: http://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'rex'
  6. require 'msf/core'
  7. class MetasploitModule < Msf::Post
  8. include Msf::Auxiliary::Report
  9. include Msf::Post::Windows::LDAP
  10. # include Msf::Post::Windows::Accounts
  11. USER_FIELDS = ['name',
  12. 'distinguishedname',
  13. 'description'].freeze
  14. def initialize(info = {})
  15. super(update_info(
  16. info,
  17. 'Name' => 'Windows Gather Active Directory Groups',
  18. 'Description' => %(
  19. This module will enumerate AD groups on the specified domain.
  20. ),
  21. 'License' => MSF_LICENSE,
  22. 'Author' => [
  23. 'Stuart Morgan <stuart.morgan[at]mwrinfosecurity.com>'
  24. ],
  25. 'Platform' => [ 'win' ],
  26. 'SessionTypes' => [ 'meterpreter' ]
  27. ))
  28. register_options([
  29. OptString.new('ADDITIONAL_FIELDS', [false, 'Additional fields to retrieve, comma separated', nil]),
  30. OptString.new('FILTER', [false, 'Customised LDAP filter', nil])
  31. ], self.class)
  32. end
  33. def run
  34. @user_fields = USER_FIELDS.dup
  35. if datastore['ADDITIONAL_FIELDS']
  36. additional_fields = datastore['ADDITIONAL_FIELDS'].gsub(/\s+/, "").split(',')
  37. @user_fields.push(*additional_fields)
  38. end
  39. max_search = datastore['MAX_SEARCH']
  40. begin
  41. f = ""
  42. f = "(#{datastore['FILTER']})" if datastore['FILTER']
  43. q = query("(&(objectClass=group)#{f})", max_search, @user_fields)
  44. rescue ::RuntimeError, ::Rex::Post::Meterpreter::RequestError => e
  45. # Can't bind or in a network w/ limited accounts
  46. print_error(e.message)
  47. return
  48. end
  49. if q.nil? || q[:results].empty?
  50. print_status('No results returned.')
  51. else
  52. results_table = parse_results(q[:results])
  53. print_line results_table.to_s
  54. end
  55. end
  56. # Takes the results of LDAP query, parses them into a table
  57. # and records and usernames as {Metasploit::Credential::Core}s in
  58. # the database.
  59. #
  60. # @param [Array<Array<Hash>>] the LDAP query results to parse
  61. # @return [Rex::Text::Table] the table containing all the result data
  62. def parse_results(results)
  63. # Results table holds raw string data
  64. results_table = Rex::Text::Table.new(
  65. 'Header' => "Domain Groups",
  66. 'Indent' => 1,
  67. 'SortIndex' => -1,
  68. 'Columns' => @user_fields
  69. )
  70. results.each do |result|
  71. row = []
  72. result.each do |field|
  73. if field.nil?
  74. row << ""
  75. else
  76. row << field[:value]
  77. end
  78. end
  79. results_table << row
  80. end
  81. results_table
  82. end
  83. end