Skip to content

Commit ea8e62f

Browse files
committed
Add #file_dropper_file_exist?
1 parent 129ed7f commit ea8e62f

File tree

1 file changed

+62
-84
lines changed

1 file changed

+62
-84
lines changed

lib/msf/core/exploit/file_dropper.rb

Lines changed: 62 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
module Msf
44
module Exploit::FileDropper
55

6-
attr_accessor :session
7-
86
def initialize(info = {})
97
super
108

@@ -14,23 +12,6 @@ def initialize(info = {})
1412
], self.class)
1513
end
1614

17-
# When a new session is created, attempt to delete any files that the
18-
# exploit created.
19-
#
20-
# @param (see Msf::Exploit#on_new_session)
21-
# @return [void]
22-
def on_new_session(session)
23-
super
24-
25-
print_status("new session...")
26-
puts "#{self.session}"
27-
if self.payload
28-
puts "#{self.payload.session}"
29-
end
30-
on_new_session_job(session)
31-
end
32-
33-
#
3415
# Record file as needing to be cleaned up
3516
#
3617
# @param files [Array<String>] List of paths on the target that should
@@ -49,7 +30,32 @@ def register_files_for_cleanup(*files)
4930
# Singular version
5031
alias register_file_for_cleanup register_files_for_cleanup
5132

33+
# When a new session is created, attempt to delete any files that the
34+
# exploit created.
5235
#
36+
# @param (see Msf::Exploit#on_new_session)
37+
# @return [void]
38+
def on_new_session(session)
39+
super
40+
41+
if session.type == 'meterpreter'
42+
session.core.use('stdapi') unless session.ext.aliases.include?('stdapi')
43+
end
44+
45+
unless @dropped_files && @dropped_files.length > 0
46+
return
47+
end
48+
49+
@dropped_files.delete_if do |file|
50+
exists_before = file_dropper_file_exist?(session, file)
51+
if file_dropper_delete(session, file)
52+
file_dropper_deleted?(session, file, exists_before)
53+
else
54+
false
55+
end
56+
end
57+
end
58+
5359
# While the exploit cleanup do a last attempt to delete any files created
5460
# if there is a file_rm method available. Warn the user if any files were
5561
# not cleaned up.
@@ -93,78 +99,44 @@ def cleanup
9399

94100
private
95101

96-
# Takes a new session and makes the drop files task
102+
# See if +path+ exists on the remote system and is a regular file
97103
#
98-
# @param (see Msf::Exploit#on_new_session)
99-
# @return [void]
100-
# @note This methods needs to overwrite *and restore* the original
101-
# `session` attribute
102-
def on_new_session_job(new_session)
103-
session_orig = session
104-
self.session = new_session
105-
106-
begin
107-
file_dropper_delete_files
108-
ensure
109-
self.session = session_orig
110-
end
111-
end
112-
113-
# Uses the exploit `session` to delete files on the `dropped_files` list
114-
#
115-
# @return [void]
116-
def file_dropper_delete_files
117-
if session.type == 'meterpreter'
118-
session.core.use('stdapi') unless session.ext.aliases.include?('stdapi')
119-
end
120-
121-
unless @dropped_files && @dropped_files.length > 0
122-
return
123-
end
124-
125-
@dropped_files.delete_if do |file|
126-
puts "Deleting #{file}"
127-
exists_before = file_dropper_check_file(file)
128-
if file_dropper_delete(file)
129-
file_dropper_deleted?(file, exists_before)
130-
else
131-
false
132-
end
133-
end
134-
end
135-
136-
# Check if a file exists in the `session` file system
137-
#
138-
# @param [String] file The file to check
104+
# @param path [String] Remote filename to check
139105
# @return [TrueClass] If the file exists
140106
# @return [FalseClass] If the file doesn't exist
141-
def file_dropper_check_file(file)
142-
puts "Checking file... #{file}"
107+
def file_dropper_file_exist?(session, path)
143108
if session.platform =~ /win/
144-
normalized = file_dropper_win_file(file)
109+
normalized = file_dropper_win_file(path)
145110
else
146-
normalized = file
111+
normalized = path
147112
end
148113

149-
puts "Checking normalized file... #{file}"
150-
Msf::Post::File.file_exist?(normalized)
151-
end
114+
if session.type == 'meterpreter'
115+
stat = session.fs.file.stat(normalized) rescue nil
116+
return false unless stat
117+
stat.file?
118+
else
119+
if session.platform =~ /win/
120+
f = shell_command_token("cmd.exe /C IF exist \"#{normalized}\" ( echo true )")
121+
if f =~ /true/
122+
f = shell_command_token("cmd.exe /C IF exist \"#{normalized}\\\\\" ( echo false ) ELSE ( echo true )")
123+
end
124+
else
125+
f = session.shell_command_token("test -f \"#{normalized}\" && echo true")
126+
end
152127

153-
# Converts a file path to use the windows separator '\'
154-
#
155-
# @param [String] file The file path to convert
156-
# @return [String] The file path converted
157-
def file_dropper_win_file(file)
158-
file.gsub('/', "\\\\")
128+
return false if f.nil? || f.empty?
129+
return false unless f =~ /true/
130+
true
131+
end
159132
end
160133

161-
# Sends a file deletion command to the remote `session`
134+
# Sends a file deletion command to the remote +session+
162135
#
163136
# @param [String] file The file to delete
164-
# @return [TrueClass] If the delete command has been executed in the remote machine
165-
# @return [FalseClass] Otherwise
166-
def file_dropper_delete(file)
167-
puts "Deleting #{file}"
137+
# @return [TrueClass] the delete command has been executed in the remote machine
138+
# @return [FalseClass] otherwise
139+
def file_dropper_delete(session, file)
168140
win_file = file_dropper_win_file(file)
169141

170142
if session.type == 'meterpreter'
@@ -181,7 +153,6 @@ def file_dropper_delete(file)
181153
false
182154
end
183155
else
184-
puts "Deleting with shell"
185156
win_cmds = [
186157
%Q|attrib.exe -r "#{win_file}"|,
187158
%Q|del.exe /f /q "#{win_file}"|
@@ -201,12 +172,11 @@ def file_dropper_delete(file)
201172
# Checks if a file has been deleted by the current job
202173
#
203174
# @param [String] file The file to check
204-
# @param [TrueClass] exists_before Indicates if the file existed before the cleanup job
175+
# @param [TrueClass] exists_before Indicates if the file existed before the deletion
205176
# @return [TrueClass] if the file has been deleted or it cannot resolve
206177
# @return [FalseClass] if the file hasn't been deleted
207-
def file_dropper_deleted?(file, exists_before)
208-
puts "Deleted? ... #{file}"
209-
if exists_before && file_dropper_check_file(file)
178+
def file_dropper_deleted?(session, file, exists_before)
179+
if exists_before && file_dropper_file_exist?(session, file)
210180
print_error("Unable to delete #{file}")
211181
false
212182
elsif exists_before
@@ -218,5 +188,13 @@ def file_dropper_deleted?(file, exists_before)
218188
end
219189
end
220190

191+
# Converts a file path to use the windows separator '\'
192+
#
193+
# @param [String] file The file path to convert
194+
# @return [String] The file path converted
195+
def file_dropper_win_file(file)
196+
file.gsub('/', '\\\\')
197+
end
198+
221199
end
222200
end

0 commit comments

Comments
 (0)