1
- ##
2
- # $Id: smtp_enum.rb 14774 2012-02-21 01:42:17Z rapid7 $
3
- ##
4
-
5
1
##
6
2
# This file is part of the Metasploit Framework and may be subject to
7
3
# redistribution and commercial restrictions. Please see the Metasploit
@@ -21,7 +17,6 @@ class Metasploit3 < Msf::Auxiliary
21
17
def initialize
22
18
super (
23
19
'Name' => 'SMTP User Enumeration Utility' ,
24
- 'Version' => '$Revision: 14774 $' ,
25
20
'Description' => %q{
26
21
The SMTP service has two internal commands that allow the enumeration
27
22
of users: VRFY (confirming the names of valid users) and EXPN (which
@@ -58,10 +53,6 @@ def initialize
58
53
deregister_options ( 'MAILTO' , 'MAILFROM' )
59
54
end
60
55
61
- def target
62
- "#{ rhost } :#{ rport } "
63
- end
64
-
65
56
def smtp_send ( data = nil )
66
57
begin
67
58
result = ''
@@ -74,7 +65,7 @@ def smtp_send(data=nil)
74
65
rescue Rex ::ConnectionError , Errno ::ECONNRESET , ::EOFError
75
66
return result , code
76
67
rescue ::Exception => e
77
- print_error ( "#{ target } Error smtp_send: '#{ e . class } ' '#{ e } ' ' #{ e . backtrace } '" )
68
+ print_error ( "#{ rhost } : #{ rport } Error smtp_send: '#{ e . class } ' '#{ e } '" )
78
69
return nil , 0
79
70
end
80
71
end
@@ -92,16 +83,16 @@ def run_host(ip)
92
83
connect
93
84
result , code = smtp_send ( cmd )
94
85
95
- if ( not result or result == nil )
96
- print_error ( "#{ target } Connection but no data...skipping" )
86
+ if ( not result )
87
+ print_error ( "#{ rhost } : #{ rport } Connection but no data...skipping" )
97
88
return
98
89
end
99
90
banner . chomp! if ( banner )
100
91
if ( banner =~ /microsoft/i and datastore [ 'UNIXONLY' ] )
101
- print_status ( "#{ target } Skipping microsoft (#{ banner } )" )
92
+ print_status ( "#{ rhost } : #{ rport } Skipping microsoft (#{ banner } )" )
102
93
return
103
94
elsif ( banner )
104
- print_status ( "#{ target } Banner: #{ banner } " )
95
+ print_status ( "#{ rhost } : #{ rport } Banner: #{ banner } " )
105
96
end
106
97
107
98
domain = result . split ( ) [ 1 ]
@@ -111,13 +102,13 @@ def run_host(ip)
111
102
vprint_status ( "#{ ip } :#{ rport } Domain Name: #{ domain } " )
112
103
113
104
result , code = smtp_send ( "VRFY root\r \n " )
114
- vrfy = false if ( code ! = 250 )
105
+ vrfy = ( code = = 250 )
115
106
users_found = do_enum ( 'VRFY' , usernames ) if ( vrfy )
116
107
117
108
if ( users_found . empty? )
118
109
# VRFY failed, lets try EXPN
119
110
result , code = smtp_send ( "EXPN root\r \n " )
120
- expn = false if ( code ! = 250 )
111
+ expn = ( code = = 250 )
121
112
users_found = do_enum ( 'EXPN' , usernames ) if ( expn )
122
113
end
123
114
@@ -128,7 +119,7 @@ def run_host(ip)
128
119
user = Rex ::Text . rand_text_alpha ( 8 )
129
120
result , code = smtp_send ( "RCPT TO: #{ user } \@ #{ domain } \r \n " )
130
121
if ( code >= 250 and code <= 259 )
131
- vprint_status ( "#{ target } RCPT TO: Allowed for random user (#{ user } )...not reliable? #{ code } '#{ result } '" )
122
+ vprint_status ( "#{ rhost } : #{ rport } RCPT TO: Allowed for random user (#{ user } )...not reliable? #{ code } '#{ result } '" )
132
123
rcpt = false
133
124
else
134
125
smtp_send ( "RSET\r \n " )
@@ -140,39 +131,38 @@ def run_host(ip)
140
131
end
141
132
142
133
if ( not vrfy and not expn and not rcpt )
143
- print_status ( "#{ target } could not be enumerated (no EXPN, no VRFY, invalid RCPT)" )
134
+ print_status ( "#{ rhost } : #{ rport } could not be enumerated (no EXPN, no VRFY, invalid RCPT)" )
144
135
return
145
136
end
146
137
finish_host ( users_found )
147
138
disconnect
148
139
149
140
rescue Rex ::ConnectionError , Errno ::ECONNRESET , Rex ::ConnectionTimeout , EOFError , Errno ::ENOPROTOOPT
150
141
rescue ::Exception => e
151
- print_error ( ( e . to_str == 'execution expired' ) ? "Error: #{ target } Execution expired" : "Error: #{ target } '#{ e . class } ' '#{ e } ' ' #{ e . backtrace } '")
142
+ print_error ( "Error: #{ rhost } : #{ rport } '#{ e . class } ' '#{ e } '" )
152
143
end
153
144
154
145
def finish_host ( users_found )
155
- ip , port = target . split ( ':' )
156
146
if users_found and not users_found . empty?
157
- print_good ( "#{ target } Users found: #{ users_found . sort . join ( ", " ) } " )
147
+ print_good ( "#{ rhost } : #{ rport } Users found: #{ users_found . sort . join ( ", " ) } " )
158
148
report_note (
159
- :host => ip ,
160
- :port => port ,
149
+ :host => rhost ,
150
+ :port => rport ,
161
151
:type => 'smtp.users' ,
162
152
:data => { :users => users_found . join ( ", " ) }
163
153
)
164
154
end
165
155
end
166
156
167
157
def kiss_and_make_up ( cmd )
168
- vprint_status ( "#{ target } SMTP server annoyed...reconnecting and saying HELO again..." )
158
+ vprint_status ( "#{ rhost } : #{ rport } SMTP server annoyed...reconnecting and saying HELO again..." )
169
159
disconnect
170
160
connect
171
161
smtp_send ( "HELO localhost\r \n " )
172
162
result , code = smtp_send ( "#{ cmd } " )
173
163
result . chomp!
174
164
cmd . chomp!
175
- vprint_status ( "#{ target } - SMTP - Re-trying #{ cmd } received #{ code } '#{ result } '" )
165
+ vprint_status ( "#{ rhost } : #{ rport } - SMTP - Re-trying #{ cmd } received #{ code } '#{ result } '" )
176
166
return result , code
177
167
end
178
168
@@ -182,10 +172,10 @@ def do_enum(cmd, usernames)
182
172
usernames . each { |user |
183
173
next if user . downcase == 'root'
184
174
result , code = smtp_send ( "#{ cmd } #{ user } \r \n " )
185
- vprint_status ( "#{ target } - SMTP - Trying #{ cmd } #{ user } received #{ code } '#{ result } '" )
175
+ vprint_status ( "#{ rhost } : #{ rport } - SMTP - Trying #{ cmd } #{ user } received #{ code } '#{ result } '" )
186
176
result , code = kiss_and_make_up ( "#{ cmd } #{ user } \r \n " ) if ( code == 0 and result . to_s == '' )
187
177
if ( code == 250 )
188
- vprint_status ( "#{ target } - Found user: #{ user } " )
178
+ vprint_status ( "#{ rhost } : #{ rport } - Found user: #{ user } " )
189
179
users . push ( user )
190
180
end
191
181
}
@@ -196,7 +186,7 @@ def do_rcpt_enum(domain, usernames)
196
186
users = [ ]
197
187
usernames . each { |user |
198
188
next if user . downcase == 'root'
199
- vprint_status ( "#{ target } - SMTP - Trying MAIL FROM: root\@ #{ domain } / RCPT TO: #{ user } ..." )
189
+ vprint_status ( "#{ rhost } : #{ rport } - SMTP - Trying MAIL FROM: root\@ #{ domain } / RCPT TO: #{ user } ..." )
200
190
result , code = smtp_send ( "MAIL FROM: root\@ #{ domain } \r \n " )
201
191
result , code = kiss_and_make_up ( "MAIL FROM: root\@ #{ domain } \r \n " ) if ( code == 0 and result . to_s == '' )
202
192
@@ -208,11 +198,11 @@ def do_rcpt_enum(domain, usernames)
208
198
end
209
199
210
200
if ( code == 250 )
211
- vprint_status ( "#{ target } - Found user: #{ user } " )
201
+ vprint_status ( "#{ rhost } : #{ rport } - Found user: #{ user } " )
212
202
users . push ( user )
213
203
end
214
204
else
215
- vprint_status ( "#{ target } MAIL FROM: #{ user } NOT allowed during brute...aborting ( '#{ code } ' '#{ result } ')" )
205
+ vprint_status ( "#{ rhost } : #{ rport } MAIL FROM: #{ user } NOT allowed during brute...aborting ( '#{ code } ' '#{ result } ')" )
216
206
break
217
207
end
218
208
smtp_send ( "RSET\r \n " )
0 commit comments