file i/o working
git-svn-id: file:///home/svn/incoming/trunk@2365 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
91600f7d52
commit
7556674686
|
@ -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
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue