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

/modules/post/windows/recon/computer_browser_discovery.rb

https://bitbucket.org/DinoRex99/metasploit-framework
Ruby | 146 lines | 112 code | 21 blank | 13 comment | 8 complexity | 3624ba28be17b3110224bb93229f3996 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, GPL-3.0, GPL-2.0
  1. ##
  2. # This module requires Metasploit: https://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'msf/core/auxiliary/report'
  6. class MetasploitModule < Msf::Post
  7. include Msf::Auxiliary::Report
  8. def initialize(info={})
  9. super( update_info( info,
  10. 'Name' => 'Windows Recon Computer Browser Discovery',
  11. 'Description' => %q{ This module uses railgun to discover hostnames and IPs on the network.
  12. LTYPE should be set to one of the following values: WK (all workstations), SVR (all servers),
  13. SQL (all SQL servers), DC (all Domain Controllers), DCBKUP (all Domain Backup Servers),
  14. NOVELL (all Novell servers), PRINTSVR (all Print Que servers), MASTERBROWSER (all Master Browsers),
  15. WINDOWS (all Windows hosts), or UNIX (all Unix hosts).
  16. },
  17. 'License' => MSF_LICENSE,
  18. 'Author' => [ 'mubix' ],
  19. 'Platform' => [ 'win' ],
  20. 'SessionTypes' => [ 'meterpreter' ]
  21. ))
  22. register_options(
  23. [
  24. OptString.new('LTYPE', [true, 'Account informations (type info for known types)', 'WK']), # Enum would be a better choice
  25. OptString.new('DOMAIN', [false, 'Domain to perform lookups on, default is current domain',nil]),
  26. OptBool.new('SAVEHOSTS', [true, 'Save Discovered Hosts to the Database', false])
  27. ])
  28. end
  29. def parse_netserverenum(startmem,count)
  30. base = 0
  31. sys_list = []
  32. mem = client.railgun.memread(startmem, 24*count)
  33. count.times{|i|
  34. x = {}
  35. x[:platform_id] = mem[(base + 0),4].unpack("V*")[0]
  36. cnameptr = mem[(base + 4),4].unpack("V*")[0]
  37. x[:major_ver] = mem[(base + 8),4].unpack("V*")[0]
  38. x[:minor_ver] = mem[(base + 12),4].unpack("V*")[0]
  39. x[:type] = mem[(base + 16),4].unpack("V*")[0]
  40. commentptr = mem[(base + 20),4].unpack("V*")[0]
  41. x[:cname] = client.railgun.memread(cnameptr,27).split("\0\0")[0].split("\0").join
  42. x[:comment] = client.railgun.memread(commentptr,255).split("\0\0")[0].split("\0").join
  43. sys_list << x
  44. base = base + 24
  45. vprint_status("Identified: #{x[:cname]} - #{x[:comment]}")
  46. }
  47. return sys_list
  48. end
  49. def run
  50. ### MAIN ###
  51. client = session
  52. domain = nil
  53. # Default = SV_TYPE_NT
  54. # Servers = SV_TYPE_ALL
  55. # Workstations = SV_TYPE_WORKSTATION
  56. # Domain Controllers = SV_TYPE_DOMAINCTRL
  57. # Novell Server = SV_TYPE_NOVELL
  58. # Terminal Servers = SV_TYPE_TERMINALSERVER
  59. # SQL Servers = SV_TYPE_SQLSERVER
  60. lookuptype = 1
  61. case datastore['LTYPE']
  62. when 'WK' then lookuptype = "1".hex
  63. when 'SVR' then lookuptype = "2".hex
  64. when 'SQL' then lookuptype = "4".hex
  65. when 'DC' then lookuptype = "8".hex
  66. when 'DCBKUP' then lookuptype = "10".hex
  67. when 'TIME' then lookuptype = "20".hex
  68. when 'NOVELL' then lookuptype = "80".hex
  69. when 'PRINTSVR' then lookuptype = "200".hex
  70. when 'MASTERBROWSER' then lookuptype = "40000".hex
  71. when 'WINDOWS' then lookuptype = "400000".hex
  72. when 'UNIX' then lookuptype = "800".hex
  73. when 'LOCAL' then lookuptype = "40000000".hex
  74. end
  75. if session.arch == ARCH_X64
  76. nameiterator = 8
  77. size = 64
  78. addrinfoinmem = 32
  79. else
  80. nameiterator = 4
  81. size = 32
  82. addrinfoinmem = 24
  83. end
  84. result = client.railgun.netapi32.NetServerEnum(nil,101,4,-1,4,4,lookuptype,datastore['DOMAIN'],0)
  85. if result['totalentries'] == 0
  86. print_error("No systems found of that type")
  87. return
  88. end
  89. print_good("Found #{result['totalentries']} systems.")
  90. endofline = 0
  91. i = nameiterator
  92. netview = parse_netserverenum(result['bufptr'],result['totalentries'])
  93. ## get IP for host
  94. begin
  95. netview.each do |x|
  96. vprint_status("Looking up IP for #{x[:cname]}")
  97. print '.'
  98. result = client.net.resolve.resolve_host(x[:cname])
  99. if result[:ip].nil? or result[:ip].blank?
  100. print_error("There was an error resolving the IP for #{x[:cname]}")
  101. next
  102. else
  103. x[:ip] = result[:ip]
  104. end
  105. end
  106. rescue ::Exception => e
  107. print_error(e)
  108. print_status('Windows 2000 and prior does not support getaddrinfo')
  109. end
  110. netview = netview.sort_by {|e| e[:type]}
  111. results = Rex::Text::Table.new(
  112. 'Header' => 'Netdiscovery Results',
  113. 'Indent' => 2,
  114. 'Columns' => ['TYPE', 'IP', 'COMPUTER NAME', 'VERSION', 'COMMENT']
  115. )
  116. netview.each do |x|
  117. results << [x[:type], x[:ip], x[:cname], "#{x[:major_ver]}.#{x[:minor_ver]}", x[:comment]]
  118. report_host(:host => x[:ip]) if datastore['SAVEHOSTS'] and !(x[:ip].empty?)
  119. end
  120. print_status(results.to_s)
  121. store_loot("discovered.hosts", "text/plain", session, results.to_s, "discovered_hosts.txt", "Computer Browser Discovered Hosts")
  122. print_status('If none of the IP addresses show up you are running this from a Win2k or older system')
  123. print_status("If a host doesn't have an IP it either timed out or only has an IPv6 address assinged to it")
  124. end
  125. end