librex 0.0.35 → 0.0.36
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/javascriptosdetect.rb +3 -22
- data/lib/rex/exploitation/jsobfu.rb +489 -0
- data/lib/rex/io/stream_abstraction.rb +4 -3
- data/lib/rex/parser/acunetix_nokogiri.rb +394 -0
- data/lib/rex/parser/appscan_nokogiri.rb +366 -0
- data/lib/rex/parser/burp_session_nokogiri.rb +290 -0
- data/lib/rex/parser/nokogiri_doc_mixin.rb +5 -3
- data/lib/rex/pescan/scanner.rb +2 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +30 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +188 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +84 -14
- data/lib/rex/proto/http/header.rb +3 -3
- data/lib/rex/ropbuilder.rb +7 -0
- data/lib/rex/ropbuilder/rop.rb +257 -0
- data/lib/rex/ui/text/table.rb +9 -0
- metadata +10 -3
@@ -0,0 +1,290 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"nokogiri_doc_mixin")
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Parser
|
5
|
+
|
6
|
+
# If Nokogiri is available, define Burp Session document class.
|
7
|
+
#
|
8
|
+
# Burp Session XML files actually provide a lot, but since it also
|
9
|
+
# provides the originating url, we can pull most of the detail from
|
10
|
+
# the URI object.
|
11
|
+
load_nokogiri && class BurpSessionDocument < Nokogiri::XML::SAX::Document
|
12
|
+
|
13
|
+
include NokogiriDocMixin
|
14
|
+
|
15
|
+
# The resolver prefers your local /etc/hosts (or windows equiv), but will
|
16
|
+
# fall back to regular DNS. It retains a cache for the import to avoid
|
17
|
+
# spamming your network with DNS requests.
|
18
|
+
attr_reader :resolv_cache
|
19
|
+
|
20
|
+
# Since we try to resolve every time we hit a new web page, need to
|
21
|
+
# hang on to our misses. Presume that it's a permanent enough failure
|
22
|
+
# that it won't get fixed during this particular import
|
23
|
+
attr_reader :missed_cache
|
24
|
+
|
25
|
+
# If name resolution of the host fails out completely, you will not be
|
26
|
+
# able to import that Scan task. Other scan tasks in the same report
|
27
|
+
# should be unaffected.
|
28
|
+
attr_reader :parse_warning
|
29
|
+
|
30
|
+
def start_document
|
31
|
+
@parse_warnings = []
|
32
|
+
@parse_warned = []
|
33
|
+
@resolv_cache = {}
|
34
|
+
@missed_cache = []
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_element(name=nil,attrs=[])
|
38
|
+
attrs = normalize_attrs(attrs)
|
39
|
+
block = @block
|
40
|
+
@state[:current_tag][name] = true
|
41
|
+
case name
|
42
|
+
when "host", "port", "protocol", "path"
|
43
|
+
@state[:has_text] = true
|
44
|
+
when "status"
|
45
|
+
@state[:has_text] = true
|
46
|
+
when "response"
|
47
|
+
@state[:has_text] = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def end_element(name=nil)
|
52
|
+
block = @block
|
53
|
+
case name
|
54
|
+
when "item" # Wrap up this item, but keep resolved web sites
|
55
|
+
collect_uri
|
56
|
+
report_web_site(&block)
|
57
|
+
handle_parse_warnings(&block)
|
58
|
+
report_web_page(&block)
|
59
|
+
report_web_service_info
|
60
|
+
report_web_host_info
|
61
|
+
# Reset the state once we close a host
|
62
|
+
@state = @state.select {|k| [:current_tag, :web_sites].include? k}
|
63
|
+
when "host"
|
64
|
+
@state[:has_text] = false
|
65
|
+
collect_host
|
66
|
+
@text = nil
|
67
|
+
when "port"
|
68
|
+
@state[:has_text] = false
|
69
|
+
collect_port
|
70
|
+
@text = nil
|
71
|
+
when "protocol"
|
72
|
+
@state[:has_text] = false
|
73
|
+
collect_protocol
|
74
|
+
@text = nil
|
75
|
+
when "path"
|
76
|
+
@state[:has_text] = false
|
77
|
+
collect_path_and_query
|
78
|
+
@text = nil
|
79
|
+
when "status"
|
80
|
+
@state[:has_text] = false
|
81
|
+
collect_status
|
82
|
+
@text = nil
|
83
|
+
when "response"
|
84
|
+
@state[:has_text] = false
|
85
|
+
collect_response
|
86
|
+
@text = nil
|
87
|
+
end
|
88
|
+
@state[:current_tag].delete name
|
89
|
+
end
|
90
|
+
|
91
|
+
def collect_host
|
92
|
+
return unless in_item
|
93
|
+
return unless has_text
|
94
|
+
@state[:host] = @text
|
95
|
+
end
|
96
|
+
|
97
|
+
def collect_port
|
98
|
+
return unless in_item
|
99
|
+
return unless has_text
|
100
|
+
return unless @text.to_i.to_s == @text.to_s
|
101
|
+
@state[:port] = @text.to_i
|
102
|
+
end
|
103
|
+
|
104
|
+
def collect_protocol
|
105
|
+
return unless in_item
|
106
|
+
return unless has_text
|
107
|
+
@state[:protocol] = @text
|
108
|
+
end
|
109
|
+
|
110
|
+
def collect_path_and_query
|
111
|
+
return unless in_item
|
112
|
+
return unless has_text
|
113
|
+
path,query = @text.split(/\?+/,2)
|
114
|
+
return unless path
|
115
|
+
if query
|
116
|
+
@state[:query] = "?#{query}" # Can be nil
|
117
|
+
end
|
118
|
+
if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/
|
119
|
+
real_path = "/#{$1}"
|
120
|
+
else
|
121
|
+
real_path = path
|
122
|
+
end
|
123
|
+
@state[:path] = real_path
|
124
|
+
end
|
125
|
+
|
126
|
+
def collect_status
|
127
|
+
return unless in_item
|
128
|
+
return unless has_text
|
129
|
+
return unless @text.to_i.to_s == @text
|
130
|
+
@state[:status] = @text.to_i
|
131
|
+
end
|
132
|
+
|
133
|
+
def collect_uri
|
134
|
+
return unless in_item
|
135
|
+
return unless @state[:host]
|
136
|
+
return unless @state[:port]
|
137
|
+
return unless @state[:protocol]
|
138
|
+
return unless @state[:path]
|
139
|
+
url = @state[:protocol].to_s
|
140
|
+
url << "://"
|
141
|
+
url << @state[:host].to_s
|
142
|
+
url << ":"
|
143
|
+
url << @state[:port].to_s
|
144
|
+
url << @state[:path]
|
145
|
+
if @state[:query]
|
146
|
+
url << "?"
|
147
|
+
url << @state[:query]
|
148
|
+
end
|
149
|
+
@state[:uri] = URI.parse(url) rescue nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def report_web_host_info
|
153
|
+
return unless @state[:web_site]
|
154
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
155
|
+
return unless @state[:web_site].service.host.name.to_s.empty?
|
156
|
+
host_info = {:workspace => @args[:wspace]}
|
157
|
+
host_info[:address] = @state[:web_site].service.host.address
|
158
|
+
host_info[:name] = @state[:uri].host
|
159
|
+
report_db(:host, host_info)
|
160
|
+
end
|
161
|
+
|
162
|
+
def report_web_service_info
|
163
|
+
return unless @state[:web_site]
|
164
|
+
return unless @state[:service_info]
|
165
|
+
return unless @state[:web_site].service.info.to_s.empty?
|
166
|
+
service_info = {}
|
167
|
+
service_info[:host] = @state[:web_site].service.host
|
168
|
+
service_info[:port] = @state[:web_site].service.port
|
169
|
+
service_info[:proto] = @state[:web_site].service.proto
|
170
|
+
service_info[:info] = @state[:service_info]
|
171
|
+
db_report(:service, service_info)
|
172
|
+
end
|
173
|
+
|
174
|
+
def report_web_page(&block)
|
175
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
176
|
+
return unless @state[:status]
|
177
|
+
return unless @state[:web_site]
|
178
|
+
return unless @state[:response_headers].kind_of? Hash
|
179
|
+
headers = {}
|
180
|
+
@state[:response_headers].each do |k,v|
|
181
|
+
headers[k.to_s.downcase] ||= []
|
182
|
+
headers[k.to_s.downcase] << v
|
183
|
+
end
|
184
|
+
if headers["server"].kind_of? Array
|
185
|
+
@state[:service_info] = headers["server"].first
|
186
|
+
end
|
187
|
+
return unless @state[:response_body]
|
188
|
+
web_page_info = {:workspace => @args[:wspace]}
|
189
|
+
web_page_info[:web_site] = @state[:web_site]
|
190
|
+
web_page_info[:code] = @state[:status]
|
191
|
+
web_page_info[:path] = @state[:uri].path
|
192
|
+
web_page_info[:headers] = headers
|
193
|
+
web_page_info[:body] = @state[:response_body]
|
194
|
+
web_page_info[:query] = @state[:uri].query
|
195
|
+
url = @state[:uri].to_s.gsub(/\?.*/,"")
|
196
|
+
db.emit(:web_page, url, &block) if block
|
197
|
+
db_report(:web_page, web_page_info)
|
198
|
+
end
|
199
|
+
|
200
|
+
def report_web_site(&block)
|
201
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
202
|
+
vhost = @state[:uri].host
|
203
|
+
web_site_info = {:workspace => @args[:wspace]}
|
204
|
+
web_site_info[:vhost] = vhost
|
205
|
+
address = resolve_vhost_address(@state[:uri])
|
206
|
+
return unless address
|
207
|
+
web_site_info[:host] = address
|
208
|
+
web_site_info[:port] = @state[:uri].port
|
209
|
+
web_site_info[:ssl] = @state[:uri].kind_of? URI::HTTPS
|
210
|
+
web_site_obj = db_report(:web_site, web_site_info)
|
211
|
+
return unless web_site_obj
|
212
|
+
@state[:web_sites] ||= []
|
213
|
+
url = "#{@state[:uri].scheme}://#{@state[:uri].host}:#{@state[:uri].port}"
|
214
|
+
unless @state[:web_sites].include? web_site_obj
|
215
|
+
db.emit(:web_site, url, &block)
|
216
|
+
@state[:web_sites] << web_site_obj
|
217
|
+
end
|
218
|
+
@state[:web_site] = web_site_obj
|
219
|
+
end
|
220
|
+
|
221
|
+
def collect_response
|
222
|
+
return unless in_item
|
223
|
+
return unless has_text
|
224
|
+
response_text = @text.dup
|
225
|
+
response_header_text,response_body_text = response_text.split(/\r*\n\r*\n/n,2)
|
226
|
+
return unless response_header_text
|
227
|
+
response_header = Rex::Proto::Http::Packet::Header.new
|
228
|
+
response_header.from_s response_header_text
|
229
|
+
@state[:response_headers] = response_header
|
230
|
+
@state[:response_body] = response_body_text
|
231
|
+
end
|
232
|
+
|
233
|
+
def in_item
|
234
|
+
return false unless in_tag("item")
|
235
|
+
return false unless in_tag("items")
|
236
|
+
return true
|
237
|
+
end
|
238
|
+
|
239
|
+
def has_text
|
240
|
+
return false unless @text
|
241
|
+
return false if @text.strip.empty?
|
242
|
+
@text = @text.strip
|
243
|
+
end
|
244
|
+
|
245
|
+
def handle_parse_warnings(&block)
|
246
|
+
return if @parse_warnings.empty?
|
247
|
+
return unless block
|
248
|
+
@parse_warnings.each_with_index do |pwarn,i|
|
249
|
+
unless @parse_warned.include? i
|
250
|
+
db.emit(:warning, pwarn, &block)
|
251
|
+
@parse_warned << i
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def resolve_address(host)
|
257
|
+
return @resolv_cache[host] if @resolv_cache[host]
|
258
|
+
return false if @missed_cache.include? host
|
259
|
+
address = Rex::Socket.resolv_to_dotted(host) rescue nil
|
260
|
+
@resolv_cache[host] = address
|
261
|
+
if address
|
262
|
+
block = @block
|
263
|
+
db.emit(:address, address, &block) if block
|
264
|
+
else
|
265
|
+
@missed_cache << host
|
266
|
+
end
|
267
|
+
return address
|
268
|
+
end
|
269
|
+
|
270
|
+
# Alias this
|
271
|
+
def resolve_vhost_address(uri)
|
272
|
+
if uri.host
|
273
|
+
address = resolve_address(uri.host)
|
274
|
+
case address
|
275
|
+
when false
|
276
|
+
return false
|
277
|
+
when nil
|
278
|
+
@parse_warnings << "Could not resolve address for '#{uri.host}', skipping."
|
279
|
+
end
|
280
|
+
else
|
281
|
+
@parse_warnings << "Could not determine a host for this import."
|
282
|
+
end
|
283
|
+
address
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
@@ -126,7 +126,8 @@ module Parser
|
|
126
126
|
nonempty_data = data.reject {|k,v| v.nil?}
|
127
127
|
valid_attrs = db_valid_attributes(table)
|
128
128
|
raise "Unknown table `#{table}'" if valid_attrs.empty?
|
129
|
-
|
129
|
+
case table
|
130
|
+
when :note, :web_site, :web_page, :web_form, :web_vuln
|
130
131
|
just_the_facts = nonempty_data
|
131
132
|
else
|
132
133
|
just_the_facts = nonempty_data.select {|k,v| valid_attrs.include? k.to_s.to_sym}
|
@@ -149,8 +150,9 @@ module Parser
|
|
149
150
|
when :vuln
|
150
151
|
Msf::DBManager::Vuln.new.attribute_names.map {|x| x.to_sym} |
|
151
152
|
[:host, :refs, :workspace, :port, :proto]
|
152
|
-
when :note
|
153
|
-
|
153
|
+
when :note, :web_site, :web_page, :web_form, :web_vuln
|
154
|
+
# These guys don't complain
|
155
|
+
[:anything]
|
154
156
|
else
|
155
157
|
[]
|
156
158
|
end
|
data/lib/rex/pescan/scanner.rb
CHANGED
@@ -31,6 +31,7 @@ module Scanner
|
|
31
31
|
if(param['disasm'])
|
32
32
|
#puts [msg].pack('H*').inspect
|
33
33
|
insns = []
|
34
|
+
|
34
35
|
msg.gsub!("; ", "\n")
|
35
36
|
if msg.include?("retn")
|
36
37
|
msg.gsub!("retn", "ret")
|
@@ -39,7 +40,7 @@ module Scanner
|
|
39
40
|
begin
|
40
41
|
d2 = Metasm::Shellcode.assemble(Metasm::Ia32.new, msg).disassemble
|
41
42
|
rescue Metasm::ParseError
|
42
|
-
d2 = Metasm::Shellcode.disassemble(Metasm::Ia32.new, [msg].pack('H*')
|
43
|
+
d2 = Metasm::Shellcode.disassemble(Metasm::Ia32.new, [msg].pack('H*'))
|
43
44
|
end
|
44
45
|
addr = 0
|
45
46
|
while ((di = d2.disassemble_instruction(addr)))
|
@@ -79,6 +79,8 @@ KEY_CREATE_SUB_KEY = 0x00000004
|
|
79
79
|
KEY_ENUMERATE_SUB_KEYS = 0x00000008
|
80
80
|
KEY_NOTIFY = 0x00000010
|
81
81
|
KEY_CREATE_LINK = 0x00000020
|
82
|
+
KEY_WOW64_64KEY = 0x00000100
|
83
|
+
KEY_WOW64_32KEY = 0x00000200
|
82
84
|
KEY_READ = (STANDARD_RIGHTS_READ | KEY_QUERY_VALUE |
|
83
85
|
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & ~SYNCHRONIZE
|
84
86
|
KEY_WRITE = (STANDARD_RIGHTS_WRITE | KEY_SET_VALUE |
|
@@ -7,6 +7,7 @@ require 'rex/post/meterpreter/extensions/stdapi/constants'
|
|
7
7
|
require 'rex/post/meterpreter/extensions/stdapi/stdapi'
|
8
8
|
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key'
|
9
9
|
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value'
|
10
|
+
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key'
|
10
11
|
|
11
12
|
module Rex
|
12
13
|
module Post
|
@@ -44,9 +45,37 @@ class Registry
|
|
44
45
|
return RegistrySubsystem::RegistryKey.new(client, root_key, base_key, perm, root_key)
|
45
46
|
end
|
46
47
|
|
47
|
-
|
48
|
+
request = Packet.create_request('stdapi_registry_open_key')
|
49
|
+
|
50
|
+
request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
|
51
|
+
request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
|
52
|
+
request.add_tlv(TLV_TYPE_PERMISSION, perm)
|
53
|
+
|
54
|
+
response = client.send_request(request)
|
55
|
+
|
56
|
+
return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryKey.new(
|
57
|
+
client, root_key, base_key, perm, response.get_tlv(TLV_TYPE_HKEY).value)
|
48
58
|
end
|
49
59
|
|
60
|
+
#
|
61
|
+
# Opens the supplied registry key on the specified remote host. Requires that the
|
62
|
+
# current process has credentials to access the target and that the target has the
|
63
|
+
# remote registry service running.
|
64
|
+
#
|
65
|
+
def Registry.open_remote_key(target_host, root_key)
|
66
|
+
|
67
|
+
request = Packet.create_request('stdapi_registry_open_remote_key')
|
68
|
+
|
69
|
+
request.add_tlv(TLV_TYPE_TARGET_HOST, target_host)
|
70
|
+
request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
|
71
|
+
|
72
|
+
|
73
|
+
response = client.send_request(request)
|
74
|
+
|
75
|
+
return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RemoteRegistryKey.new(
|
76
|
+
client, target_host, root_key, response.get_tlv(TLV_TYPE_HKEY).value)
|
77
|
+
end
|
78
|
+
|
50
79
|
#
|
51
80
|
# Creates the supplied registry key or opens it if it already exists.
|
52
81
|
#
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rex/post/meterpreter/extensions/stdapi/constants'
|
4
|
+
require 'rex/post/meterpreter/extensions/stdapi/sys/registry'
|
5
|
+
|
6
|
+
module Rex
|
7
|
+
module Post
|
8
|
+
module Meterpreter
|
9
|
+
module Extensions
|
10
|
+
module Stdapi
|
11
|
+
module Sys
|
12
|
+
module RegistrySubsystem
|
13
|
+
|
14
|
+
###
|
15
|
+
#
|
16
|
+
# Class wrapper around a remote registry key on the remote side
|
17
|
+
#
|
18
|
+
###
|
19
|
+
class RemoteRegistryKey
|
20
|
+
|
21
|
+
|
22
|
+
#
|
23
|
+
# Initializes an instance of a registry key using the supplied properties
|
24
|
+
# and HKEY handle from the server.
|
25
|
+
#
|
26
|
+
def initialize(client, target_host, root_key, hkey)
|
27
|
+
self.client = client
|
28
|
+
self.root_key = root_key
|
29
|
+
self.target_host = target_host
|
30
|
+
self.hkey = hkey
|
31
|
+
|
32
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.hkey) )
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.finalize(client,hkey)
|
36
|
+
proc { self.close(client,hkey) }
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
#
|
41
|
+
# Enumerators
|
42
|
+
#
|
43
|
+
##
|
44
|
+
|
45
|
+
#
|
46
|
+
# Enumerates all of the child keys within this registry key.
|
47
|
+
#
|
48
|
+
def each_key(&block)
|
49
|
+
return enum_key.each(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Enumerates all of the child values within this registry key.
|
54
|
+
#
|
55
|
+
def each_value(&block)
|
56
|
+
return enum_value.each(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Retrieves all of the registry keys that are direct descendents of
|
61
|
+
# the class' registry key.
|
62
|
+
#
|
63
|
+
def enum_key()
|
64
|
+
return self.client.sys.registry.enum_key(self.hkey)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Retrieves all of the registry values that exist within the opened
|
69
|
+
# registry key.
|
70
|
+
#
|
71
|
+
def enum_value()
|
72
|
+
return self.client.sys.registry.enum_value(self.hkey)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
##
|
77
|
+
#
|
78
|
+
# Registry key interaction
|
79
|
+
#
|
80
|
+
##
|
81
|
+
|
82
|
+
#
|
83
|
+
# Opens a registry key that is relative to this registry key.
|
84
|
+
#
|
85
|
+
def open_key(base_key, perm = KEY_READ)
|
86
|
+
return self.client.sys.registry.open_key(self.hkey, base_key, perm)
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Creates a registry key that is relative to this registry key.
|
91
|
+
#
|
92
|
+
def create_key(base_key, perm = KEY_READ)
|
93
|
+
return self.client.sys.registry.create_key(self.hkey, base_key, perm)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Deletes a registry key that is relative to this registry key.
|
98
|
+
#
|
99
|
+
def delete_key(base_key, recursive = true)
|
100
|
+
return self.client.sys.registry.delete_key(self.hkey, base_key, recursive)
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Closes the open key. This must be called if the registry
|
105
|
+
# key was opened.
|
106
|
+
#
|
107
|
+
def self.close(client, hkey)
|
108
|
+
if hkey != nil
|
109
|
+
return client.sys.registry.close_key(hkey)
|
110
|
+
end
|
111
|
+
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
|
115
|
+
# Instance method for the same
|
116
|
+
def close()
|
117
|
+
self.class.close(self.client, self.hkey)
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
#
|
122
|
+
# Registry value interaction
|
123
|
+
#
|
124
|
+
##
|
125
|
+
|
126
|
+
#
|
127
|
+
# Sets a value relative to the opened registry key.
|
128
|
+
#
|
129
|
+
def set_value(name, type, data)
|
130
|
+
return self.client.sys.registry.set_value(self.hkey, name, type, data)
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Queries the attributes of the supplied registry value relative to
|
135
|
+
# the opened registry key.
|
136
|
+
#
|
137
|
+
def query_value(name)
|
138
|
+
return self.client.sys.registry.query_value(self.hkey, name)
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Queries the class of the specified key
|
143
|
+
#
|
144
|
+
def query_class
|
145
|
+
return self.client.sys.registry.query_class(self.hkey)
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Delete the supplied registry value.
|
150
|
+
#
|
151
|
+
def delete_value(name)
|
152
|
+
return self.client.sys.registry.delete_value(self.hkey, name)
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
#
|
157
|
+
# Serializers
|
158
|
+
#
|
159
|
+
##
|
160
|
+
|
161
|
+
#
|
162
|
+
# Returns the path to the key.
|
163
|
+
#
|
164
|
+
def to_s
|
165
|
+
return "\\\\" + self.target_host + "\\" + self.root_key.to_s + "\\"
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# The open handle to the key on the server.
|
170
|
+
#
|
171
|
+
attr_reader :hkey
|
172
|
+
#
|
173
|
+
# The root key name, such as HKEY_LOCAL_MACHINE.
|
174
|
+
#
|
175
|
+
attr_reader :root_key
|
176
|
+
#
|
177
|
+
# The remote machine name, such as PDC01
|
178
|
+
#
|
179
|
+
attr_reader :target_host
|
180
|
+
|
181
|
+
protected
|
182
|
+
|
183
|
+
attr_accessor :client # :nodoc:
|
184
|
+
attr_writer :hkey, :root_key, :target_host # :nodoc:
|
185
|
+
end
|
186
|
+
|
187
|
+
end; end; end; end; end; end; end
|
188
|
+
|