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 'socket'
|
||||||
require 'Rex/Post/Meterpreter/ClientCore'
|
require 'Rex/Post/Meterpreter/ClientCore'
|
||||||
|
require 'Rex/Post/Meterpreter/Channel'
|
||||||
require 'Rex/Post/Meterpreter/ObjectAliases'
|
require 'Rex/Post/Meterpreter/ObjectAliases'
|
||||||
require 'Rex/Post/Meterpreter/Packet'
|
require 'Rex/Post/Meterpreter/Packet'
|
||||||
require 'Rex/Post/Meterpreter/PacketParser'
|
require 'Rex/Post/Meterpreter/PacketParser'
|
||||||
|
|
|
@ -9,10 +9,6 @@ module Meterpreter
|
||||||
module Extensions
|
module Extensions
|
||||||
module Stdapi
|
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 Dir < Rex::Post::Dir
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#!/usr/bin/ruby
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
require 'Rex/Post/File'
|
require 'Rex/Post/File'
|
||||||
|
require 'Rex/Post/Meterpreter/Channel'
|
||||||
require 'Rex/Post/Meterpreter/Extensions/Stdapi/Stdapi'
|
require 'Rex/Post/Meterpreter/Extensions/Stdapi/Stdapi'
|
||||||
|
require 'Rex/Post/Meterpreter/Extensions/Stdapi/IO'
|
||||||
|
require 'Rex/Post/Meterpreter/Extensions/Stdapi/FileStat'
|
||||||
|
|
||||||
module Rex
|
module Rex
|
||||||
module Post
|
module Post
|
||||||
|
@ -9,7 +12,7 @@ module Meterpreter
|
||||||
module Extensions
|
module Extensions
|
||||||
module Stdapi
|
module Stdapi
|
||||||
|
|
||||||
class File
|
class File < Rex::Post::Meterpreter::Extensions::Stdapi::IO
|
||||||
|
|
||||||
include Rex::Post::File
|
include Rex::Post::File
|
||||||
|
|
||||||
|
@ -17,14 +20,23 @@ class File
|
||||||
attr_accessor :client
|
attr_accessor :client
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(name, mode = "r", perms = 0)
|
|
||||||
self.client = self.class.client
|
|
||||||
end
|
|
||||||
|
|
||||||
def File.stat(name)
|
def File.stat(name)
|
||||||
return client.filestat.new(name)
|
return client.filestat.new(name)
|
||||||
end
|
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
|
protected
|
||||||
attr_accessor :client
|
attr_accessor :client
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ module Meterpreter
|
||||||
module Extensions
|
module Extensions
|
||||||
module Stdapi
|
module Stdapi
|
||||||
|
|
||||||
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
|
|
||||||
|
|
||||||
class FileStat < Rex::Post::FileStat
|
class FileStat < Rex::Post::FileStat
|
||||||
|
|
||||||
@@struct_stat = [
|
@@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 Extensions
|
||||||
module Stdapi
|
module Stdapi
|
||||||
|
|
||||||
TLV_TYPE_PID = TLV_META_TYPE_UINT | 0
|
|
||||||
|
|
||||||
class Process < Rex::Post::Process
|
class Process < Rex::Post::Process
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
|
|
|
@ -14,18 +14,6 @@ module Meterpreter
|
||||||
module Extensions
|
module Extensions
|
||||||
module Stdapi
|
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 Registry
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
|
|
|
@ -13,6 +13,29 @@ module Meterpreter
|
||||||
module Extensions
|
module Extensions
|
||||||
module Stdapi
|
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
|
# Stdapi
|
||||||
|
|
|
@ -61,6 +61,7 @@ LOAD_LIBRARY_FLAG_ON_DISK = (1 << 0)
|
||||||
LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
|
LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
|
||||||
LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
|
LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
|
||||||
|
|
||||||
|
CHANNEL_FLAG_SYNCHRONOUS = (1 << 0)
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
|
@ -217,6 +218,19 @@ class GroupTlv < Tlv
|
||||||
return tlv
|
return tlv
|
||||||
end
|
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
|
# Gets the first TLV of a given type
|
||||||
def get_tlv(type, index = 0)
|
def get_tlv(type, index = 0)
|
||||||
type_tlvs = get_tlvs(type)
|
type_tlvs = get_tlvs(type)
|
||||||
|
|
Loading…
Reference in New Issue