|
1 | 1 | ## |
2 | | -# This module requires Metasploit: http//metasploit.com/download |
| 2 | +# This module requires Metasploit: http://metasploit.com/download |
3 | 3 | # Current source: https://github.com/rapid7/metasploit-framework |
4 | 4 | ## |
5 | 5 |
|
6 | 6 | require 'msf/core' |
7 | 7 |
|
8 | 8 | class Metasploit3 < Msf::Auxiliary |
9 | | - |
10 | 9 | include Msf::Exploit::Remote::SNMPClient |
11 | 10 | include Msf::Auxiliary::Report |
12 | 11 | include Msf::Auxiliary::Scanner |
| 12 | + include SNMP |
13 | 13 |
|
14 | 14 | def initialize |
15 | 15 | super( |
16 | 16 | 'Name' => 'SNMP Windows Username Enumeration', |
17 | | - 'Description' => "This module will use LanManager/psProcessUsername OID values to enumerate local user accounts on a Windows/Solaris system via SNMP", |
| 17 | + 'Description' => ' |
| 18 | + This module will use LanManager/psProcessUsername OID values to |
| 19 | + enumerate local user accounts on a Windows/Solaris system via SNMP |
| 20 | + ', |
18 | 21 | 'Author' => ['tebo[at]attackresearch.com'], |
19 | 22 | 'License' => MSF_LICENSE |
20 | 23 | ) |
21 | | - |
22 | 24 | end |
23 | 25 |
|
24 | 26 | def run_host(ip) |
| 27 | + peer = "#{ip}:#{rport}" |
25 | 28 | begin |
26 | 29 | snmp = connect_snmp |
27 | 30 |
|
28 | 31 | sys_desc = snmp.get_value('sysDescr.0') |
29 | | - @users = [] |
30 | | - case sys_desc |
31 | | - when /Windows/ |
32 | | - snmp.walk("1.3.6.1.4.1.77.1.2.25") do |row| |
33 | | - row.each { |val| @users << val.value.to_s } |
34 | | - end |
35 | | - when /Sun/ |
36 | | - snmp.walk("1.3.6.1.4.1.42.3.12.1.8") do |row| |
37 | | - row.each { |val| @users << val.value.to_s } |
38 | | - end |
| 32 | + if sys_desc.blank? || sys_desc.to_s == 'Null' |
| 33 | + vprint_error("#{peer} No sysDescr received") |
| 34 | + return |
39 | 35 | end |
40 | | - unless @users.empty? |
41 | | - @users.sort! |
42 | | - @users.uniq! |
43 | | - print_good("#{ip} Found Users: #{@users.size} users: #{@users.join(', ')}") |
| 36 | + sys_desc = sys_desc.split(/[\r\n]/).join(' ') |
| 37 | + |
| 38 | + sys_desc_map = { |
| 39 | + /Windows/ => '1.3.6.1.4.1.77.1.2.25', |
| 40 | + /Sun/ => '1.3.6.1.4.1.42.3.12.1.8' |
| 41 | + } |
| 42 | + |
| 43 | + matching_oids = sys_desc_map.select { |re, _| sys_desc =~ re }.values |
| 44 | + if matching_oids.empty? |
| 45 | + vprint_warning("#{peer} Skipping unsupported sysDescr: '#{sys_desc}'") |
| 46 | + return |
44 | 47 | end |
| 48 | + users = [] |
45 | 49 |
|
46 | | - disconnect_snmp |
| 50 | + matching_oids.each do |oid| |
| 51 | + snmp.walk(oid) do |row| |
| 52 | + row.each { |val| users << val.value.to_s } |
| 53 | + end |
| 54 | + end |
| 55 | + unless users.empty? |
| 56 | + users.sort! |
| 57 | + users.uniq! |
| 58 | + print_good("#{peer} Found #{users.size} users: #{users.join(', ')}") |
| 59 | + end |
47 | 60 |
|
48 | 61 | report_note( |
49 | | - :host => rhost, |
50 | | - :port => datastore['RPORT'], |
51 | | - :proto => 'udp', |
52 | | - :sname => 'snmp', |
53 | | - :update => :unique_data, |
54 | | - :type => 'snmp.users', |
55 | | - :data => @users |
| 62 | + host: rhost, |
| 63 | + port: rport, |
| 64 | + proto: 'udp', |
| 65 | + sname: 'snmp', |
| 66 | + update: :unique_data, |
| 67 | + type: 'snmp.users', |
| 68 | + data: users |
56 | 69 | ) |
57 | | - |
58 | | - |
59 | | - rescue ::SNMP::UnsupportedVersion |
60 | | - rescue ::SNMP::RequestTimeout |
61 | | - rescue ::Interrupt |
62 | | - raise $! |
63 | | - rescue ::Exception => e |
64 | | - print_error("Unknown error: #{e.class} #{e}") |
| 70 | + rescue ::SNMP::RequestTimeout, ::SNMP::UnsupportedVersion |
| 71 | + # too noisy for a scanner |
| 72 | + ensure |
| 73 | + disconnect_snmp |
65 | 74 | end |
66 | | - |
67 | 75 | end |
68 | | - |
69 | 76 | end |
0 commit comments