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,19 @@
1
+ ##
2
+ # $Id: $
3
+ ##
4
+
5
+ ##
6
+ #
7
+ # RFB protocol support
8
+ #
9
+ # by Joshua J. Drake <jduck>
10
+ #
11
+ # Based on:
12
+ # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
+ # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
+ #
15
+ ##
16
+
17
+ require 'rex/proto/rfb/constants'
18
+ require 'rex/proto/rfb/cipher'
19
+ require 'rex/proto/rfb/client'
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ##
4
+ # $Id: $
5
+ ##
6
+
7
+ ##
8
+ #
9
+ # RFB protocol support
10
+ #
11
+ # by Joshua J. Drake <jduck>
12
+ #
13
+ # Based on:
14
+ # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
15
+ # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
16
+ #
17
+ ##
18
+
19
+ require 'rex/socket'
20
+ require 'rex/proto/rfb'
21
+
22
+ sd = Rex::Socket::Tcp.create('PeerHost' => ENV["VNCHOST"], 'PeerPort' => Rex::Proto::RFB::DefaultPort)
23
+
24
+ v = Rex::Proto::RFB::Client.new(sd)
25
+ if not v.connect('password')
26
+ $stderr.puts v.error
27
+ exit(1)
28
+ end
29
+
30
+ loop {
31
+ sret = select([sd],nil,nil,10)
32
+ puts sret.inspect
33
+ if sret and sret[0].include? sd
34
+ buf = sd.sysread(8192)
35
+ puts "read #{buf.length} bytes: #{buf.inspect}"
36
+ end
37
+ }
@@ -0,0 +1,78 @@
1
+ ##
2
+ # $Id: $
3
+ ##
4
+
5
+ ##
6
+ #
7
+ # RFB protocol support
8
+ #
9
+ # by Joshua J. Drake <jduck>
10
+ #
11
+ # Based on:
12
+ # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
+ # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
+ #
15
+ ##
16
+
17
+ # Required for VNC authentication
18
+ require 'openssl'
19
+
20
+ module Rex
21
+ module Proto
22
+ module RFB
23
+
24
+ ##
25
+ # A bit of information about the DES algorithm was found here:
26
+ # http://www.vidarholen.net/contents/junk/vnc.html
27
+ #
28
+ # In addition, VNC uses two individual 8 byte block encryptions rather than
29
+ # using any block mode (like cbc, ecb, etc).
30
+ ##
31
+
32
+ class Cipher
33
+
34
+ def self.mangle_password(password)
35
+ key = ''
36
+ key = password.dup if password
37
+ key.slice!(8,key.length) if key.length > 8
38
+ key << "\x00" * (8 - key.length) if key.length < 8
39
+
40
+ # We have to mangle the key so the LSB are kept vs the MSB
41
+ [key.unpack('B*').first.scan(/.{8}/).map! { |e| e.reverse }.join].pack('B*')
42
+ end
43
+
44
+ def self.encrypt(plain, password)
45
+ key = self.mangle_password(password)
46
+
47
+ # VNC auth does two 8-byte blocks individually instead supporting some block mode
48
+ cipher = ''
49
+ 2.times { |x|
50
+ c = OpenSSL::Cipher::Cipher.new('des')
51
+ c.encrypt
52
+ c.key = key
53
+ cipher << c.update(plain[x*8, 8])
54
+ }
55
+
56
+ cipher
57
+ end
58
+
59
+ #
60
+ # NOTE: The default password is that of winvnc/etc which is used for
61
+ # encrypting the password(s) on disk/in registry.
62
+ #
63
+ def self.decrypt(cipher, password = "\x17\x52\x6b\x06\x23\x4e\x58\x07")
64
+ key = self.mangle_password(password)
65
+
66
+ # NOTE: This only does one 8 byte block
67
+ plain = ''
68
+ c = OpenSSL::Cipher::Cipher.new('des')
69
+ c.decrypt
70
+ c.key = key
71
+ c.update(cipher)
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,207 @@
1
+ ##
2
+ # $Id: $
3
+ ##
4
+
5
+ ##
6
+ #
7
+ # RFB protocol support
8
+ #
9
+ # by Joshua J. Drake <jduck>
10
+ #
11
+ # Based on:
12
+ # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
+ # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
+ #
15
+ # TODO: determine how to detect a view-only session.
16
+ ##
17
+
18
+ module Rex
19
+ module Proto
20
+ module RFB
21
+
22
+ class Client
23
+
24
+ def initialize(sock, opts = {})
25
+ @sock = sock
26
+ @opts = opts
27
+
28
+ @banner = nil
29
+ @majver = MajorVersion
30
+ @minver = -1
31
+ @auth_types = []
32
+ end
33
+
34
+ def read_error_message
35
+ len = @sock.get_once(4)
36
+ return 'Unknown error' if not len or len.length != 4
37
+
38
+ len = len.unpack("N").first
39
+ @sock.get_once(len)
40
+ end
41
+
42
+ def handshake
43
+ @banner = @sock.get_once(12)
44
+ if not @banner
45
+ @error = "Unable to obtain banner from server"
46
+ return false
47
+ end
48
+
49
+ # RFB Protocol Version 3.3 (1998-01)
50
+ # RFB Protocol Version 3.7 (2003-08)
51
+ # RFB Protocol Version 3.8 (2007-06)
52
+
53
+ if @banner =~ /RFB ([0-9]{3})\.([0-9]{3})/
54
+ maj = $1.to_i
55
+ if maj != MajorVersion
56
+ @error = "Invalid major version number: #{maj}"
57
+ return false
58
+ end
59
+ else
60
+ @error = "Invalid RFB banner: #{@banner}"
61
+ return false
62
+ end
63
+
64
+ @minver = $2.to_i
65
+
66
+ our_ver = "RFB %03d.%03d\n" % [MajorVersion, @minver]
67
+ @sock.put(our_ver)
68
+
69
+ true
70
+ end
71
+
72
+ def connect(password = nil)
73
+ return false if not handshake
74
+ return false if not authenticate(password)
75
+ return false if not send_client_init
76
+ true
77
+ end
78
+
79
+ def send_client_init
80
+ if @opts[:exclusive]
81
+ @sock.put("\x00") # do share.
82
+ else
83
+ @sock.put("\x01") # do share.
84
+ end
85
+ end
86
+
87
+ def authenticate(password = nil)
88
+ type = negotiate_authentication
89
+ return false if not type
90
+
91
+ # Authenticate.
92
+ case type
93
+ when AuthType::None
94
+ # Nothing here.
95
+
96
+ when AuthType::VNC
97
+ return false if not negotiate_vnc_auth(password)
98
+
99
+ end
100
+
101
+ # Handle reading the security result message
102
+ result = @sock.get_once(4)
103
+ if not result
104
+ @error = "Unable to read auth result"
105
+ return false
106
+ end
107
+
108
+ result = result.unpack('N').first
109
+ case result
110
+ when 0
111
+ return true
112
+
113
+ when 1
114
+ if @minver >= 8
115
+ msg = read_error_message
116
+ @error = "Authentication failed: #{msg}"
117
+ else
118
+ @error = "Authentication failed"
119
+ end
120
+ when 2
121
+ @error = "Too many authentication attempts"
122
+ else
123
+ @error = "Unknown authentication result: #{result}"
124
+ end
125
+
126
+ false
127
+ end
128
+
129
+ def negotiate_authentication
130
+ # Authentication type negotiation is protocol version specific.
131
+ if @minver < 7
132
+ buf = @sock.get_once(4)
133
+ if not buf
134
+ @error = "Unable to obtain requested authentication method"
135
+ return nil
136
+ end
137
+ @auth_types = buf.unpack('N')
138
+ if not @auth_types or @auth_types.first == 0
139
+ msg = read_error_message
140
+ @error = "No authentication types available: #{msg}"
141
+ return nil
142
+ end
143
+ else
144
+ buf = @sock.get_once(1)
145
+ if not buf
146
+ @error = "Unable to obtain supported authentication method count"
147
+ return nil
148
+ end
149
+
150
+ # first byte is number of security types
151
+ num_types = buf.unpack("C").first
152
+ if (num_types == 0)
153
+ msg = read_error_message
154
+ @error = "No authentication types available: #{msg}"
155
+ return nil
156
+ end
157
+
158
+ buf = @sock.get_once(num_types)
159
+ if not buf or buf.length != num_types
160
+ @error = "Unable to read authentication types"
161
+ return nil
162
+ end
163
+
164
+ @auth_types = buf.unpack("C*")
165
+ end
166
+
167
+ if not @auth_types or @auth_types.length < 1
168
+ @error = "No authentication types found"
169
+ return nil
170
+ end
171
+
172
+ # Select the one we prefer
173
+ selected = nil
174
+ selected ||= AuthType::None if @opts[:allow_none] and @auth_types.include? AuthType::None
175
+ selected ||= AuthType::VNC if @auth_types.include? AuthType::VNC
176
+
177
+ if not selected
178
+ @error = "No supported authentication method found."
179
+ return nil
180
+ end
181
+
182
+ # For 3.7 and later, clients must state which security-type to use
183
+ @sock.put([selected].pack('C')) if @minver >= 7
184
+
185
+ selected
186
+ end
187
+
188
+ def negotiate_vnc_auth(password = nil)
189
+ challenge = @sock.get_once(16)
190
+ if not challenge or challenge.length != 16
191
+ @error = "Unable to obtain VNC challenge"
192
+ return false
193
+ end
194
+
195
+ response = Cipher.encrypt(challenge, password)
196
+ @sock.put(response)
197
+
198
+ true
199
+ end
200
+
201
+ attr_reader :error, :majver, :minver, :auth_types
202
+ attr_reader :view_only
203
+ end
204
+
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,52 @@
1
+ ##
2
+ # $Id: $
3
+ ##
4
+
5
+ ##
6
+ #
7
+ # RFB protocol support
8
+ #
9
+ # by Joshua J. Drake <jduck>
10
+ #
11
+ # Based on:
12
+ # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
+ # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
+ #
15
+ ##
16
+
17
+ module Rex
18
+ module Proto
19
+ module RFB
20
+
21
+ DefaultPort = 5900
22
+
23
+ # Version information
24
+ MajorVersion = 3
25
+ # NOTE: We will emulate whatever minor version the server reports.
26
+
27
+ # Security types
28
+ class AuthType
29
+ Invalid = 0
30
+ None = 1
31
+ VNC = 2
32
+ RA2 = 5
33
+ RA2ne = 6
34
+ Tight = 16
35
+ Ultra = 17
36
+ TLS = 18
37
+ VeNCrypt = 19
38
+ GtkVncSasl = 20
39
+ MD5Hash = 21
40
+ ColinDeanXVP = 22
41
+
42
+ def self.to_s(num)
43
+ self.constants.each { |c|
44
+ return c.to_s if self.const_get(c) == num
45
+ }
46
+ 'Unknown'
47
+ end
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -1,4 +1,4 @@
1
- # $Id: server.rb 10163 2010-08-27 04:44:02Z jduck $
1
+ # $Id: server.rb 11454 2010-12-30 16:37:58Z hdm $
2
2
  require 'rex/socket'
3
3
  require 'rex/proto/tftp'
4
4
 
@@ -51,7 +51,7 @@ class Server
51
51
  'Context' => context
52
52
  )
53
53
 
54
- self.thread = Thread.new {
54
+ self.thread = Rex::ThreadFactory.spawn("TFTPServerMonitor", false) {
55
55
  monitor_socket
56
56
  }
57
57
  end
@@ -64,10 +64,10 @@ class Server
64
64
  @shutting_down = true
65
65
 
66
66
  # Wait a maximum of 30 seconds for all transfers to finish.
67
- start = Time.now
67
+ start = ::Time.now
68
68
  while (self.transfers.length > 0)
69
69
  ::IO.select(nil, nil, nil, 0.5)
70
- dur = Time.now - start
70
+ dur = ::Time.now - start
71
71
  break if (dur > 30)
72
72
  end
73
73
 
@@ -93,7 +93,7 @@ class Server
93
93
  # Register an entire directory to serve files from
94
94
  #
95
95
  def set_tftproot(rootdir)
96
- @tftproot = rootdir if File.directory?(rootdir)
96
+ @tftproot = rootdir if ::File.directory?(rootdir)
97
97
  end
98
98
 
99
99
 
@@ -101,7 +101,7 @@ class Server
101
101
  # Register a directory to write uploaded files to
102
102
  #
103
103
  def set_output_dir(outdir)
104
- @output_dir = outdir if File.directory?(outdir)
104
+ @output_dir = outdir if ::File.directory?(outdir)
105
105
  end
106
106
 
107
107
 
@@ -153,15 +153,15 @@ class Server
153
153
  # entry to the files hash.
154
154
  #
155
155
  def find_file_in_root(fname)
156
- fn = File.expand_path(File.join(@tftproot, fname))
156
+ fn = ::File.expand_path(::File.join(@tftproot, fname))
157
157
 
158
158
  # Don't allow directory traversal
159
159
  return nil if fn.index(@tftproot) != 0
160
160
 
161
- return nil if not File.file?(fn) or not File.readable?(fn)
161
+ return nil if not ::File.file?(fn) or not ::File.readable?(fn)
162
162
 
163
163
  # Read the file contents, and register it as being served once
164
- data = data = File.open(fn, "rb") { |fd| fd.read(fd.stat.size) }
164
+ data = data = ::File.open(fn, "rb") { |fd| fd.read(fd.stat.size) }
165
165
  register_file(fname, data, true)
166
166
 
167
167
  # Return the last file in the array
@@ -172,7 +172,8 @@ class Server
172
172
  attr_accessor :listen_host, :listen_port, :context
173
173
  attr_accessor :sock, :files, :transfers, :uploaded
174
174
  attr_accessor :thread
175
-
175
+
176
+ attr_accessor :incoming_file_hook
176
177
 
177
178
  protected
178
179
 
@@ -185,14 +186,16 @@ protected
185
186
  nil
186
187
  end
187
188
 
188
-
189
189
  def save_output(tr)
190
190
  self.uploaded << tr[:file]
191
+
192
+ return incoming_file_hook.call(tr) if incoming_file_hook
193
+
191
194
  if @output_dir
192
195
  fn = tr[:file][:name].split(File::SEPARATOR)[-1]
193
196
  if fn
194
- fn = File.join(@output_dir, fn)
195
- File.open(fn, "wb") { |fd|
197
+ fn = ::File.join(@output_dir, fn)
198
+ ::File.open(fn, "wb") { |fd|
196
199
  fd.write(tr[:file][:data])
197
200
  }
198
201
  end
@@ -201,7 +204,7 @@ protected
201
204
 
202
205
 
203
206
  def check_retransmission(tr)
204
- elapsed = Time.now - tr[:last_sent]
207
+ elapsed = ::Time.now - tr[:last_sent]
205
208
  if (elapsed >= tr[:timeout])
206
209
  # max retries reached?
207
210
  if (tr[:retries] < 3)
@@ -262,7 +265,7 @@ protected
262
265
  pkt << chunk
263
266
 
264
267
  send_packet(tr[:from], pkt)
265
- tr[:last_sent] = Time.now
268
+ tr[:last_sent] = ::Time.now
266
269
 
267
270
  # If the file is a one-serve, mark it as started
268
271
  tr[:file][:started] = true if (tr[:file][:once])
@@ -282,7 +285,7 @@ protected
282
285
  pkt = [OpAck, tr[:block]].pack('nn')
283
286
 
284
287
  send_packet(tr[:from], pkt)
285
- tr[:last_sent] = Time.now
288
+ tr[:last_sent] = ::Time.now
286
289
 
287
290
  # If we had a 0-511 byte chunk, we're done.
288
291
  if (tr[:last_size] and tr[:last_size] < tr[:blksize])
@@ -355,7 +358,7 @@ protected
355
358
 
356
359
  #puts "%s %s %s" % [start, fn, mode]
357
360
 
358
- if (not @shutting_down) and (@output_dir)
361
+ if not @shutting_down
359
362
  transfer = {
360
363
  :type => OpWrite,
361
364
  :from => from,