file i/o working

git-svn-id: file:///home/svn/incoming/trunk@2365 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2005-04-11 04:56:24 +00:00
parent 91600f7d52
commit 7556674686
10 changed files with 254 additions and 25 deletions

View File

@ -0,0 +1,164 @@
#!/usr/bin/ruby
module Rex
module Post
module Meterpreter
class Channel
@@channels = []
##
#
# Factory
#
##
=begin
create(client, type, addends)
Creates a logical channel between the client and the server
based on a given type.
=end
def Channel.create(client, type = nil,
flags = CHANNEL_FLAG_SYNCHRONOUS, addends = nil)
request = Packet.create_request('core_channel_open')
# Set the type of channel that we're allocating
if (type != nil)
request.add_tlv(TLV_TYPE_CHANNEL_TYPE, type)
end
# Add flag information and addends
request.add_tlv(TLV_TYPE_FLAGS, flags)
request.add_tlvs(addends);
# Transmit the request and wait for the response
response = client.send_request(request)
cid = response.get_tlv(TLV_TYPE_CHANNEL_ID).value
# Create the channel instance
channel = Channel.new(client, cid, type, flags)
# Insert the instance into the channel list
if (channel != nil)
@@channels << channel
end
return channel
end
##
#
# Constructor
#
##
def initialize(client, cid, type, flags = 0)
self.client = client
self.cid = cid
self.type = type
self.flags = flags
end
##
#
# Channel interaction
#
##
def recv(length = nil, addends = nil)
request = Packet.create_request('core_channel_read')
if (length == nil)
length = 65536
end
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
request.add_tlv(TLV_TYPE_LENGTH, length)
request.add_tlvs(addends)
response = self.client.send_request(request)
# If the channel is in synchronous mode, the response should contain
# data that was read from the remote side of the channel
if (flag?(CHANNEL_FLAG_SYNCHRONOUS))
data = response.get_tlv(TLV_TYPE_CHANNEL_DATA);
if (data != nil)
return data.value
end
else
raise NotImplementedError, "Asynchronous channel mode is not implemented", caller
end
return nil
end
def send(buf, length = nil, addends = nil)
request = Packet.create_request('core_channel_write')
# Truncation and celebration
if ((length != nil) &&
(buf.length >= length))
buf = buf[0..length]
else
length = buf.length
end
# Populate the request
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
request.add_tlv(TLV_TYPE_CHANNEL_DATA, buf)
request.add_tlv(TLV_TYPE_LENGTH, length)
response = self.client.send_request(request)
written = response.get_tlv(TLV_TYPE_LENGTH)
return (written == nil) ? 0 : written.value
end
def close(addends = nil)
request = Packet.create_request('core_channel_close')
# Populate the request
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
self.client.send_request(request)
self.cid = 0
return true
end
##
#
# Direct I/O
#
##
def dio
raise NotImplementedError, "dio not implemented", caller
end
##
#
# Conditionals
#
##
def flag?(flag)
return ((self.flags & flag) == flag)
end
attr_reader :cid, :type, :flags
attr_accessor :dio_handler
protected
attr_accessor :client
attr_writer :cid, :type, :flags
end
end; end; end

View File

@ -2,6 +2,7 @@
require 'socket'
require 'Rex/Post/Meterpreter/ClientCore'
require 'Rex/Post/Meterpreter/Channel'
require 'Rex/Post/Meterpreter/ObjectAliases'
require 'Rex/Post/Meterpreter/Packet'
require 'Rex/Post/Meterpreter/PacketParser'

View File

@ -9,10 +9,6 @@ module Meterpreter
module Extensions
module Stdapi
TLV_TYPE_DIRECTORY_PATH = TLV_META_TYPE_STRING | 1200
TLV_TYPE_FILE_NAME = TLV_META_TYPE_STRING | 1201
TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202
class Dir < Rex::Post::Dir
class <<self

View File

@ -1,7 +1,10 @@
#!/usr/bin/ruby
require 'Rex/Post/File'
require 'Rex/Post/Meterpreter/Channel'
require 'Rex/Post/Meterpreter/Extensions/Stdapi/Stdapi'
require 'Rex/Post/Meterpreter/Extensions/Stdapi/IO'
require 'Rex/Post/Meterpreter/Extensions/Stdapi/FileStat'
module Rex
module Post
@ -9,7 +12,7 @@ module Meterpreter
module Extensions
module Stdapi
class File
class File < Rex::Post::Meterpreter::Extensions::Stdapi::IO
include Rex::Post::File
@ -17,14 +20,23 @@ class File
attr_accessor :client
end
def initialize(name, mode = "r", perms = 0)
self.client = self.class.client
end
def File.stat(name)
return client.filestat.new(name)
end
def initialize(name, mode = "r", perms = 0)
self.client = self.class.client
self.filed = _open(name, mode, perms)
end
def _open(name, mode = "r", perms = 0)
return Channel.create(self.client, 'stdapi_fs_file',
CHANNEL_FLAG_SYNCHRONOUS, [
{ 'type' => TLV_TYPE_FILE_PATH, 'value' => name },
{ 'type' => TLV_TYPE_FILE_MODE, 'value' => mode + "b" },
])
end
protected
attr_accessor :client

View File

@ -9,8 +9,6 @@ module Meterpreter
module Extensions
module Stdapi
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
class FileStat < Rex::Post::FileStat
@@struct_stat = [

View File

@ -0,0 +1,35 @@
#!/usr/bin/ruby
require 'Rex/Post/IO'
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
class IO < Rex::Post::IO
def read(length = nil, flags = nil)
recv(length, flags)
end
def recv(length = nil, flags = nil)
filed.recv(length)
end
def write(buf, length = nil, flags = nil)
send(buf, length, flags)
end
def send(buf, length = nil, flags = nil)
filed.send(buf, length)
end
def close
filed.close
end
end
end; end; end; end; end

View File

@ -11,8 +11,6 @@ module Meterpreter
module Extensions
module Stdapi
TLV_TYPE_PID = TLV_META_TYPE_UINT | 0
class Process < Rex::Post::Process
class <<self

View File

@ -14,18 +14,6 @@ module Meterpreter
module Extensions
module Stdapi
DELETE_KEY_FLAG_RECURSIVE = (1 << 0)
TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000
TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY
TLV_TYPE_BASE_KEY = TLV_META_TYPE_STRING | 1001
TLV_TYPE_PERMISSION = TLV_META_TYPE_UINT | 1002
TLV_TYPE_KEY_NAME = TLV_META_TYPE_STRING | 1003
TLV_TYPE_VALUE_NAME = TLV_META_TYPE_STRING | 1010
TLV_TYPE_VALUE_TYPE = TLV_META_TYPE_UINT | 1011
TLV_TYPE_VALUE_DATA = TLV_META_TYPE_RAW | 1012
class Registry
class <<self

View File

@ -13,6 +13,29 @@ module Meterpreter
module Extensions
module Stdapi
# Process
TLV_TYPE_PID = TLV_META_TYPE_UINT | 0
# Registry
TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000
TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY
TLV_TYPE_BASE_KEY = TLV_META_TYPE_STRING | 1001
TLV_TYPE_PERMISSION = TLV_META_TYPE_UINT | 1002
TLV_TYPE_KEY_NAME = TLV_META_TYPE_STRING | 1003
TLV_TYPE_VALUE_NAME = TLV_META_TYPE_STRING | 1010
TLV_TYPE_VALUE_TYPE = TLV_META_TYPE_UINT | 1011
TLV_TYPE_VALUE_DATA = TLV_META_TYPE_RAW | 1012
# Fs
TLV_TYPE_DIRECTORY_PATH = TLV_META_TYPE_STRING | 1200
TLV_TYPE_FILE_NAME = TLV_META_TYPE_STRING | 1201
TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202
TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
DELETE_KEY_FLAG_RECURSIVE = (1 << 0)
###
#
# Stdapi

View File

@ -61,6 +61,7 @@ LOAD_LIBRARY_FLAG_ON_DISK = (1 << 0)
LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
CHANNEL_FLAG_SYNCHRONOUS = (1 << 0)
###
#
@ -217,6 +218,19 @@ class GroupTlv < Tlv
return tlv
end
=begin
add_tlvs(tlvs)
Adds zero or more TLVs to the packet
=end
def add_tlvs(tlvs)
if (tlvs != nil)
tlvs.each { |tlv|
add_tlv(tlv['type'], tlv['value'])
}
end
end
# Gets the first TLV of a given type
def get_tlv(type, index = 0)
type_tlvs = get_tlvs(type)