commit the rest of chao's patch :/
git-svn-id: file:///home/svn/framework3/trunk@12412 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
3829d2606b
commit
c9ab8f248d
|
@ -0,0 +1,286 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib'))
|
||||||
|
|
||||||
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Post
|
||||||
|
module Meterpreter
|
||||||
|
module Extensions
|
||||||
|
module Stdapi
|
||||||
|
module Railgun
|
||||||
|
class DLL::UnitTest < Test::Unit::TestCase
|
||||||
|
|
||||||
|
TLV_TYPE_NAMES = {
|
||||||
|
TLV_TYPE_RAILGUN_SIZE_OUT => "TLV_TYPE_RAILGUN_SIZE_OUT",
|
||||||
|
TLV_TYPE_RAILGUN_STACKBLOB => "TLV_TYPE_RAILGUN_STACKBLOB",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "TLV_TYPE_RAILGUN_BUFFERBLOB_IN",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT",
|
||||||
|
TLV_TYPE_RAILGUN_DLLNAME => "TLV_TYPE_RAILGUN_DLLNAME",
|
||||||
|
TLV_TYPE_RAILGUN_FUNCNAME => "TLV_TYPE_RAILGUN_FUNCNAME",
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockRailgunClient
|
||||||
|
attr_reader :platform, :check_request, :response_tlvs
|
||||||
|
|
||||||
|
def initialize(platform, response_tlvs, check_request)
|
||||||
|
@check_request = check_request
|
||||||
|
@response_tlvs = response_tlvs
|
||||||
|
@platform = platform
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_request(request)
|
||||||
|
check_request.call(request)
|
||||||
|
|
||||||
|
(Class.new do
|
||||||
|
def initialize(response_tlvs)
|
||||||
|
@response_tlvs = response_tlvs
|
||||||
|
end
|
||||||
|
def get_tlv_value(type)
|
||||||
|
return @response_tlvs[type]
|
||||||
|
end
|
||||||
|
end).new(@response_tlvs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_mock_client(platform = "x86/win32", target_request_tlvs = [], response_tlvs = [])
|
||||||
|
check_request = lambda do |request|
|
||||||
|
target_request_tlvs.each_pair do |type, target_value|
|
||||||
|
assert_equal(target_value, request.get_tlv_value(type),
|
||||||
|
"process_function_call should send to client appropriate #{TLV_TYPE_NAMES[type]}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return MockRailgunClient.new(platform, response_tlvs, check_request)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_add_function
|
||||||
|
function_descriptions.each do |func|
|
||||||
|
dll = DLL.new(func[:dll_name], make_mock_client(func[:platform]), nil)
|
||||||
|
dll.add_function(func[:name], func[:return_type], func[:params])
|
||||||
|
|
||||||
|
assert(dll.functions.has_key?(func[:name]),
|
||||||
|
"add_function should expand the list of available functions")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_missing
|
||||||
|
function_descriptions.each do |func|
|
||||||
|
client = make_mock_client(func[:platform], func[:request_to_client], func[:response_from_client])
|
||||||
|
dll = DLL.new(func[:dll_name], client, nil)
|
||||||
|
|
||||||
|
dll.add_function(func[:name], func[:return_type], func[:params])
|
||||||
|
|
||||||
|
actual_returned_hash = dll.send(:method_missing, func[:name].to_sym, *func[:ruby_args])
|
||||||
|
|
||||||
|
assert(func[:returned_hash].has_key?('GetLastError'),
|
||||||
|
"process_function_call should add the result of GetLastError to the key GetLastError")
|
||||||
|
|
||||||
|
assert_equal(func[:returned_hash], actual_returned_hash,
|
||||||
|
"process_function_call convert function result to a ruby hash")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# These are sample descriptions of functions to use for testing.
|
||||||
|
def function_descriptions
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:platform => "x86/win32",
|
||||||
|
:name => "LookupAccountSidA",
|
||||||
|
:params => [
|
||||||
|
["PCHAR","lpSystemName","in"],
|
||||||
|
["LPVOID","Sid","in"],
|
||||||
|
["PCHAR","Name","out"],
|
||||||
|
["PDWORD","cchName","inout"],
|
||||||
|
["PCHAR","ReferencedDomainName","out"],
|
||||||
|
["PDWORD","cchReferencedDomainName","inout"],
|
||||||
|
["PBLOB","peUse","out"],
|
||||||
|
],
|
||||||
|
:return_type => "BOOL",
|
||||||
|
:dll_name => "advapi32",
|
||||||
|
:ruby_args => [nil, 1371864, 100, 100, 100, 100, 1],
|
||||||
|
:request_to_client => {
|
||||||
|
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
||||||
|
TLV_TYPE_RAILGUN_STACKBLOB => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD8\xEE\x14\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00d\x00\x00\x00\x03\x00\x00\x00\b\x00\x00\x00\x02\x00\x00\x00\xC8\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_DLLNAME => "advapi32",
|
||||||
|
TLV_TYPE_RAILGUN_FUNCNAME => "LookupAccountSidA"
|
||||||
|
},
|
||||||
|
:response_from_client => {
|
||||||
|
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
||||||
|
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
||||||
|
TLV_TYPE_RAILGUN_BACK_ERR => 997
|
||||||
|
},
|
||||||
|
:returned_hash => {
|
||||||
|
"GetLastError" => 997,
|
||||||
|
"return" => true,
|
||||||
|
"Name" => "SYSTEM",
|
||||||
|
"ReferencedDomainName" => "NT AUTHORITY",
|
||||||
|
"peUse" => "\x05",
|
||||||
|
"cchName" => 6,
|
||||||
|
"cchReferencedDomainName" => 12
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:platform => 'x64/win64',
|
||||||
|
:name => 'LookupAccountSidA',
|
||||||
|
:params => [
|
||||||
|
["PCHAR", "lpSystemName", "in"],
|
||||||
|
["LPVOID", "Sid", "in"],
|
||||||
|
["PCHAR", "Name", "out"],
|
||||||
|
["PDWORD", "cchName", "inout"],
|
||||||
|
["PCHAR", "ReferencedDomainName", "out"],
|
||||||
|
["PDWORD", "cchReferencedDomainName", "inout"],
|
||||||
|
["PBLOB", "peUse", "out"]
|
||||||
|
],
|
||||||
|
:return_type => 'BOOL',
|
||||||
|
:dll_name => 'advapi32',
|
||||||
|
:ruby_args => [nil, 1631552, 100, 100, 100, 100, 1],
|
||||||
|
:request_to_client => {
|
||||||
|
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
||||||
|
TLV_TYPE_RAILGUN_STACKBLOB => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xE5\x18\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xC8\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
||||||
|
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_DLLNAME => 'advapi32',
|
||||||
|
TLV_TYPE_RAILGUN_FUNCNAME => 'LookupAccountSidA',
|
||||||
|
},
|
||||||
|
:response_from_client => {
|
||||||
|
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
||||||
|
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
||||||
|
TLV_TYPE_RAILGUN_BACK_ERR => 0,
|
||||||
|
},
|
||||||
|
:returned_hash => {
|
||||||
|
"GetLastError"=>0,
|
||||||
|
"return"=>true,
|
||||||
|
"Name"=>"SYSTEM",
|
||||||
|
"ReferencedDomainName"=>"NT AUTHORITY",
|
||||||
|
"peUse"=>"\x05",
|
||||||
|
"cchName"=>6,
|
||||||
|
"cchReferencedDomainName"=>12
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def MockClient
|
||||||
|
|
||||||
|
def initialize(x64=false)
|
||||||
|
@x64 = x64
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_request(request)
|
||||||
|
|
||||||
|
if @x64
|
||||||
|
## TODO - we can probably parse up the TLV, or fake it
|
||||||
|
|
||||||
|
## Parse up the TLV here
|
||||||
|
only_out_size_bytes = ""
|
||||||
|
literal_pairs_blob = ""
|
||||||
|
in_only_buffer = ""
|
||||||
|
inout_buffer = ""
|
||||||
|
dll_path = ""
|
||||||
|
function_windows_name = ""
|
||||||
|
|
||||||
|
return MockResponse(function_windows_name)
|
||||||
|
else
|
||||||
|
raise "Unimplemented"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MockResponse(function)
|
||||||
|
|
||||||
|
def initialize(function)
|
||||||
|
@fuction_to_mock = function
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_tlv_value(TLV_CONST)
|
||||||
|
if @function_to_mock == ""
|
||||||
|
return ##TODO
|
||||||
|
elsif @function_to_mock == "whateverx2"
|
||||||
|
else
|
||||||
|
raise "Unknown TLV_CONST - We don't know how to mock this?"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
## This stuff probably shouldn't be mocked, but we're in a hurry.
|
||||||
|
class MockFunction
|
||||||
|
|
||||||
|
def initialize(name)
|
||||||
|
@name = name
|
||||||
|
@hash = {} ##TODO
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
if @name == "ActivateActCtx"
|
||||||
|
@hash = {} ## TODO
|
||||||
|
return @hash
|
||||||
|
else
|
||||||
|
raise "That function: #{@name} is not implemented."
|
||||||
|
end
|
||||||
|
|
||||||
|
def return_type
|
||||||
|
return "" ##TODO
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Post
|
||||||
|
module Meterpreter
|
||||||
|
module Extensions
|
||||||
|
module Stdapi
|
||||||
|
module Railgun
|
||||||
|
class DLL::UnitTest < Test::Unit::TestCase
|
||||||
|
|
||||||
|
## x64 testing
|
||||||
|
|
||||||
|
def test_add_function_x64
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_process_function_call_x64
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new(true))
|
||||||
|
process_function_call(MockFunction("ActivateActCtx"),
|
||||||
|
assert ##TODO
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_missing_x64
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
## x86 testing
|
||||||
|
|
||||||
|
def test_add_function_x86
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new(true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_process_function_call_x86
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new(true) )
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_missing_x86
|
||||||
|
dll = DLL.new("kernel32.dll", Mockclient.new(true))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue