librex 0.0.5 → 0.0.6

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.
Files changed (68) hide show
  1. data/README.md +1 -1
  2. data/Rakefile +13 -0
  3. data/lib/rex.rb +4 -1
  4. data/lib/rex/assembly/nasm.rb +4 -0
  5. data/lib/rex/compat.rb +31 -1
  6. data/lib/rex/encoder/alpha2/generic.rb +11 -10
  7. data/lib/rex/exceptions.rb +1 -1
  8. data/lib/rex/exploitation/egghunter.rb +27 -0
  9. data/lib/rex/file.rb +13 -0
  10. data/lib/rex/io/stream.rb +9 -1
  11. data/lib/rex/io/stream_abstraction.rb +18 -7
  12. data/lib/rex/io/stream_server.rb +2 -2
  13. data/lib/rex/job_container.rb +1 -1
  14. data/lib/rex/mime/message.rb +5 -4
  15. data/lib/rex/ole.rb +83 -6
  16. data/lib/rex/ole/propset.rb +144 -0
  17. data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
  18. data/lib/rex/parser/ip360_xml.rb +93 -0
  19. data/lib/rex/parser/nessus_xml.rb +118 -0
  20. data/lib/rex/parser/netsparker_xml.rb +94 -0
  21. data/lib/rex/parser/retina_xml.rb +109 -0
  22. data/lib/rex/post/meterpreter/channel.rb +15 -8
  23. data/lib/rex/post/meterpreter/client.rb +32 -3
  24. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +1 -1
  25. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +14 -5
  26. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
  27. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +3 -3
  28. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +1 -1
  29. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +1 -1
  30. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +5 -0
  31. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +16 -8
  32. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -7
  33. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +1 -1
  34. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +15 -4
  35. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +13 -7
  36. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +20 -0
  37. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
  38. data/lib/rex/post/meterpreter/packet_dispatcher.rb +18 -7
  39. data/lib/rex/post/meterpreter/packet_response_waiter.rb +10 -17
  40. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +1 -1
  41. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +16 -6
  42. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +4 -5
  43. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +2 -0
  44. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +4 -2
  45. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
  46. data/lib/rex/proto/dhcp/server.rb +8 -4
  47. data/lib/rex/proto/http/client.rb +19 -45
  48. data/lib/rex/proto/http/packet.rb +8 -5
  49. data/lib/rex/proto/http/response.rb +8 -3
  50. data/lib/rex/proto/http/server.rb +1 -1
  51. data/lib/rex/proto/proxy/socks4a.rb +4 -4
  52. data/lib/rex/proto/rfb.rb +19 -0
  53. data/lib/rex/proto/rfb.rb.ut.rb +37 -0
  54. data/lib/rex/proto/rfb/cipher.rb +78 -0
  55. data/lib/rex/proto/rfb/client.rb +207 -0
  56. data/lib/rex/proto/rfb/constants.rb +52 -0
  57. data/lib/rex/proto/tftp/server.rb +20 -17
  58. data/lib/rex/services/local_relay.rb +1 -1
  59. data/lib/rex/socket.rb +69 -10
  60. data/lib/rex/socket/comm/local.rb +7 -4
  61. data/lib/rex/socket/range_walker.rb +14 -1
  62. data/lib/rex/text.rb +28 -3
  63. data/lib/rex/text.rb.ut.rb +14 -0
  64. data/lib/rex/thread_factory.rb +42 -0
  65. data/lib/rex/ui/text/input/buffer.rb +1 -1
  66. data/lib/rex/zip/archive.rb +74 -9
  67. data/lib/rex/zip/entry.rb +6 -1
  68. metadata +22 -7
@@ -0,0 +1,94 @@
1
+ module Rex
2
+ module Parser
3
+
4
+
5
+ class NetSparkerXMLStreamParser
6
+
7
+ attr_accessor :on_found_vuln
8
+
9
+ def initialize(on_found_vuln = nil)
10
+ self.on_found_vuln = on_found_vuln if on_found_vuln
11
+ reset_state
12
+ end
13
+
14
+ def reset_state
15
+ @state = :generic_state
16
+ @vuln = {'info' => []}
17
+ @attr = {}
18
+ end
19
+
20
+ def tag_start(name, attributes)
21
+ @state = "in_#{name.downcase}".intern
22
+ @attr = attributes
23
+
24
+ case name
25
+ when "vulnerability"
26
+ @vuln['confirmed'] = attributes['confirmed']
27
+ end
28
+ end
29
+
30
+ def text(str)
31
+ case @state
32
+ when :in_url
33
+ @vuln['url'] ||= ""
34
+ @vuln['url'] += str
35
+ when :in_type
36
+ @vuln['type'] ||= ""
37
+ @vuln['type'] += str
38
+ when :in_severity
39
+ @vuln['severity'] ||= ""
40
+ @vuln['severity'] += str
41
+ when :in_vulnerableparametertype
42
+ @vuln["vparam_type"] ||= ""
43
+ @vuln["vparam_type"] += str
44
+ when :in_vulnerableparameter
45
+ @vuln["vparam_name"] ||= ""
46
+ @vuln["vparam_name"] += str
47
+ when :in_vulnerableparametervalue
48
+ @vuln["vparam_value"] ||= ""
49
+ @vuln["vparam_value"] += str
50
+ when :in_rawrequest
51
+ @vuln["request"] ||= ""
52
+ @vuln["request"] += str
53
+ when :in_rawresponse
54
+ @vuln["response"] ||= ""
55
+ @vuln["response"] += str
56
+ when :in_info
57
+ # <info name="Identified Internal Path(s)">C:\AppServ\www\test-apps\dokeos\main\inc\banner.inc.php</info>
58
+ if not str.to_s.strip.empty?
59
+ @vuln['info'] << [@attr['name'] || "Information", str]
60
+ end
61
+ when :in_netsparker
62
+ when :in_target
63
+ when :in_scantime
64
+ when :generic_state
65
+ when :in_vulnerability
66
+ when :in_extrainformation
67
+ else
68
+ # $stderr.puts "unknown state: #{@state}"
69
+ end
70
+ end
71
+
72
+ def tag_end(name)
73
+ case name
74
+ when "vulnerability"
75
+ @vuln.keys.each do |k|
76
+ @vuln[k] = @vuln[k].strip if @vuln[k].kind_of?(::String)
77
+ end
78
+ on_found_vuln.call(@vuln) if on_found_vuln
79
+ reset_state
80
+ end
81
+ end
82
+
83
+ # We don't need these methods, but they're necessary to keep REXML happy
84
+ def xmldecl(version, encoding, standalone); end
85
+ def cdata; end
86
+ def comment(str); end
87
+ def instruction(name, instruction); end
88
+ def attlist; end
89
+ end
90
+ end
91
+ end
92
+
93
+ __END__
94
+
@@ -0,0 +1,109 @@
1
+ module Rex
2
+ module Parser
3
+
4
+ # XXX - Retina XML does not include ANY service/port information export
5
+ class RetinaXMLStreamParser
6
+
7
+ attr_accessor :on_found_host
8
+
9
+ def initialize(on_found_host = nil)
10
+ reset_state
11
+ self.on_found_host = on_found_host if on_found_host
12
+ end
13
+
14
+ def reset_state
15
+ @state = :generic_state
16
+ @host = { 'vulns' => [] }
17
+ reset_audit_state
18
+ end
19
+
20
+ def reset_audit_state
21
+ @audit = { 'refs' => [] }
22
+ end
23
+
24
+ def tag_start(name, attributes)
25
+ @state = "in_#{name.downcase}".intern
26
+ end
27
+
28
+ def text(str)
29
+ case @state
30
+ when :in_ip
31
+ @host["address"] = str
32
+ when :in_dnsname
33
+ @host["hostname"] = str.split(/\s+/).first
34
+ when :in_netbiosname
35
+ @host["netbios"] = str
36
+ when :in_mac
37
+ @host["mac"] = str
38
+ when :in_os
39
+ @host["os"] = str
40
+ when :in_rthid
41
+ @audit['refs'].push(['RETINA', str])
42
+ when :in_cve
43
+ str.split(",").each do |cve|
44
+ cve = cve.to_s.strip
45
+ next if cve.empty?
46
+ pre,val = cve.split('-', 2)
47
+ next if not val
48
+ next if pre != "CVE"
49
+ @audit['refs'].push( ['CVE', val] )
50
+ end
51
+ when :in_name
52
+ @audit['name'] = str
53
+ when :in_description
54
+ @audit['description'] = str
55
+ when :in_risk
56
+ @audit['risk'] = str
57
+ when :in_cce
58
+ @audit['cce'] = str
59
+ when :in_date
60
+ @audit['data'] = str
61
+ end
62
+ end
63
+
64
+ def tag_end(name)
65
+ case name
66
+ when "host"
67
+ on_found_host.call(@host) if on_found_host
68
+ reset_state
69
+ when "audit"
70
+ @host['vulns'].push @audit
71
+ reset_audit_state
72
+ end
73
+ end
74
+
75
+ # We don't need these methods, but they're necessary to keep REXML happy
76
+ def xmldecl(version, encoding, standalone); end
77
+ def cdata; end
78
+ def comment(str); end
79
+ def instruction(name, instruction); end
80
+ def attlist; end
81
+ end
82
+ end
83
+ end
84
+
85
+ __END__
86
+ <scanJob>
87
+ <hosts>
88
+ <host>
89
+ <ip>10.2.79.98</ip>
90
+ <netBIOSName>bsmith-10156B07C</netBIOSName>
91
+ <dnsName>bsmith-10156b07c.core.testcorp.com random.testcorp.com</dnsName>
92
+ <mac>00:02:29:0E:38:2B</mac>
93
+ <os>Windows Server 2003 (X64), Service Pack 2</os>
94
+ <audit>
95
+ <rthID>7851</rthID>
96
+ <cve>CVE-2009-0089,CVE-2009-0550,CVE-2009-0086</cve>
97
+ <cce>N/A</cce>
98
+ <name>Microsoft Windows HTTP Services Multiple Vulnerabilities (960803)</name>
99
+ <description>Microsoft Windows HTTP Services contains multiple vulnerabilities when handling ..</description>
100
+ <date>09/15/2010</date>
101
+ <risk>Low</risk>
102
+ <pciLevel>5 (Urgent)</pciLevel>
103
+ <cvssScore>10 [AV:N/AC:L/Au:N/C:C/I:C/A:C]</cvssScore>
104
+ <fixInformation>....</fixInformation>
105
+ </audit>
106
+ </host>
107
+ </hosts>
108
+ </scanJob>
109
+
@@ -141,6 +141,11 @@ class Channel
141
141
  if (cid and client)
142
142
  client.add_channel(self)
143
143
  end
144
+ ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.cid) )
145
+ end
146
+
147
+ def self.finalize(client,cid)
148
+ proc { self._close(client,cid) }
144
149
  end
145
150
 
146
151
  ##
@@ -262,27 +267,29 @@ class Channel
262
267
  #
263
268
  # Closes the channel.
264
269
  #
265
- def _close(addends = nil)
266
- if (self.cid == nil)
270
+ def self._close(client, cid, addends=nil)
271
+ if (cid == nil)
267
272
  raise IOError, "Channel has been closed.", caller
268
273
  end
269
274
 
270
275
  request = Packet.create_request('core_channel_close')
271
276
 
272
277
  # Populate the request
273
- request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
278
+ request.add_tlv(TLV_TYPE_CHANNEL_ID, cid)
274
279
  request.add_tlvs(addends)
275
280
 
276
- self.client.send_request(request)
281
+ client.send_request(request, nil)
277
282
 
278
283
  # Disassociate this channel instance
279
- self.client.remove_channel(self.cid)
280
-
281
- self.cid = nil
284
+ client.remove_channel(cid)
282
285
 
283
286
  return true
284
287
  end
285
-
288
+
289
+ def _close(addends = nil)
290
+ self.class._close(self.client, self.cid, addends)
291
+ self.cid = nil
292
+ end
286
293
  #
287
294
  # Enables or disables interactive mode.
288
295
  #
@@ -41,6 +41,23 @@ class Client
41
41
  #
42
42
  @@ext_hash = {}
43
43
 
44
+ #
45
+ # Cached SSL certificate (required to scale)
46
+ #
47
+ @@ssl_ctx = nil
48
+
49
+ #
50
+ # Mutex to synchronize class-wide operations
51
+ #
52
+ @@ssl_mutex = ::Mutex.new
53
+
54
+ #
55
+ # Lookup the error that occurred
56
+ #
57
+ def self.lookup_error(code)
58
+ code
59
+ end
60
+
44
61
  #
45
62
  # Checks the extension hash to see if a class has already been associated
46
63
  # with the supplied extension name.
@@ -133,6 +150,11 @@ class Client
133
150
  end
134
151
 
135
152
  def generate_ssl_context
153
+ @@ssl_mutex.synchronize do
154
+ if not @@ssl_ctx
155
+
156
+ wlog("Generating SSL certificate for Meterpreter sessions")
157
+
136
158
  key = OpenSSL::PKey::RSA.new(1024){ }
137
159
  cert = OpenSSL::X509::Certificate.new
138
160
  cert.version = 2
@@ -175,7 +197,14 @@ class Client
175
197
 
176
198
  ctx.session_id_context = Rex::Text.rand_text(16)
177
199
 
178
- return ctx
200
+ wlog("Generated SSL certificate for Meterpreter sessions")
201
+
202
+ @@ssl_ctx = ctx
203
+
204
+ end # End of if not @ssl_ctx
205
+ end # End of mutex.synchronize
206
+
207
+ @@ssl_ctx
179
208
  end
180
209
 
181
210
  #
@@ -197,7 +226,7 @@ class Client
197
226
  # waiting for a response.
198
227
  #
199
228
  def Client.default_timeout
200
- return 30
229
+ return 300
201
230
  end
202
231
 
203
232
  ##
@@ -233,7 +262,7 @@ class Client
233
262
 
234
263
  # No new constants added?
235
264
  if ((diff = new - old).empty?)
236
- return false
265
+ diff = [ name.capitalize ]
237
266
  end
238
267
 
239
268
  klass = Rex::Post::Meterpreter::Extensions.const_get(diff[0]).const_get(diff[0])
@@ -51,7 +51,7 @@ class Sniffer < Extension
51
51
  request = Packet.create_request('sniffer_capture_start')
52
52
  request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
53
53
  request.add_tlv(TLV_TYPE_SNIFFER_PACKET_COUNT, maxp.to_i)
54
- request.add_tlv(TLV_TYPE_SNIFFER_ADDITIONAL_FILTER, filter) if filter.length
54
+ request.add_tlv(TLV_TYPE_SNIFFER_ADDITIONAL_FILTER, filter) if filter.length > 0
55
55
  response = client.send_request(request)
56
56
  end
57
57
 
@@ -18,7 +18,7 @@ module Fs
18
18
  ###
19
19
  class Dir < Rex::Post::Dir
20
20
 
21
- class <<self
21
+ class << self
22
22
  attr_accessor :client
23
23
  end
24
24
 
@@ -192,7 +192,7 @@ class Dir < Rex::Post::Dir
192
192
  # Downloads the contents of a remote directory a
193
193
  # local directory, optionally in a recursive fashion.
194
194
  #
195
- def Dir.download(dst, src, recursive = false, &stat)
195
+ def Dir.download(dst, src, recursive = false, force = true, &stat)
196
196
  self.entries(src).each { |src_sub|
197
197
  dst_item = dst + ::File::SEPARATOR + src_sub
198
198
  src_item = src + File::SEPARATOR + src_sub
@@ -205,8 +205,17 @@ class Dir < Rex::Post::Dir
205
205
 
206
206
  if (src_stat.file?)
207
207
  stat.call('downloading', src_item, dst_item) if (stat)
208
- client.fs.file.download(dst_item, src_item)
209
- stat.call('downloaded', src_item, dst_item) if (stat)
208
+ begin
209
+ client.fs.file.download(dst_item, src_item)
210
+ stat.call('downloaded', src_item, dst_item) if (stat)
211
+ rescue ::Rex::Post::Meterpreter::RequestError => e
212
+ if force
213
+ stat.call('failed', src_item, dst_item) if (stat)
214
+ else
215
+ raise e
216
+ end
217
+ end
218
+
210
219
  elsif (src_stat.directory?)
211
220
  if (recursive == false)
212
221
  next
@@ -218,7 +227,7 @@ class Dir < Rex::Post::Dir
218
227
  end
219
228
 
220
229
  stat.call('mirroring', src_item, dst_item) if (stat)
221
- download(dst_item, src_item, recursive, &stat)
230
+ download(dst_item, src_item, recursive, force, &stat)
222
231
  stat.call('mirrored', src_item, dst_item) if (stat)
223
232
  end
224
233
  }
@@ -28,7 +28,7 @@ Separator = "\\"
28
28
 
29
29
  include Rex::Post::File
30
30
 
31
- class <<self
31
+ class << self
32
32
  attr_accessor :client
33
33
  end
34
34
 
@@ -84,7 +84,7 @@ class Socket
84
84
  begin
85
85
  return SocketSubsystem::TcpServerChannel.open(client, params)
86
86
  rescue ::Rex::Post::Meterpreter::RequestError => e
87
- case e.result
87
+ case e.code
88
88
  when 10000 .. 10100
89
89
  raise ::Rex::ConnectionError.new
90
90
  end
@@ -103,7 +103,7 @@ class Socket
103
103
  end
104
104
  return nil
105
105
  rescue ::Rex::Post::Meterpreter::RequestError => e
106
- case e.result
106
+ case e.code
107
107
  when 10000 .. 10100
108
108
  raise ::Rex::ConnectionError.new
109
109
  end
@@ -118,7 +118,7 @@ class Socket
118
118
  begin
119
119
  return SocketSubsystem::UdpChannel.open(client, params)
120
120
  rescue ::Rex::Post::Meterpreter::RequestError => e
121
- case e.result
121
+ case e.code
122
122
  when 10000 .. 10100
123
123
  raise ::Rex::ConnectionError.new
124
124
  end
@@ -168,7 +168,7 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream
168
168
  begin
169
169
  super(*args)
170
170
  rescue ::Rex::Post::Meterpreter::RequestError => e
171
- case e.result
171
+ case e.code
172
172
  when 10000 .. 10100
173
173
  raise ::Rex::ConnectionError.new
174
174
  end
@@ -194,7 +194,7 @@ class UdpChannel < Rex::Post::Meterpreter::Channel
194
194
  begin
195
195
  super(*args)
196
196
  rescue ::Rex::Post::Meterpreter::RequestError => e
197
- case e.result
197
+ case e.code
198
198
  when 10000 .. 10100
199
199
  raise ::Rex::ConnectionError.new
200
200
  end
@@ -16,6 +16,7 @@ require 'rex/post/meterpreter/extensions/stdapi/sys/event_log'
16
16
  require 'rex/post/meterpreter/extensions/stdapi/sys/power'
17
17
  require 'rex/post/meterpreter/extensions/stdapi/railgun/railgun'
18
18
  require 'rex/post/meterpreter/extensions/stdapi/ui'
19
+ require 'rex/post/meterpreter/extensions/stdapi/webcam/webcam'
19
20
 
20
21
  module Rex
21
22
  module Post
@@ -74,6 +75,10 @@ class Stdapi < Extension
74
75
  'name' => 'railgun',
75
76
  'ext' => Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun.new(client)
76
77
  },
78
+ {
79
+ 'name' => 'webcam',
80
+ 'ext' => Rex::Post::Meterpreter::Extensions::Stdapi::Webcam::Webcam.new(client)
81
+ },
77
82
  {
78
83
  'name' => 'ui',
79
84
  'ext' => UI.new(client)