librex 0.0.32 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +1 -1
- data/lib/rex/exploitation/egghunter.rb +90 -1
- data/lib/rex/exploitation/javascriptosdetect.rb +9 -1
- data/lib/rex/io/ring_buffer.rb.ut.rb +134 -0
- data/lib/rex/io/stream_server.rb +11 -2
- data/lib/rex/parser/nessus_xml.rb +4 -2
- data/lib/rex/parser/nexpose_xml.rb +45 -15
- data/lib/rex/parser/nmap_nokogiri.rb +385 -0
- data/lib/rex/parser/nmap_xml.rb +71 -51
- data/lib/rex/parser/nokogiri_doc_mixin.rb +99 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +1 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb +4 -128
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +146 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb.ut.rb +63 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +8 -2
- data/lib/rex/proto/http/handler/proc.rb +1 -1
- data/lib/rex/proto/http/server.rb +15 -10
- data/lib/rex/socket/parameters.rb +16 -0
- data/lib/rex/socket/ssl_tcp_server.rb +47 -38
- data/lib/rex/ui/text/dispatcher_shell.rb +49 -29
- data/lib/rex/zip.rb +3 -0
- data/lib/rex/zip/archive.rb +13 -89
- data/lib/rex/zip/entry.rb +11 -1
- data/lib/rex/zip/jar.rb +224 -0
- metadata +9 -3
data/lib/rex/parser/nmap_xml.rb
CHANGED
@@ -59,66 +59,86 @@ class NmapXMLStreamParser
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def reset_state
|
62
|
-
@host = { "status" => nil, "addrs" => {}, "ports" => [] }
|
62
|
+
@host = { "status" => nil, "addrs" => {}, "ports" => [], "scripts" => {} }
|
63
|
+
@state = nil
|
63
64
|
end
|
64
65
|
|
65
66
|
def tag_start(name, attributes)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
@host["
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
67
|
+
begin
|
68
|
+
case name
|
69
|
+
when "address"
|
70
|
+
@host["addrs"][attributes["addrtype"]] = attributes["addr"]
|
71
|
+
if (attributes["addrtype"] =~ /ipv[46]/)
|
72
|
+
@host["addr"] = attributes["addr"]
|
73
|
+
end
|
74
|
+
when "osclass"
|
75
|
+
# If there is more than one, take the highest accuracy. In case of
|
76
|
+
# a tie, this will have the effect of taking the last one in the
|
77
|
+
# list. Last is really no better than first but nmap appears to
|
78
|
+
# put OSes in chronological order, at least for Windows.
|
79
|
+
# Accordingly, this will report XP instead of 2000, 7 instead of
|
80
|
+
# Vista, etc, when each has the same accuracy.
|
81
|
+
if (@host["os_accuracy"].to_i <= attributes["accuracy"].to_i)
|
82
|
+
@host["os_vendor"] = attributes["vendor"]
|
83
|
+
@host["os_family"] = attributes["osfamily"]
|
84
|
+
@host["os_version"] = attributes["osgen"]
|
85
|
+
@host["os_accuracy"] = attributes["accuracy"]
|
86
|
+
end
|
87
|
+
when "osmatch"
|
88
|
+
if(attributes["accuracy"].to_i == 100)
|
89
|
+
@host["os_match"] = attributes["name"]
|
90
|
+
end
|
91
|
+
when "uptime"
|
92
|
+
@host["last_boot"] = attributes["lastboot"]
|
93
|
+
when "hostname"
|
94
|
+
if(attributes["type"] == "PTR")
|
95
|
+
@host["reverse_dns"] = attributes["name"]
|
96
|
+
end
|
97
|
+
when "status"
|
98
|
+
# <status> refers to the liveness of the host; values are "up" or "down"
|
99
|
+
@host["status"] = attributes["state"]
|
100
|
+
@host["status_reason"] = attributes["reason"]
|
101
|
+
when "port"
|
102
|
+
@host["ports"].push(attributes)
|
103
|
+
when "state"
|
104
|
+
# <state> refers to the state of a port; values are "open", "closed", or "filtered"
|
105
|
+
@host["ports"].last["state"] = attributes["state"]
|
106
|
+
when "service"
|
107
|
+
# Store any service and script info with the associated port. There shouldn't
|
108
|
+
# be any collisions on attribute names here, so just merge them.
|
109
|
+
@host["ports"].last.merge!(attributes)
|
110
|
+
when "script"
|
111
|
+
# Associate scripts under a port tag with the appropriate port.
|
112
|
+
# Other scripts from <hostscript> tags can only be associated with
|
113
|
+
# the host and scripts from <postscript> tags don't really belong
|
114
|
+
# to anything, so ignore them
|
115
|
+
if @state == :in_port_tag
|
116
|
+
@host["ports"].last["scripts"] ||= {}
|
117
|
+
@host["ports"].last["scripts"][attributes["id"]] = attributes["output"]
|
118
|
+
elsif @host
|
119
|
+
@host["scripts"] ||= {}
|
120
|
+
@host["scripts"][attributes["id"]] = attributes["output"]
|
121
|
+
else
|
122
|
+
# post scripts are used for things like comparing all the found
|
123
|
+
# ssh keys to see if multiple hosts have the same key
|
124
|
+
# fingerprint. Ignore them.
|
125
|
+
end
|
126
|
+
when "trace"
|
127
|
+
@host["trace"] = {"port" => attributes["port"], "proto" => attributes["proto"], "hops" => [] }
|
128
|
+
when "hop"
|
129
|
+
if @host["trace"]
|
130
|
+
@host["trace"]["hops"].push(attributes)
|
131
|
+
end
|
116
132
|
end
|
133
|
+
rescue NoMethodError => err
|
134
|
+
raise err unless err.message =~ /NilClass/
|
117
135
|
end
|
118
136
|
end
|
119
137
|
|
120
138
|
def tag_end(name)
|
121
139
|
case name
|
140
|
+
when "port"
|
141
|
+
@state = nil
|
122
142
|
when "host"
|
123
143
|
on_found_host.call(@host) if on_found_host
|
124
144
|
reset_state
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Rex
|
2
|
+
module Parser
|
3
|
+
|
4
|
+
# Determines if Nokogiri is available and if it's a minimum
|
5
|
+
# acceptable version.
|
6
|
+
def self.load_nokogiri
|
7
|
+
@nokogiri_loaded = false
|
8
|
+
begin
|
9
|
+
require 'nokogiri'
|
10
|
+
major,minor = Nokogiri::VERSION.split(".")[0,2]
|
11
|
+
if major.to_i >= 1
|
12
|
+
if minor.to_i >= 4
|
13
|
+
@nokogiri_loaded = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
rescue LoadError => e
|
17
|
+
@nokogiri_loaded = false
|
18
|
+
@nokogiri_error = e
|
19
|
+
end
|
20
|
+
@nokogiri_loaded
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.nokogiri_loaded
|
24
|
+
!!@nokogiri_loaded
|
25
|
+
end
|
26
|
+
|
27
|
+
module NokogiriDocMixin
|
28
|
+
|
29
|
+
# Set up the getters and instance variables for the document
|
30
|
+
eval("attr_reader :args, :db, :state, :block, :report_data")
|
31
|
+
|
32
|
+
def initialize(args,db,&block)
|
33
|
+
@args = args
|
34
|
+
@db = db
|
35
|
+
@state = {}
|
36
|
+
@state[:current_tag] = {}
|
37
|
+
@block = block if block
|
38
|
+
@report_data = {:wspace => args[:wspace]}
|
39
|
+
super()
|
40
|
+
end
|
41
|
+
|
42
|
+
# Turn XML attribute pairs in to more workable hashes (there
|
43
|
+
# are better Enumerable tricks in Ruby 1.9, but ignoring for now)
|
44
|
+
def attr_hash(attrs)
|
45
|
+
h = {}
|
46
|
+
attrs.each {|k,v| h[k] = v}
|
47
|
+
h
|
48
|
+
end
|
49
|
+
|
50
|
+
def valid_ip(addr)
|
51
|
+
valid = false
|
52
|
+
valid = ::Rex::Socket::RangeWalker.new(addr).valid? rescue false
|
53
|
+
!!valid
|
54
|
+
end
|
55
|
+
|
56
|
+
# If there's an address, it's not on the blacklist,
|
57
|
+
# it has ports, and the port list isn't
|
58
|
+
# empty... it's okay.
|
59
|
+
def host_is_okay
|
60
|
+
return false unless @report_data[:host]
|
61
|
+
return false unless valid_ip(@report_data[:host])
|
62
|
+
return false unless @report_data[:state] == Msf::HostState::Alive
|
63
|
+
if @args[:blacklist]
|
64
|
+
return false if @args[:blacklist].include?(@report_data[:host])
|
65
|
+
end
|
66
|
+
return false unless @report_data[:ports]
|
67
|
+
return false if @report_data[:ports].empty?
|
68
|
+
return true
|
69
|
+
end
|
70
|
+
|
71
|
+
# XXX: Define this
|
72
|
+
def determine_port_state(v)
|
73
|
+
return v
|
74
|
+
end
|
75
|
+
|
76
|
+
# Nokogiri 1.4.4 (and presumably beyond) generates attrs as pairs,
|
77
|
+
# like [["value1","foo"],["value2","bar"]] (but not hashes for some
|
78
|
+
# reason). 1.4.3.1 (and presumably 1.4.3.x and prior) generates attrs
|
79
|
+
# as a flat array of strings. We want array_pairs.
|
80
|
+
def normalize_attrs(attrs)
|
81
|
+
attr_pairs = []
|
82
|
+
case attrs.first
|
83
|
+
when Array, NilClass
|
84
|
+
attr_pairs = attrs
|
85
|
+
when String
|
86
|
+
attrs.each_index {|i|
|
87
|
+
next if i % 2 == 0
|
88
|
+
attr_pairs << [attrs[i-1],attrs[i]]
|
89
|
+
}
|
90
|
+
else # Wow, yet another format! It's either from the distant past or distant future.
|
91
|
+
raise ::Msf::DBImportError.new("Unknown format for XML attributes. Please check your Nokogiri version.")
|
92
|
+
end
|
93
|
+
return attr_pairs
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib'))
|
4
4
|
|
5
5
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll'
|
6
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/mock_magic'
|
6
7
|
require 'test/unit'
|
7
8
|
|
8
9
|
module Rex
|
@@ -13,51 +14,10 @@ module Stdapi
|
|
13
14
|
module Railgun
|
14
15
|
class DLL::UnitTest < Test::Unit::TestCase
|
15
16
|
|
16
|
-
|
17
|
-
TLV_TYPE_RAILGUN_SIZE_OUT => "TLV_TYPE_RAILGUN_SIZE_OUT",
|
18
|
-
TLV_TYPE_RAILGUN_STACKBLOB => "TLV_TYPE_RAILGUN_STACKBLOB",
|
19
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "TLV_TYPE_RAILGUN_BUFFERBLOB_IN",
|
20
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT",
|
21
|
-
TLV_TYPE_RAILGUN_DLLNAME => "TLV_TYPE_RAILGUN_DLLNAME",
|
22
|
-
TLV_TYPE_RAILGUN_FUNCNAME => "TLV_TYPE_RAILGUN_FUNCNAME",
|
23
|
-
}
|
24
|
-
|
25
|
-
class MockRailgunClient
|
26
|
-
attr_reader :platform, :check_request, :response_tlvs
|
27
|
-
|
28
|
-
def initialize(platform, response_tlvs, check_request)
|
29
|
-
@check_request = check_request
|
30
|
-
@response_tlvs = response_tlvs
|
31
|
-
@platform = platform
|
32
|
-
end
|
33
|
-
|
34
|
-
def send_request(request)
|
35
|
-
check_request.call(request)
|
36
|
-
|
37
|
-
(Class.new do
|
38
|
-
def initialize(response_tlvs)
|
39
|
-
@response_tlvs = response_tlvs
|
40
|
-
end
|
41
|
-
def get_tlv_value(type)
|
42
|
-
return @response_tlvs[type]
|
43
|
-
end
|
44
|
-
end).new(@response_tlvs)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def make_mock_client(platform = "x86/win32", target_request_tlvs = [], response_tlvs = [])
|
49
|
-
check_request = lambda do |request|
|
50
|
-
target_request_tlvs.each_pair do |type, target_value|
|
51
|
-
assert_equal(target_value, request.get_tlv_value(type),
|
52
|
-
"process_function_call should send to client appropriate #{TLV_TYPE_NAMES[type]}")
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
return MockRailgunClient.new(platform, response_tlvs, check_request)
|
57
|
-
end
|
17
|
+
include MockMagic
|
58
18
|
|
59
19
|
def test_add_function
|
60
|
-
|
20
|
+
mock_function_descriptions.each do |func|
|
61
21
|
dll = DLL.new(func[:dll_name], make_mock_client(func[:platform]), nil)
|
62
22
|
dll.add_function(func[:name], func[:return_type], func[:params])
|
63
23
|
|
@@ -67,7 +27,7 @@ class DLL::UnitTest < Test::Unit::TestCase
|
|
67
27
|
end
|
68
28
|
|
69
29
|
def test_method_missing
|
70
|
-
|
30
|
+
mock_function_descriptions.each do |func|
|
71
31
|
client = make_mock_client(func[:platform], func[:request_to_client], func[:response_from_client])
|
72
32
|
dll = DLL.new(func[:dll_name], client, nil)
|
73
33
|
|
@@ -82,90 +42,6 @@ class DLL::UnitTest < Test::Unit::TestCase
|
|
82
42
|
"process_function_call convert function result to a ruby hash")
|
83
43
|
end
|
84
44
|
end
|
85
|
-
|
86
|
-
# These are sample descriptions of functions to use for testing.
|
87
|
-
def function_descriptions
|
88
|
-
[
|
89
|
-
{
|
90
|
-
:platform => "x86/win32",
|
91
|
-
:name => "LookupAccountSidA",
|
92
|
-
:params => [
|
93
|
-
["PCHAR","lpSystemName","in"],
|
94
|
-
["LPVOID","Sid","in"],
|
95
|
-
["PCHAR","Name","out"],
|
96
|
-
["PDWORD","cchName","inout"],
|
97
|
-
["PCHAR","ReferencedDomainName","out"],
|
98
|
-
["PDWORD","cchReferencedDomainName","inout"],
|
99
|
-
["PBLOB","peUse","out"],
|
100
|
-
],
|
101
|
-
:return_type => "BOOL",
|
102
|
-
:dll_name => "advapi32",
|
103
|
-
:ruby_args => [nil, 1371864, 100, 100, 100, 100, 1],
|
104
|
-
:request_to_client => {
|
105
|
-
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
106
|
-
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",
|
107
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
108
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
109
|
-
TLV_TYPE_RAILGUN_DLLNAME => "advapi32",
|
110
|
-
TLV_TYPE_RAILGUN_FUNCNAME => "LookupAccountSidA"
|
111
|
-
},
|
112
|
-
:response_from_client => {
|
113
|
-
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
114
|
-
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
115
|
-
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
116
|
-
TLV_TYPE_RAILGUN_BACK_ERR => 997
|
117
|
-
},
|
118
|
-
:returned_hash => {
|
119
|
-
"GetLastError" => 997,
|
120
|
-
"return" => true,
|
121
|
-
"Name" => "SYSTEM",
|
122
|
-
"ReferencedDomainName" => "NT AUTHORITY",
|
123
|
-
"peUse" => "\x05",
|
124
|
-
"cchName" => 6,
|
125
|
-
"cchReferencedDomainName" => 12
|
126
|
-
},
|
127
|
-
},
|
128
|
-
{
|
129
|
-
:platform => 'x64/win64',
|
130
|
-
:name => 'LookupAccountSidA',
|
131
|
-
:params => [
|
132
|
-
["PCHAR", "lpSystemName", "in"],
|
133
|
-
["LPVOID", "Sid", "in"],
|
134
|
-
["PCHAR", "Name", "out"],
|
135
|
-
["PDWORD", "cchName", "inout"],
|
136
|
-
["PCHAR", "ReferencedDomainName", "out"],
|
137
|
-
["PDWORD", "cchReferencedDomainName", "inout"],
|
138
|
-
["PBLOB", "peUse", "out"]
|
139
|
-
],
|
140
|
-
:return_type => 'BOOL',
|
141
|
-
:dll_name => 'advapi32',
|
142
|
-
:ruby_args => [nil, 1631552, 100, 100, 100, 100, 1],
|
143
|
-
:request_to_client => {
|
144
|
-
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
145
|
-
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",
|
146
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
147
|
-
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
148
|
-
TLV_TYPE_RAILGUN_DLLNAME => 'advapi32',
|
149
|
-
TLV_TYPE_RAILGUN_FUNCNAME => 'LookupAccountSidA',
|
150
|
-
},
|
151
|
-
:response_from_client => {
|
152
|
-
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
153
|
-
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
154
|
-
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
155
|
-
TLV_TYPE_RAILGUN_BACK_ERR => 0,
|
156
|
-
},
|
157
|
-
:returned_hash => {
|
158
|
-
"GetLastError"=>0,
|
159
|
-
"return"=>true,
|
160
|
-
"Name"=>"SYSTEM",
|
161
|
-
"ReferencedDomainName"=>"NT AUTHORITY",
|
162
|
-
"peUse"=>"\x05",
|
163
|
-
"cchName"=>6,
|
164
|
-
"cchReferencedDomainName"=>12
|
165
|
-
},
|
166
|
-
},
|
167
|
-
]
|
168
|
-
end
|
169
45
|
end
|
170
46
|
end
|
171
47
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Rex
|
2
|
+
module Post
|
3
|
+
module Meterpreter
|
4
|
+
module Extensions
|
5
|
+
module Stdapi
|
6
|
+
module Railgun
|
7
|
+
|
8
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
|
9
|
+
|
10
|
+
#
|
11
|
+
# This mixin serves as a means of providing common mock objects and utilities
|
12
|
+
# relevant to railgun until a better home is decided upon
|
13
|
+
#
|
14
|
+
module MockMagic
|
15
|
+
|
16
|
+
TLV_TYPE_NAMES = {
|
17
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => "TLV_TYPE_RAILGUN_SIZE_OUT",
|
18
|
+
TLV_TYPE_RAILGUN_STACKBLOB => "TLV_TYPE_RAILGUN_STACKBLOB",
|
19
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "TLV_TYPE_RAILGUN_BUFFERBLOB_IN",
|
20
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT",
|
21
|
+
TLV_TYPE_RAILGUN_DLLNAME => "TLV_TYPE_RAILGUN_DLLNAME",
|
22
|
+
TLV_TYPE_RAILGUN_FUNCNAME => "TLV_TYPE_RAILGUN_FUNCNAME",
|
23
|
+
}
|
24
|
+
|
25
|
+
class MockRailgunClient
|
26
|
+
attr_reader :platform, :check_request, :response_tlvs
|
27
|
+
|
28
|
+
def initialize(platform, response_tlvs, check_request)
|
29
|
+
@check_request = check_request
|
30
|
+
@response_tlvs = response_tlvs
|
31
|
+
@platform = platform
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_request(request)
|
35
|
+
check_request.call(request)
|
36
|
+
|
37
|
+
(Class.new do
|
38
|
+
def initialize(response_tlvs)
|
39
|
+
@response_tlvs = response_tlvs
|
40
|
+
end
|
41
|
+
def get_tlv_value(type)
|
42
|
+
return @response_tlvs[type]
|
43
|
+
end
|
44
|
+
end).new(@response_tlvs)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def make_mock_client(platform = "x86/win32", target_request_tlvs = [], response_tlvs = [])
|
49
|
+
check_request = lambda do |request|
|
50
|
+
target_request_tlvs.each_pair do |type, target_value|
|
51
|
+
assert_equal(target_value, request.get_tlv_value(type),
|
52
|
+
"process_function_call should send to client appropriate #{TLV_TYPE_NAMES[type]}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
return MockRailgunClient.new(platform, response_tlvs, check_request)
|
57
|
+
end
|
58
|
+
|
59
|
+
# These are sample descriptions of functions to use for testing.
|
60
|
+
# the definitions include everything needed to mock and end to end test
|
61
|
+
def mock_function_descriptions
|
62
|
+
[
|
63
|
+
{
|
64
|
+
:platform => "x86/win32",
|
65
|
+
:name => "LookupAccountSidA",
|
66
|
+
:params => [
|
67
|
+
["PCHAR","lpSystemName","in"],
|
68
|
+
["LPVOID","Sid","in"],
|
69
|
+
["PCHAR","Name","out"],
|
70
|
+
["PDWORD","cchName","inout"],
|
71
|
+
["PCHAR","ReferencedDomainName","out"],
|
72
|
+
["PDWORD","cchReferencedDomainName","inout"],
|
73
|
+
["PBLOB","peUse","out"],
|
74
|
+
],
|
75
|
+
:return_type => "BOOL",
|
76
|
+
:dll_name => "advapi32",
|
77
|
+
:ruby_args => [nil, 1371864, 100, 100, 100, 100, 1],
|
78
|
+
:request_to_client => {
|
79
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
80
|
+
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",
|
81
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
82
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
83
|
+
TLV_TYPE_RAILGUN_DLLNAME => "advapi32",
|
84
|
+
TLV_TYPE_RAILGUN_FUNCNAME => "LookupAccountSidA"
|
85
|
+
},
|
86
|
+
:response_from_client => {
|
87
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
88
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
89
|
+
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
90
|
+
TLV_TYPE_RAILGUN_BACK_ERR => 997
|
91
|
+
},
|
92
|
+
:returned_hash => {
|
93
|
+
"GetLastError" => 997,
|
94
|
+
"return" => true,
|
95
|
+
"Name" => "SYSTEM",
|
96
|
+
"ReferencedDomainName" => "NT AUTHORITY",
|
97
|
+
"peUse" => "\x05",
|
98
|
+
"cchName" => 6,
|
99
|
+
"cchReferencedDomainName" => 12
|
100
|
+
},
|
101
|
+
},
|
102
|
+
{
|
103
|
+
:platform => 'x64/win64',
|
104
|
+
:name => 'LookupAccountSidA',
|
105
|
+
:params => [
|
106
|
+
["PCHAR", "lpSystemName", "in"],
|
107
|
+
["LPVOID", "Sid", "in"],
|
108
|
+
["PCHAR", "Name", "out"],
|
109
|
+
["PDWORD", "cchName", "inout"],
|
110
|
+
["PCHAR", "ReferencedDomainName", "out"],
|
111
|
+
["PDWORD", "cchReferencedDomainName", "inout"],
|
112
|
+
["PBLOB", "peUse", "out"]
|
113
|
+
],
|
114
|
+
:return_type => 'BOOL',
|
115
|
+
:dll_name => 'advapi32',
|
116
|
+
:ruby_args => [nil, 1631552, 100, 100, 100, 100, 1],
|
117
|
+
:request_to_client => {
|
118
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
119
|
+
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",
|
120
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
121
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
122
|
+
TLV_TYPE_RAILGUN_DLLNAME => 'advapi32',
|
123
|
+
TLV_TYPE_RAILGUN_FUNCNAME => 'LookupAccountSidA',
|
124
|
+
},
|
125
|
+
:response_from_client => {
|
126
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
127
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
128
|
+
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
129
|
+
TLV_TYPE_RAILGUN_BACK_ERR => 0,
|
130
|
+
},
|
131
|
+
:returned_hash => {
|
132
|
+
"GetLastError"=>0,
|
133
|
+
"return"=>true,
|
134
|
+
"Name"=>"SYSTEM",
|
135
|
+
"ReferencedDomainName"=>"NT AUTHORITY",
|
136
|
+
"peUse"=>"\x05",
|
137
|
+
"cchName"=>6,
|
138
|
+
"cchReferencedDomainName"=>12
|
139
|
+
},
|
140
|
+
},
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end; end; end; end; end; end;
|