librex 0.0.32 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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;
|