rex 2.0.5 → 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex/exploitation/egghunter.rb +4 -6
  3. data/lib/rex/exploitation/powershell/psh_methods.rb +9 -0
  4. data/lib/rex/java/serialization.rb +2 -1
  5. data/lib/rex/java/serialization/builder.rb +94 -0
  6. data/lib/rex/java/serialization/model.rb +29 -18
  7. data/lib/rex/java/serialization/model/annotation.rb +2 -2
  8. data/lib/rex/java/serialization/model/field.rb +2 -2
  9. data/lib/rex/java/serialization/model/new_array.rb +8 -3
  10. data/lib/rex/java/serialization/model/new_class_desc.rb +3 -3
  11. data/lib/rex/java/serialization/model/new_enum.rb +4 -4
  12. data/lib/rex/java/serialization/model/new_object.rb +17 -10
  13. data/lib/rex/ole/direntry.rb +1 -1
  14. data/lib/rex/ole/samples/create_ole.rb +0 -0
  15. data/lib/rex/ole/samples/dir.rb +0 -0
  16. data/lib/rex/ole/samples/dump_stream.rb +0 -0
  17. data/lib/rex/ole/samples/ole_info.rb +0 -0
  18. data/lib/rex/parser/foundstone_nokogiri.rb +1 -1
  19. data/lib/rex/parser/fs/ntfs.rb +252 -0
  20. data/lib/rex/parser/openvas_nokogiri.rb +2 -0
  21. data/lib/rex/payloads/win32/kernel.rb +3 -3
  22. data/lib/rex/post/meterpreter/client_core.rb +172 -64
  23. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +3 -2
  24. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +12 -10
  25. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +64 -37
  26. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +8 -2
  27. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +15 -3
  28. data/lib/rex/post/meterpreter/packet.rb +41 -38
  29. data/lib/rex/post/meterpreter/packet_dispatcher.rb +7 -1
  30. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +17 -4
  31. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +11 -4
  32. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +1 -1
  33. data/lib/rex/proto.rb +2 -0
  34. data/lib/rex/proto/acpp.rb +17 -0
  35. data/lib/rex/proto/acpp/client.rb +29 -0
  36. data/lib/rex/proto/acpp/message.rb +183 -0
  37. data/lib/rex/proto/http/client.rb +1 -2
  38. data/lib/rex/proto/iax2/call.rb +22 -3
  39. data/lib/rex/proto/iax2/client.rb +1 -0
  40. data/lib/rex/proto/kerberos.rb +13 -0
  41. data/lib/rex/proto/kerberos/client.rb +213 -0
  42. data/lib/rex/proto/kerberos/credential_cache.rb +19 -0
  43. data/lib/rex/proto/kerberos/credential_cache/cache.rb +81 -0
  44. data/lib/rex/proto/kerberos/credential_cache/credential.rb +151 -0
  45. data/lib/rex/proto/kerberos/credential_cache/element.rb +49 -0
  46. data/lib/rex/proto/kerberos/credential_cache/key_block.rb +62 -0
  47. data/lib/rex/proto/kerberos/credential_cache/principal.rb +70 -0
  48. data/lib/rex/proto/kerberos/credential_cache/time.rb +69 -0
  49. data/lib/rex/proto/kerberos/crypto.rb +21 -0
  50. data/lib/rex/proto/kerberos/crypto/rc4_hmac.rb +65 -0
  51. data/lib/rex/proto/kerberos/crypto/rsa_md5.rb +15 -0
  52. data/lib/rex/proto/kerberos/model.rb +133 -0
  53. data/lib/rex/proto/kerberos/model/ap_req.rb +98 -0
  54. data/lib/rex/proto/kerberos/model/authenticator.rb +143 -0
  55. data/lib/rex/proto/kerberos/model/authorization_data.rb +85 -0
  56. data/lib/rex/proto/kerberos/model/checksum.rb +59 -0
  57. data/lib/rex/proto/kerberos/model/element.rb +67 -0
  58. data/lib/rex/proto/kerberos/model/enc_kdc_response.rb +215 -0
  59. data/lib/rex/proto/kerberos/model/encrypted_data.rb +171 -0
  60. data/lib/rex/proto/kerberos/model/encryption_key.rb +106 -0
  61. data/lib/rex/proto/kerberos/model/kdc_request.rb +166 -0
  62. data/lib/rex/proto/kerberos/model/kdc_request_body.rb +315 -0
  63. data/lib/rex/proto/kerberos/model/kdc_response.rb +141 -0
  64. data/lib/rex/proto/kerberos/model/krb_error.rb +219 -0
  65. data/lib/rex/proto/kerberos/model/last_request.rb +82 -0
  66. data/lib/rex/proto/kerberos/model/pre_auth_data.rb +104 -0
  67. data/lib/rex/proto/kerberos/model/pre_auth_enc_time_stamp.rb +126 -0
  68. data/lib/rex/proto/kerberos/model/pre_auth_pac_request.rb +81 -0
  69. data/lib/rex/proto/kerberos/model/principal_name.rb +116 -0
  70. data/lib/rex/proto/kerberos/model/ticket.rb +151 -0
  71. data/lib/rex/proto/kerberos/pac.rb +36 -0
  72. data/lib/rex/proto/kerberos/pac/client_info.rb +53 -0
  73. data/lib/rex/proto/kerberos/pac/element.rb +52 -0
  74. data/lib/rex/proto/kerberos/pac/logon_info.rb +566 -0
  75. data/lib/rex/proto/kerberos/pac/priv_svr_checksum.rb +29 -0
  76. data/lib/rex/proto/kerberos/pac/server_checksum.rb +30 -0
  77. data/lib/rex/proto/kerberos/pac/type.rb +121 -0
  78. data/lib/rex/proto/rmi.rb +7 -0
  79. data/lib/rex/proto/rmi/model.rb +31 -0
  80. data/lib/rex/proto/rmi/model/call.rb +60 -0
  81. data/lib/rex/proto/rmi/model/continuation.rb +76 -0
  82. data/lib/rex/proto/rmi/model/dgc_ack.rb +62 -0
  83. data/lib/rex/proto/rmi/model/element.rb +143 -0
  84. data/lib/rex/proto/rmi/model/output_header.rb +86 -0
  85. data/lib/rex/proto/rmi/model/ping.rb +41 -0
  86. data/lib/rex/proto/rmi/model/ping_ack.rb +41 -0
  87. data/lib/rex/proto/rmi/model/protocol_ack.rb +100 -0
  88. data/lib/rex/proto/rmi/model/return_data.rb +60 -0
  89. data/lib/rex/socket.rb +9 -1
  90. data/lib/rex/socket/tcp_server.rb +3 -0
  91. data/lib/rex/ui/text/dispatcher_shell.rb +4 -4
  92. data/lib/rex/ui/text/output/tee.rb +2 -0
  93. data/lib/rex/zip/samples/comment.rb +0 -0
  94. data/lib/rex/zip/samples/mkwar.rb +0 -0
  95. data/lib/rex/zip/samples/mkzip.rb +0 -0
  96. data/lib/rex/zip/samples/recursive.rb +0 -0
  97. data/rex.gemspec +1 -1
  98. metadata +56 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31837db98ac01dead4073a5d9785ee8c3885772a
4
- data.tar.gz: 0976f856604fdeee60805d11fe36faeee0e4656b
3
+ metadata.gz: 5cc2f7d9e9457482ffe5b8935f8b93c4e57560cc
4
+ data.tar.gz: b6e6ee56e59286b54a62d28540e92fa6363dd6ae
5
5
  SHA512:
6
- metadata.gz: f35c3bb765efa30161a507f41e8e1016296bacb8bb8b80eb0220c8cfc18092957f479f3ea17b1994fc4e38e58e60eed8bcb3e545f6a3f62cebe54a44afca9099
7
- data.tar.gz: 89e3d3600fd209b95a8bf231df5d4ab8d839ca6b1b8e1178e23b676cddf1d1afd7461985c2689b54d71d437fb3839e12497c9f7bde7b5f1f9a59a1655fda82ed
6
+ metadata.gz: 17d81b1cda43811ec7acc076f4c903da5cb48316c399dd08abf2839df6e979b9de977f321e004ec1391fe86d472b450af2262f9be6a30aad8ddc30c2358a107e
7
+ data.tar.gz: f921d0e028d10c3b96eaaa65eff57a39d085dae29067d7e5b64addef567aff2043fc4079801a0cf11053abea603055a3d1ffcaeb9c3bf7788644bf44c0011d1c
@@ -65,12 +65,10 @@ class Egghunter
65
65
  flippage = "\n\tor dx,0xfff"
66
66
  edxdirection = "\n\tinc edx"
67
67
 
68
- if searchforward
69
- if searchforward.to_s.downcase == 'false'
70
- # go backwards
71
- flippage = "\n\txor dl,dl"
72
- edxdirection = "\n\tdec edx"
73
- end
68
+ if searchforward.to_s.downcase == 'false'
69
+ # go backwards
70
+ flippage = "\n\txor dl,dl"
71
+ edxdirection = "\n\tdec edx"
74
72
  end
75
73
 
76
74
  # other vars
@@ -64,6 +64,15 @@ module Powershell
64
64
  def self.get_last_login(user)
65
65
  %Q^ Get-QADComputer -ComputerRole DomainController | foreach { (Get-QADUser -Service $_.Name -SamAccountName "#{user}").LastLogon} | Measure-Latest^
66
66
  end
67
+
68
+ #
69
+ # Disable SSL Certificate verification
70
+ #
71
+ # @return [String] Powershell code to disable SSL verification
72
+ # checks.
73
+ def self.ignore_ssl_certificate
74
+ '[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true};'
75
+ end
67
76
  end
68
77
  end
69
78
  end
@@ -51,4 +51,5 @@ module Rex
51
51
  end
52
52
  end
53
53
 
54
- require 'rex/java/serialization/model'
54
+ require 'rex/java/serialization/model'
55
+ require 'rex/java/serialization/builder'
@@ -0,0 +1,94 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ # This class provides a builder to help in the construction of
7
+ # Java serialized contents.
8
+ class Builder
9
+
10
+ # Creates a Rex::Java::Serialization::Model::NewArray
11
+ #
12
+ # @param opts [Hash{Symbol => <Rex::Java::Serialization::Model::NewClassDesc, String, Array>}]
13
+ # @option opts [Rex::Java::Serialization::Model::NewClassDesc] :description
14
+ # @option opts [String] :values_type
15
+ # @option opts [Array] :values
16
+ # @return [Rex::Java::Serialization::Model::NewArray]
17
+ # @see #new_class
18
+ def new_array(opts = {})
19
+ class_desc = opts[:description] || new_class(opts)
20
+ type = opts[:values_type] || ''
21
+ values = opts[:values] || []
22
+
23
+ array = Rex::Java::Serialization::Model::NewArray.new
24
+ array.array_description = Rex::Java::Serialization::Model::ClassDesc.new
25
+ array.array_description.description = class_desc
26
+ array.type = type
27
+ array.values = values
28
+
29
+ array
30
+ end
31
+
32
+ # Creates a Rex::Java::Serialization::Model::NewObject
33
+ #
34
+ # @param opts [Hash{Symbol => <Rex::Java::Serialization::Model::NewClassDesc, Array>}]
35
+ # @option opts [Rex::Java::Serialization::Model::NewClassDesc] :description
36
+ # @option opts [Array] :data
37
+ # @return [Rex::Java::Serialization::Model::NewObject]
38
+ # @see #new_class
39
+ def new_object(opts = {})
40
+ class_desc = opts[:description] || new_class(opts)
41
+ data = opts[:data] || []
42
+
43
+ object = Rex::Java::Serialization::Model::NewObject.new
44
+ object.class_desc = Rex::Java::Serialization::Model::ClassDesc.new
45
+ object.class_desc.description = class_desc
46
+ object.class_data = data
47
+
48
+ object
49
+ end
50
+
51
+ # Creates a Rex::Java::Serialization::Model::NewClassDesc
52
+ #
53
+ # @param opts [Hash{Symbol => <Rex::Java::Serialization::Model::NewClassDesc, Array>}]
54
+ # @option opts [String] :name
55
+ # @option opts [Fixnum] :serial
56
+ # @option opts [Fixnum] :flags
57
+ # @option opts [Array] :fields
58
+ # @option opts [Array] :annotations
59
+ # @option opts [Rex::Java::Serialization::Model::Element] :super_class
60
+ # @return [Rex::Java::Serialization::Model::NewClassDesc]
61
+ def new_class(opts = {})
62
+ class_name = opts[:name] || ''
63
+ serial_version = opts[:serial] || 0
64
+ flags = opts[:flags] || 2
65
+ fields = opts[:fields] || []
66
+ annotations = opts[:annotations] || [Rex::Java::Serialization::Model::NullReference.new,
67
+ Rex::Java::Serialization::Model::EndBlockData.new]
68
+ super_class = opts[:super_class] || Rex::Java::Serialization::Model::NullReference.new
69
+
70
+ class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
71
+ class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, class_name)
72
+ class_desc.serial_version = serial_version
73
+ class_desc.flags = flags
74
+ class_desc.fields = []
75
+
76
+ fields.each do |f|
77
+ field = Rex::Java::Serialization::Model::Field.new
78
+ field.type = f[0]
79
+ field.name = Rex::Java::Serialization::Model::Utf.new(nil, f[1])
80
+ field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, f[2]) if f[2]
81
+ class_desc.fields << field
82
+ end
83
+
84
+ class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
85
+ class_desc.class_annotation.contents = annotations
86
+ class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
87
+ class_desc.super_class.description = super_class
88
+
89
+ class_desc
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,20 +1,31 @@
1
1
  # -*- coding: binary -*-
2
2
 
3
- require 'rex/java/serialization/model/element'
4
- require 'rex/java/serialization/model/null_reference'
5
- require 'rex/java/serialization/model/reference'
6
- require 'rex/java/serialization/model/reset'
7
- require 'rex/java/serialization/model/utf'
8
- require 'rex/java/serialization/model/long_utf'
9
- require 'rex/java/serialization/model/block_data'
10
- require 'rex/java/serialization/model/block_data_long'
11
- require 'rex/java/serialization/model/end_block_data'
12
- require 'rex/java/serialization/model/contents'
13
- require 'rex/java/serialization/model/new_enum'
14
- require 'rex/java/serialization/model/field'
15
- require 'rex/java/serialization/model/new_array'
16
- require 'rex/java/serialization/model/annotation'
17
- require 'rex/java/serialization/model/class_desc'
18
- require 'rex/java/serialization/model/new_class_desc'
19
- require 'rex/java/serialization/model/new_object'
20
- require 'rex/java/serialization/model/stream'
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+
8
+ autoload :Annotation, 'rex/java/serialization/model/annotation'
9
+ autoload :BlockDataLong, 'rex/java/serialization/model/block_data_long'
10
+ autoload :BlockData, 'rex/java/serialization/model/block_data'
11
+ autoload :ClassDesc, 'rex/java/serialization/model/class_desc'
12
+ autoload :Contents, 'rex/java/serialization/model/contents'
13
+ autoload :Element, 'rex/java/serialization/model/element'
14
+ autoload :EndBlockData, 'rex/java/serialization/model/end_block_data'
15
+ autoload :Field, 'rex/java/serialization/model/field'
16
+ autoload :LongUtf, 'rex/java/serialization/model/long_utf'
17
+ autoload :NewArray, 'rex/java/serialization/model/new_array'
18
+ autoload :NewClassDesc, 'rex/java/serialization/model/new_class_desc'
19
+ autoload :NewEnum, 'rex/java/serialization/model/new_enum'
20
+ autoload :NewObject, 'rex/java/serialization/model/new_object'
21
+ autoload :NullReference, 'rex/java/serialization/model/null_reference'
22
+ autoload :Reference, 'rex/java/serialization/model/reference'
23
+ autoload :Reset, 'rex/java/serialization/model/reset'
24
+ autoload :Stream, 'rex/java/serialization/model/stream'
25
+ autoload :Utf, 'rex/java/serialization/model/utf'
26
+
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -29,7 +29,7 @@ module Rex
29
29
  loop do
30
30
  content = decode_content(io, stream)
31
31
  self.contents << content
32
- return self if content.class == EndBlockData
32
+ return self if content.kind_of?(EndBlockData)
33
33
  end
34
34
 
35
35
  self
@@ -66,4 +66,4 @@ module Rex
66
66
  end
67
67
  end
68
68
  end
69
- end
69
+ end
@@ -55,7 +55,7 @@ module Rex
55
55
  # @return [String] if serialization succeeds
56
56
  # @raise [RuntimeError] if serialization doesn't succeed
57
57
  def encode
58
- unless name.class == Rex::Java::Serialization::Model::Utf
58
+ unless name.kind_of?(Rex::Java::Serialization::Model::Utf)
59
59
  raise ::RuntimeError, 'Failed to serialize Field'
60
60
  end
61
61
 
@@ -169,4 +169,4 @@ module Rex
169
169
  end
170
170
  end
171
171
  end
172
- end
172
+ end
@@ -52,7 +52,7 @@ module Rex
52
52
  # @return [String] if serialization succeeds
53
53
  # @raise [RuntimeError] if serialization doesn't succeed
54
54
  def encode
55
- unless array_description.class == ClassDesc
55
+ unless array_description.kind_of?(ClassDesc)
56
56
  raise ::RuntimeError, 'Failed to serialize NewArray'
57
57
  end
58
58
 
@@ -103,12 +103,17 @@ module Rex
103
103
  raise ::RuntimeError, 'Empty NewArray description'
104
104
  end
105
105
 
106
- unless array_description.class == ClassDesc
106
+ unless array_description.kind_of?(ClassDesc)
107
107
  raise ::RuntimeError, 'Unsupported NewArray description class'
108
108
  end
109
109
 
110
110
  desc = array_description.description
111
111
 
112
+ if desc.class == Reference
113
+ ref = desc.handle - BASE_WIRE_HANDLE
114
+ desc = stream.references[ref]
115
+ end
116
+
112
117
  unless desc.class_name.contents[0] == '[' # Array
113
118
  raise ::RuntimeError, 'Unsupported NewArray description'
114
119
  end
@@ -222,4 +227,4 @@ module Rex
222
227
  end
223
228
  end
224
229
  end
225
- end
230
+ end
@@ -66,8 +66,8 @@ module Rex
66
66
  # @return [String] if serialization succeeds
67
67
  # @raise [RuntimeError] if serialization doesn't succeed
68
68
  def encode
69
- unless class_name.class == Rex::Java::Serialization::Model::Utf &&
70
- class_annotation.class == Rex::Java::Serialization::Model::Annotation &&
69
+ unless class_name.class == Rex::Java::Serialization::Model::Utf ||
70
+ class_annotation.class == Rex::Java::Serialization::Model::Annotation ||
71
71
  super_class.class == Rex::Java::Serialization::Model::ClassDesc
72
72
  raise ::RuntimeError, 'Filed to serialize NewClassDesc'
73
73
  end
@@ -152,4 +152,4 @@ module Rex
152
152
  end
153
153
  end
154
154
  end
155
- end
155
+ end
@@ -41,8 +41,8 @@ module Rex
41
41
  # @return [String] if serialization succeeds
42
42
  # @raise [RuntimeError] if serialization doesn't succeed
43
43
  def encode
44
- unless enum_description.class == ClassDesc &&
45
- constant_name.class == Utf
44
+ unless enum_description.kind_of?(ClassDesc) &&
45
+ constant_name.kind_of?(Utf)
46
46
  raise ::RuntimeError, 'Failed to serialize EnumDescription'
47
47
  end
48
48
 
@@ -68,7 +68,7 @@ module Rex
68
68
  # @raise [RuntimeError] if deserialization doesn't succed
69
69
  def decode_constant_name(io)
70
70
  content = decode_content(io, stream)
71
- raise ::RuntimeError, 'Failed to unserialize NewEnum' unless content.class == Rex::Java::Serialization::Model::Utf
71
+ raise ::RuntimeError, 'Failed to unserialize NewEnum' unless content.kind_of?(Rex::Java::Serialization::Model::Utf)
72
72
 
73
73
  content
74
74
  end
@@ -76,4 +76,4 @@ module Rex
76
76
  end
77
77
  end
78
78
  end
79
- end
79
+ end
@@ -32,9 +32,10 @@ module Rex
32
32
  self.class_desc = ClassDesc.decode(io, stream)
33
33
  stream.add_reference(self) unless stream.nil?
34
34
 
35
- if class_desc.description.class == NewClassDesc
35
+ case class_desc.description
36
+ when NewClassDesc
36
37
  self.class_data = decode_class_data(io, class_desc.description)
37
- elsif class_desc.description.class == Reference
38
+ when Reference
38
39
  ref = class_desc.description.handle - BASE_WIRE_HANDLE
39
40
  self.class_data = decode_class_data(io, stream.references[ref])
40
41
  end
@@ -47,7 +48,7 @@ module Rex
47
48
  # @return [String] if serialization succeeds
48
49
  # @raise [RuntimeError] if serialization doesn't succeed
49
50
  def encode
50
- unless class_desc.class == ClassDesc
51
+ unless class_desc.kind_of?(ClassDesc)
51
52
  raise ::RuntimeError, 'Failed to serialize NewObject'
52
53
  end
53
54
 
@@ -55,7 +56,7 @@ module Rex
55
56
  encoded << class_desc.encode
56
57
 
57
58
  class_data.each do |value|
58
- if value.class == Array
59
+ if value.kind_of?(Array)
59
60
  encoded << encode_value(value)
60
61
  else
61
62
  encoded << encode_content(value)
@@ -70,15 +71,16 @@ module Rex
70
71
  # @return [String]
71
72
  def to_s
72
73
  str = ''
73
- if class_desc.description.class == NewClassDesc
74
+ case class_desc.description
75
+ when NewClassDesc
74
76
  str << class_desc.description.class_name.to_s
75
- elsif class_desc.description.class == Reference
77
+ when Reference
76
78
  str << (class_desc.description.handle - BASE_WIRE_HANDLE).to_s(16)
77
79
  end
78
80
 
79
81
  str << ' => { '
80
- data = class_data.collect { |data| data.to_s }
81
- str << data.join(', ')
82
+ data_str = class_data.collect { |data| data.to_s }
83
+ str << data_str.join(', ')
82
84
  str << ' }'
83
85
  end
84
86
 
@@ -94,7 +96,12 @@ module Rex
94
96
  values = []
95
97
 
96
98
  unless my_class_desc.super_class.description.class == NullReference
97
- values += decode_class_data(io, my_class_desc.super_class.description)
99
+ if my_class_desc.super_class.description.class == Reference
100
+ ref = my_class_desc.super_class.description.handle - BASE_WIRE_HANDLE
101
+ values += decode_class_data(io, stream.references[ref])
102
+ else
103
+ values += decode_class_data(io, my_class_desc.super_class.description)
104
+ end
98
105
  end
99
106
 
100
107
  values += decode_class_fields(io, my_class_desc)
@@ -220,4 +227,4 @@ module Rex
220
227
  end
221
228
  end
222
229
  end
223
- end
230
+ end
@@ -96,7 +96,7 @@ class DirEntry
96
96
  return de
97
97
  end
98
98
  @children.each { |cde|
99
- ret = find_by_sid(cde, sid)
99
+ ret = find_by_sid(sid, cde)
100
100
  if (ret)
101
101
  return ret
102
102
  end
File without changes
File without changes
File without changes
File without changes
@@ -293,7 +293,7 @@ module Rex
293
293
  # XXX: Actually implement more of these
294
294
  def process_service(service,banner)
295
295
  meth = "process_service_#{service.gsub("-","_")}"
296
- if self.respond_to? meth
296
+ if self.respond_to?(meth, true)
297
297
  self.send meth, banner
298
298
  else
299
299
  return (first_line banner)
@@ -0,0 +1,252 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Parser
4
+ ###
5
+ #
6
+ # This class parses the contents of an NTFS partition file.
7
+ # Author : Danil Bazin <danil.bazin[at]hsc.fr> @danilbaz
8
+ #
9
+ ###
10
+ class NTFS
11
+ #
12
+ # Initialize the NTFS class with an already open file handler
13
+ #
14
+ DATA_ATTRIBUTE_ID = 128
15
+ INDEX_ROOT_ID = 144
16
+ INDEX_ALLOCATION_ID = 160
17
+ def initialize(file_handler)
18
+ @file_handler = file_handler
19
+ data = @file_handler.read(4096)
20
+ # Boot sector reading
21
+ @bytes_per_sector = data[11, 2].unpack('v')[0]
22
+ @sector_per_cluster = data[13].unpack('C')[0]
23
+ @cluster_per_mft_record = data[64].unpack('c')[0]
24
+ if @cluster_per_mft_record < 0
25
+ @bytes_per_mft_record = 2**(-@cluster_per_mft_record)
26
+ @cluster_per_mft_record = @bytes_per_mft_record.to_f / @bytes_per_sector / @sector_per_cluster
27
+ else
28
+ @bytes_per_mft_record = @bytes_per_sector * @sector_per_cluster * @cluster_per_mft_record
29
+ end
30
+ @bytes_per_cluster = @sector_per_cluster * @bytes_per_sector
31
+ @mft_logical_cluster_number = data[48, 8].unpack('Q<')[0]
32
+ @mft_offset = @mft_logical_cluster_number * @sector_per_cluster * @bytes_per_sector
33
+ @file_handler.seek(@mft_offset)
34
+ @mft = @file_handler.read(@bytes_per_mft_record)
35
+ end
36
+
37
+ #
38
+ # Gather the MFT entry corresponding to his number
39
+ #
40
+ def mft_record_from_mft_num(mft_num)
41
+ mft_num_offset = mft_num * @cluster_per_mft_record
42
+ mft_data_attribute = mft_record_attribute(@mft)[DATA_ATTRIBUTE_ID]['data']
43
+ cluster_from_attribute_non_resident(mft_data_attribute, mft_num_offset, @bytes_per_mft_record)
44
+ end
45
+
46
+ #
47
+ # Get the size of the file in the $FILENAME (64) attribute
48
+ #
49
+ def real_size_from_filenameattribute(attribute)
50
+ filename_attribute = attribute
51
+ filename_attribute[48, 8].unpack('Q<')[0]
52
+ end
53
+
54
+ #
55
+ # Gather the name of the file from the $FILENAME (64) attribute
56
+ #
57
+ def filename_from_filenameattribute(attribute)
58
+ filename_attribute = attribute
59
+ length_of_name = filename_attribute[64].ord
60
+ # uft16 *2
61
+ d = ::Encoding::Converter.new('UTF-16LE', 'UTF-8')
62
+ d.convert(filename_attribute[66, (length_of_name * 2)])
63
+ end
64
+
65
+ #
66
+ # Get the file from the MFT number
67
+ # The size must be gived because the $FILENAME attribute
68
+ # in the MFT entry does not contain it
69
+ # The file is in $DATA (128) Attribute
70
+ #
71
+ def file_content_from_mft_num(mft_num, size)
72
+ mft_record = mft_record_from_mft_num(mft_num)
73
+ attribute_list = mft_record_attribute(mft_record)
74
+ if attribute_list[DATA_ATTRIBUTE_ID]['resident']
75
+ return attribute_list[DATA_ATTRIBUTE_ID]['data']
76
+ else
77
+ data_attribute = attribute_list[DATA_ATTRIBUTE_ID]['data']
78
+ return cluster_from_attribute_non_resident(data_attribute)[0, size]
79
+ end
80
+ end
81
+
82
+ #
83
+ # parse one index record and return the name, MFT number and size of the file
84
+ #
85
+ def parse_index(index_entry)
86
+ res = {}
87
+ filename_size = index_entry[10, 2].unpack('v')[0]
88
+ filename_attribute = index_entry[16, filename_size]
89
+ # Should be 8 bytes but it doesn't work
90
+ # mft_offset = index_entry[0.unpack('Q<',:8])[0]
91
+ # work with 4 bytes
92
+ mft_offset = index_entry[0, 4].unpack('V')[0]
93
+ res[filename_from_filenameattribute(filename_attribute)] = {
94
+ 'mft_offset' => mft_offset,
95
+ 'file_size' => real_size_from_filenameattribute(filename_attribute) }
96
+ res
97
+ end
98
+
99
+ #
100
+ # parse index_record in $INDEX_ROOT and recursively index_record in
101
+ # INDEX_ALLOCATION
102
+ #
103
+ def parse_index_list(index_record, index_allocation_attribute)
104
+ offset_index_entry_list = index_record[0, 4].unpack('V')[0]
105
+ index_size = index_record[offset_index_entry_list + 8, 2].unpack('v')[0]
106
+ index_size_in_bytes = index_size * @bytes_per_cluster
107
+ index_entry = index_record[offset_index_entry_list, index_size]
108
+ res = {}
109
+ while index_entry[12, 4].unpack('V')[0] & 2 != 2
110
+ res.update(parse_index(index_entry))
111
+ # if son
112
+ if index_entry[12, 4].unpack('V')[0] & 1 == 1
113
+ # should be 8 bytes length
114
+ vcn = index_entry[-8, 4].unpack('V')[0]
115
+ vcn_in_bytes = vcn * @bytes_per_cluster
116
+ res_son = parse_index_list(index_allocation_attribute[vcn_in_bytes + 24, index_size_in_bytes], index_allocation_attribute)
117
+ res.update(res_son)
118
+ end
119
+ offset_index_entry_list += index_size
120
+ index_size = index_record[offset_index_entry_list + 8, 2].unpack('v')[0]
121
+ index_size_in_bytes = index_size * @bytes_per_cluster
122
+ index_entry = index_record [offset_index_entry_list, index_size]
123
+ end
124
+ # if son on the last
125
+ if index_entry[12, 4].unpack('V')[0] & 1 == 1
126
+ # should be 8 bytes length
127
+ vcn = index_entry[-8, 4].unpack('V')[0]
128
+ vcn_in_bytes = vcn * @bytes_per_cluster
129
+ res_son = parse_index_list(index_allocation_attribute[vcn_in_bytes + 24, index_size_in_bytes], index_allocation_attribute)
130
+ res.update(res_son)
131
+ end
132
+ res
133
+ end
134
+
135
+ #
136
+ # return the list of files in attribute directory and their MFT number and size
137
+ #
138
+ def index_list_from_attributes(attributes)
139
+ index_root_attribute = attributes[INDEX_ROOT_ID]
140
+ index_record = index_root_attribute[16, index_root_attribute.length - 16]
141
+ if attributes.key?(INDEX_ALLOCATION_ID)
142
+ return parse_index_list(index_record, attributes[INDEX_ALLOCATION_ID])
143
+ else
144
+ return parse_index_list(index_record, '')
145
+ end
146
+ end
147
+
148
+ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = ((2**31) - 1))
149
+ lowvcn = attribute[16, 8].unpack('Q<')[0]
150
+ highvcn = attribute[24, 8].unpack('Q<')[0]
151
+ offset = attribute[32, 2].unpack('v')[0]
152
+ real_size = attribute[48, 8].unpack('Q<')[0]
153
+ attribut = ''
154
+ run_list_num = lowvcn
155
+ old_offset = 0
156
+ while run_list_num <= highvcn
157
+ first_runlist_byte = attribute[offset].ord
158
+ run_offset_size = first_runlist_byte >> 4
159
+ run_length_size = first_runlist_byte & 15
160
+ run_length = attribute[offset + 1, run_length_size]
161
+ run_length += "\x00" * (8 - run_length_size)
162
+ run_length = run_length.unpack('Q<')[0]
163
+
164
+ offset_run_offset = offset + 1 + run_length_size
165
+ run_offset = attribute[offset_run_offset, run_offset_size]
166
+ if run_offset[-1].ord & 128 == 128
167
+ run_offset += "\xFF" * (8 - run_offset_size)
168
+ else
169
+ run_offset += "\x00" * (8 - run_offset_size)
170
+ end
171
+ run_offset = run_offset.unpack('q<')[0]
172
+ #offset relative to previous offset
173
+ run_offset += old_offset
174
+
175
+ size_wanted = [run_length * @bytes_per_cluster, size_max - attribut.length].min
176
+ if cluster_num + (size_max / @bytes_per_cluster) >= run_list_num && (cluster_num < run_length + run_list_num)
177
+ run_list_offset_in_cluster = run_offset + [cluster_num - run_list_num, 0].max
178
+ run_list_offset = (run_list_offset_in_cluster) * @bytes_per_cluster
179
+ run_list_offset = run_list_offset.to_i
180
+ @file_handler.seek(run_list_offset)
181
+
182
+ data = ''
183
+ while data.length < size_wanted
184
+ data << @file_handler.read(size_wanted - data.length)
185
+ end
186
+ attribut << data
187
+ end
188
+ offset += run_offset_size + run_length_size + 1
189
+ run_list_num += run_length
190
+ old_offset = run_offset
191
+ end
192
+ attribut = attribut[0, real_size]
193
+ attribut
194
+ end
195
+
196
+ #
197
+ # return the attribute list from the MFT record
198
+ # deal with resident and non resident attributes (but not $DATA due to performance issue)
199
+ #
200
+ def mft_record_attribute(mft_record)
201
+ attribute_list_offset = mft_record[20, 2].unpack('C')[0]
202
+ curs = attribute_list_offset
203
+ attribute_identifier = mft_record[curs, 4].unpack('V')[0]
204
+ res = {}
205
+ while attribute_identifier != 0xFFFFFFFF
206
+ # attribute_size=mft_record[curs + 4, 4].unpack('V')[0]
207
+ # should be on 4 bytes but doesnt work
208
+ attribute_size = mft_record[curs + 4, 2].unpack('v')[0]
209
+ # resident
210
+ if mft_record[curs + 8] == "\x00"
211
+ content_size = mft_record[curs + 16, 4].unpack('V')[0]
212
+ content_offset = mft_record[curs + 20, 2].unpack('v')[0]
213
+ res[attribute_identifier] = mft_record[curs + content_offset, content_size]
214
+ else
215
+ # non resident
216
+ if attribute_identifier == DATA_ATTRIBUTE_ID
217
+ res[attribute_identifier] = mft_record[curs, attribute_size]
218
+ else
219
+ res[attribute_identifier] = cluster_from_attribute_non_resident(mft_record[curs, attribute_size])
220
+ end
221
+ end
222
+ if attribute_identifier == DATA_ATTRIBUTE_ID
223
+ res[attribute_identifier] = {
224
+ 'data' => res[attribute_identifier],
225
+ 'resident' => mft_record[curs + 8] == "\x00" }
226
+ end
227
+ curs += attribute_size
228
+ attribute_identifier = mft_record[curs, 4].unpack('V')[0]
229
+ end
230
+ res
231
+ end
232
+
233
+ #
234
+ # return the file path in the NTFS partition
235
+ #
236
+ def file(path)
237
+ repertory = mft_record_from_mft_num(5)
238
+ index_entry = {}
239
+ path.split('\\').each do |r|
240
+ attributes = mft_record_attribute(repertory)
241
+ index = index_list_from_attributes(attributes)
242
+ unless index.key?(r)
243
+ fail ArgumentError, 'File path does not exist', caller
244
+ end
245
+ index_entry = index[r]
246
+ repertory = mft_record_from_mft_num(index_entry['mft_offset'])
247
+ end
248
+ file_content_from_mft_num(index_entry['mft_offset'], index_entry['file_size'])
249
+ end
250
+ end
251
+ end
252
+ end