librex 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,