Class: Rex::Post::Meterpreter::Extensions::Stdapi::Fs::File

Inherits:
IO
  • Object
show all
Includes:
File
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb

Overview

This class implements the Rex::Post::File interface and wraps interaction with files on the remote machine.

Constant Summary collapse

SEPARATOR =
"\\"
Separator =
"\\"

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from File

atime, blockdev?, chardev?, chmod, chown, ctime, delete, directory?, dirname, executable?, executable_real?, extname, file?, fnmatch, fnmatch?, ftype, grpowned?, join, lchmod, lchown, link, lstat, mtime, owned?, #path, pipe?, readable?, readable_real?, setgid?, setuid?, size, socket?, sticky?, symlink?, writeable?, writeable_real?, zero?

Methods inherited from IO

#close, #sysread, #syswrite

Methods inherited from IO

#binmode, #close, #close_read, #close_write, #closed?, #each, #each_byte, #each_line, #eof?, #fcntl, #flush, #fsync, #getc, #gets, #ioctl, #isatty, #lineno, #print, #printf, #putc, #puts, #read, #readchar, #readline, #readlines, #rewind, #stat, #sync, #sysread, #syswrite, #tell, #tty?, #ungetc, #write

Constructor Details

#initialize(name, mode = "r", perms = 0) ⇒ File

Initializes and opens the specified file with the specified permissions.



215
216
217
218
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 215

def initialize(name, mode = "r", perms = 0)
	self.client = self.class.client
	self.filed  = _open(name, mode, perms)
end

Class Attribute Details

.clientObject

Returns the value of attribute client.



32
33
34
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 32

def client
  @client
end

Class Method Details

.basename(*a) ⇒ Object

Returns the base name of the supplied file path to the caller.



69
70
71
72
73
74
75
76
77
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 69

def File.basename(*a)
	path = a[0]
	sep  = "\\" + File::SEPARATOR

	# I suck at regex.
	path =~ /(.*)#{sep}(.*)$/

	Rex::FileUtils.clean_path($2 || path)
end

.download(destination, *src_files, &stat) ⇒ Object

Download one or more files from the remote computer to the local directory supplied in destination.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 170

def File.download(destination, *src_files, &stat)
	src_files.each { |src|
		dest = destination

		stat.call('downloading', src, dest) if (stat)

		if (::File.basename(destination) != File.basename(src))
			dest += ::File::SEPARATOR + File.basename(src)
		end

		download_file(dest, src)
		
		stat.call('downloaded', src, dest) if (stat)
	}
end

.download_file(dest_file, src_file) ⇒ Object

Download a single file.



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 189

def File.download_file(dest_file, src_file)
	src_fd = client.fs.file.new(src_file, "rb")
	::FileUtils.mkdir_p(::File.dirname(dest_file))
	dst_fd = ::File.new(dest_file, "wb")

	# Keep transferring until EOF is reached...
	begin
		while ((data = src_fd.read) != nil)
			dst_fd.write(data)
		end
	rescue EOFError
	ensure
		src_fd.close
		dst_fd.close
	end
end

.exists?(name) ⇒ Boolean

Determines if a file exists and returns true/false

Returns:

  • (Boolean)


103
104
105
106
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 103

def File.exists?(name)
	r = client.fs.filestat.new(name) rescue nil
	r ? true : false
end

.expand_path(path) ⇒ Object

Expands a file path, substituting all environment variables, such as %TEMP%.



83
84
85
86
87
88
89
90
91
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 83

def File.expand_path(path)
	request = Packet.create_request('stdapi_fs_file_expand_path')

	request.add_tlv(TLV_TYPE_FILE_PATH, path)

	response = client.send_request(request)
	
	return response.get_tlv_value(TLV_TYPE_FILE_PATH)
end

.rm(name) ⇒ Object

Performs a delete on the specified file.



111
112
113
114
115
116
117
118
119
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 111

def File.rm(name)		
	request = Packet.create_request('stdapi_fs_delete_file')

	request.add_tlv(TLV_TYPE_FILE_PATH,name)

	response = client.send_request(request)
	
	return response
end

.search(root = nil, glob = "*.*", recurse = true, timeout = -1 )) ⇒ Object

Search for files.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 38

def File.search( root=nil, glob="*.*", recurse=true, timeout=-1 )
	
	files = ::Array.new
	
	request = Packet.create_request( 'stdapi_fs_search' )

	root = root.chomp( '\\' ) if root
	
	request.add_tlv( TLV_TYPE_SEARCH_ROOT, root )
	request.add_tlv( TLV_TYPE_SEARCH_GLOB, glob )
	request.add_tlv( TLV_TYPE_SEARCH_RECURSE, recurse )

	# we set the response timeout to -1 to wait indefinatly as a 
	# search could take an indeterminate ammount of time to complete.
	response = client.send_request( request, timeout )
	if( response.result == 0 )
		response.each( TLV_TYPE_SEARCH_RESULTS ) do | results |
			files << {
				'path' => results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ),
				'name' => results.get_tlv_value( TLV_TYPE_FILE_NAME ),
				'size' => results.get_tlv_value( TLV_TYPE_FILE_SIZE )
			}
		end
	end
	
	return files
end

.stat(name) ⇒ Object

Performs a stat on a file and returns a FileStat instance.



96
97
98
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 96

def File.stat(name)
	return client.fs.filestat.new(name)
end

Performs a delete on the specified file.



124
125
126
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 124

def File.unlink(name)
	return File.rm(name)
end

.upload(destination, *src_files, &stat) ⇒ Object

Upload one or more files to the remote computer the remote directory supplied in destination.



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 132

def File.upload(destination, *src_files, &stat)
	src_files.each { |src|
		dest = destination

		stat.call('uploading', src, dest) if (stat)
		if (File.basename(destination) != ::File.basename(src))
			dest += File::SEPARATOR + ::File.basename(src)
		end

		upload_file(dest, src)
		stat.call('uploaded', src, dest) if (stat)
	}
end

.upload_file(dest_file, src_file) ⇒ Object

Upload a single file.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 149

def File.upload_file(dest_file, src_file)
	# Open the file on the remote side for writing and read
	# all of the contents of the local file
	dest_fd = client.fs.file.new(dest_file, "wb")
	src_buf = ''
	
	::File.open(src_file, 'rb') { |f|
		src_buf = f.read(f.stat.size)
	}

	begin
		dest_fd.write(src_buf)
	ensure
		dest_fd.close
	end
end

Instance Method Details

#eofObject

Returns whether or not the file has reach EOF.



229
230
231
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 229

def eof
	return self.filed.eof
end

#posObject

Returns the current position of the file pointer.



236
237
238
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 236

def pos
	return self.filed.tell
end

#seek(offset, whence = SEEK_SET) ⇒ Object

Synonym for sysseek.



243
244
245
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 243

def seek(offset, whence = SEEK_SET)
	return self.sysseek(offset, whence)
end

#sysseek(offset, whence = SEEK_SET) ⇒ Object

Seeks to the supplied offset based on the supplied relativity.



250
251
252
# File 'lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb', line 250

def sysseek(offset, whence = SEEK_SET)
	return self.filed.seek(offset, whence)
end