librex 0.0.35 → 0.0.36

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- if table == :note # Notes don't whine about extra stuff
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
- [:anything]
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
@@ -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*')[0])
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 |
@@ -17,6 +17,11 @@ class Def_netapi32
17
17
  ["PWCHAR","username","in"],
18
18
  ])
19
19
 
20
+ railgun.add_function( 'netapi32', 'NetGetJoinInformation', 'DWORD',[
21
+ ["PBLOB","lpServer","in"],
22
+ ["PDWORD","lpNameBugger","out"],
23
+ ["PDWORD","BufferType","out"]
24
+ ])
20
25
  end
21
26
 
22
27
  end
@@ -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
- return self.create_key(root_key, base_key, perm)
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
+