ruby_smb 3.2.2 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20c59ae356835caa5149193af377ecb8aaf5f1e635f34d8f660d9da1df6a94d5
4
- data.tar.gz: dbb749afb04c0a9909af9667e0b602ebf43cf00770a7a1d2a4df0e0a520db897
3
+ metadata.gz: 8f850321711ac70e25f6b483f82454520f2b567cc349ee02eb99bba5c48dfeb4
4
+ data.tar.gz: 22ee0ab297710e76071fa8302165b903b39d211205ca1d6b95d697bf3eecae67
5
5
  SHA512:
6
- metadata.gz: 0d826659151d98a13517cb5026dde99852ec2feaaeb6af17559782c2147026ae8cebc5ba0c19a576fb4e87e1c0950e33a3f9c9026fe8752d6503fe263796fdaf
7
- data.tar.gz: 057f902a9540bdf4b312ec3000441fcdba9a930021a15ca12935c2b486647edae85475991c0837876e1f3b365d9c791aeecb11533970f9a63e4d9df6fe13d48a
6
+ metadata.gz: 8708897bda47dd2c07b064eaafbbfe8641af469a1b5688a98bbef9e38119675de9ce52287fdb00c75f908e29e70499d14203fc53a11c6824691c315a5ebeb746
7
+ data.tar.gz: aad169c776223bb67198ba223f0b53d640706540f67ec125d4527a05fa4ac8c42676588b84f5e0385c4db846631783159c2a44801964284b6ae0b78b83c0a031
checksums.yaml.gz.sig CHANGED
Binary file
@@ -26,6 +26,7 @@ client = RubySMB::Dcerpc::Client.new(
26
26
  client.connect
27
27
  puts('Binding to DRSR...')
28
28
  client.bind(
29
+ endpoint: RubySMB::Dcerpc::Drsr,
29
30
  auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
30
31
  auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
31
32
  )
@@ -1315,5 +1315,123 @@ module RubySMB::Dcerpc::Ndr
1315
1315
  end
1316
1316
  end
1317
1317
 
1318
+ # (IDL/NDR) Pickles as defined in
1319
+ # [(IDL/NDR) # Pickles](https://pubs.opengroup.org/onlinepubs/9668899/chap2.htm#tagcjh_05_01_07)
1320
+ # and
1321
+ # [2.2.6 Type Serialization Version # 1](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/9a1d0f97-eac0-49ab-a197-f1a581c2d6a0)
1322
+
1323
+ # [2.2.6.1 Common Type Header for the Serialization Stream](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/6d75d40e-e2d2-4420-b9e9-8508a726a9ae)
1324
+ class TypeSerialization1CommonTypeHeader < BinData::Record
1325
+ default_parameter byte_align: 8
1326
+ endian :little
1327
+
1328
+ uint8 :version, initial_value: 1
1329
+ uint8 :endianness, initial_value: 0x10
1330
+ uint16 :common_header_length, initial_value: 8
1331
+ uint32 :filler, initial_value: 0xCCCCCCCC
1332
+ end
1333
+
1334
+ # [2.2.6.2 Private Header for Constructed Type](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/63949ba8-bc88-4c0c-9377-23f14b197827)
1335
+ class TypeSerialization1PrivateHeader < BinData::Record
1336
+ default_parameter byte_align: 8
1337
+ endian :little
1338
+
1339
+ uint32 :object_buffer_length, initial_value: -> { buffer_length(@obj) }
1340
+ uint32 :filler, initial_value: 0x00000000
1341
+
1342
+ def buffer_length(obj)
1343
+ parent.respond_to?(:field_length) ? parent.field_length(obj.parent) : 0
1344
+ end
1345
+ end
1346
+
1347
+ # [2.2.6 Type Serialization Version 1](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/9a1d0f97-eac0-49ab-a197-f1a581c2d6a0)
1348
+ #
1349
+ # This structure is not meant to be instantiated directly. Instead, the
1350
+ # structure with the fields to be serialized needs to inherit from
1351
+ # TypeSerialization1. This class will take care of adding the
1352
+ # TypeSerialization1PrivateHeader fields in front of any NDR constructed type
1353
+ # structures and setting the buffer length field (:object_buffer_length) to
1354
+ # the correct value.
1355
+ #
1356
+ # Example:
1357
+ #
1358
+ # class TestStruct < RubySMB::Dcerpc::Ndr::NdrStruct
1359
+ # default_parameters byte_align: 8
1360
+ # endian :little
1361
+
1362
+ # rpc_unicode_string :full_name
1363
+ # ndr_uint32 :user_id
1364
+ # end
1365
+
1366
+ # class TestTypeSerialization1 < RubySMB::Dcerpc::Ndr::TypeSerialization1
1367
+ # default_parameter byte_align: 8
1368
+ # endian :little
1369
+ #
1370
+ # test_struct :data1
1371
+ # uint32 :value1, initial_value: 5
1372
+ # uint32 :value2, initial_value: 6
1373
+ # test_struct :data2
1374
+ # uint32 :value3, initial_value: 7
1375
+ # test_struct :data3
1376
+ # end
1377
+ #
1378
+ # This will result in the following structure:
1379
+ # {
1380
+ # :common_header => {:version=>1, :endianness=>16, :common_header_length=>8, :filler=>3435973836},
1381
+ # :private_header1 => {:object_buffer_length=>12, :filler=>0},
1382
+ # :data1 => {:full_name=>{:buffer_length=>0, :maximum_length=>0, :buffer=>:null}, :user_id=>0},
1383
+ # :value1 => 5,
1384
+ # :value2 => 6,
1385
+ # :private_header2 => {:object_buffer_length=>12, :filler=>0},
1386
+ # :data2 => {:full_name=>{:buffer_length=>0, :maximum_length=>0, :buffer=>:null}, :user_id=>0},
1387
+ # :value3 => 7,
1388
+ # :private_header3 => {:object_buffer_length=>12, :filler=>0},
1389
+ # :data3 => {:full_name=>{:buffer_length=>0, :maximum_length=>0, :buffer=>:null}, :user_id=>0}
1390
+ # }
1391
+ #
1392
+ class TypeSerialization1 < BinData::Record
1393
+ PRIVATE_HEADER_BASE_NAME = 'private_header'.freeze
1394
+
1395
+ default_parameter byte_align: 8
1396
+ endian :little
1397
+ search_prefix :type_serialization1
1398
+
1399
+ common_type_header :common_header
1400
+
1401
+ def field_length(obj)
1402
+ length = 0
1403
+ index = find_index_of(obj)
1404
+ if index
1405
+ each_pair {|n, o| length = o.num_bytes if n == field_names[index + 1]}
1406
+ end
1407
+ length
1408
+ end
1409
+
1410
+ def self.method_missing(symbol, *args, &block)
1411
+ return super if dsl_parser.respond_to?(symbol)
1412
+
1413
+ klass = BinData::RegisteredClasses.lookup(symbol, {endian: dsl_parser.endian, search_prefix: dsl_parser.search_prefix})
1414
+ if klass.new.is_a?(ConstructedTypePlugin)
1415
+ # We cannot have two fields with the same name. So, here we look for
1416
+ # existing TypeSerialization1PrivateHeader fields and just increment
1417
+ # the ending number of the last TypeSerialization1PrivateHeader field
1418
+ # to make the new name unique.
1419
+ names = dsl_parser.fields.find_all do |field|
1420
+ field.prototype.instance_variable_get(:@obj_class) == TypeSerialization1PrivateHeader
1421
+ end.map(&:name).sort
1422
+ if names.empty?
1423
+ new_name = "#{PRIVATE_HEADER_BASE_NAME}1"
1424
+ else
1425
+ num = names.last.match(/#{PRIVATE_HEADER_BASE_NAME}(\d)$/)[1].to_i
1426
+ new_name = "#{PRIVATE_HEADER_BASE_NAME}#{num + 1}"
1427
+ end
1428
+
1429
+ super(:private_header, new_name.to_sym)
1430
+ end
1431
+
1432
+ super
1433
+ end
1434
+ end
1435
+
1318
1436
  end
1319
1437
 
@@ -259,6 +259,8 @@ module RubySMB
259
259
  3 => 'des-cbc-md5',
260
260
  17 => 'aes128-cts-hmac-sha1-96',
261
261
  18 => 'aes256-cts-hmac-sha1-96',
262
+ # Windows Server 2008 and later DC includes a KeyType of -140. Not present when the domain functional level is raised to DS_BEHAVIOR_WIN2008 or greater
263
+ # [Appendix_A_24](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/fa61e5fc-f8fb-4d5b-9695-c724af0c3829#Appendix_A_24)
262
264
  0xffffff74 => 'rc4_hmac'
263
265
  }
264
266
 
@@ -461,7 +463,7 @@ module RubySMB
461
463
  array :old_credentials, type: :kerb_key_data_new, initial_length: :old_credential_count
462
464
  array :older_credentials, type: :kerb_key_data_new, initial_length: :older_credential_count
463
465
  string :default_salt, read_length: -> { credentials.map { |e| e.key_offset }.min - @obj.abs_offset }
464
- string :key_values, read_length: -> { credentials.map { |e| e.key_length }.sum }
466
+ string :key_values, read_length: -> { credentials.map { |e| e.key_length }.sum(&:to_i) }
465
467
 
466
468
  def get_key_values
467
469
  credentials.map do |credential|
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.2.2'.freeze
2
+ VERSION = '3.2.4'.freeze
3
3
  end
@@ -4146,3 +4146,201 @@ RSpec.describe 'Alignment' do
4146
4146
  end
4147
4147
  end
4148
4148
  end
4149
+
4150
+ RSpec.describe RubySMB::Dcerpc::Ndr::TypeSerialization1CommonTypeHeader do
4151
+ it 'is a BinData::Record class' do
4152
+ expect(described_class).to be < BinData::Record
4153
+ end
4154
+ it 'has :byte_align parameter set to the expected value' do
4155
+ expect(described_class.default_parameters[:byte_align]).to eq(8)
4156
+ end
4157
+
4158
+ subject { described_class.new }
4159
+
4160
+ it { is_expected.to respond_to :version }
4161
+ it { is_expected.to respond_to :endianness }
4162
+ it { is_expected.to respond_to :common_header_length }
4163
+ it { is_expected.to respond_to :filler }
4164
+
4165
+ context 'with #version' do
4166
+ it 'is a BinData::Uint8' do
4167
+ expect(subject.version).to be_a BinData::Uint8
4168
+ end
4169
+ it 'returns 1 by default' do
4170
+ expect(subject.version).to eq(1)
4171
+ end
4172
+ end
4173
+
4174
+ context 'with #endianness' do
4175
+ it 'is a BinData::Uint8' do
4176
+ expect(subject.endianness).to be_a BinData::Uint8
4177
+ end
4178
+ it 'returns 0x10 by default' do
4179
+ expect(subject.endianness).to eq(0x10)
4180
+ end
4181
+ end
4182
+
4183
+ context 'with #common_header_length' do
4184
+ it 'is a BinData::Uint16le' do
4185
+ expect(subject.common_header_length).to be_a BinData::Uint16le
4186
+ end
4187
+ it 'returns 8 by default' do
4188
+ expect(subject.common_header_length).to eq(8)
4189
+ end
4190
+ end
4191
+
4192
+ context 'with #filler' do
4193
+ it 'is a BinData::Uint32le' do
4194
+ expect(subject.filler).to be_a BinData::Uint32le
4195
+ end
4196
+ it 'returns 0xCCCCCCCC by default' do
4197
+ expect(subject.filler).to eq(0xCCCCCCCC)
4198
+ end
4199
+ end
4200
+
4201
+ it 'reads itself' do
4202
+ values = {version: 4, endianness: 0x33, common_header_length: 44, filler: 0xFFFFFFFF}
4203
+ struct_instance = described_class.new(values)
4204
+ expect(described_class.read(struct_instance.to_binary_s)).to eq(values)
4205
+ end
4206
+ end
4207
+
4208
+ RSpec.describe RubySMB::Dcerpc::Ndr::TypeSerialization1PrivateHeader do
4209
+ it 'is a BinData::Record class' do
4210
+ expect(described_class).to be < BinData::Record
4211
+ end
4212
+ it 'has :byte_align parameter set to the expected value' do
4213
+ expect(described_class.default_parameters[:byte_align]).to eq(8)
4214
+ end
4215
+
4216
+ subject { described_class.new }
4217
+
4218
+ it { is_expected.to respond_to :object_buffer_length }
4219
+ it { is_expected.to respond_to :filler }
4220
+
4221
+ context 'with #object_buffer_length' do
4222
+ it 'is a BinData::Uint32le' do
4223
+ expect(subject.object_buffer_length).to be_a BinData::Uint32le
4224
+ end
4225
+ it 'calls its parent\'s #field_length method to set its default value' do
4226
+ test_struct = Class.new(BinData::Record) do
4227
+ endian :little
4228
+ type_serialization1_private_header :header
4229
+
4230
+ def field_length(obj);end
4231
+ end.new
4232
+ expect(test_struct).to receive(:field_length).and_return(4)
4233
+ expect(test_struct.header.object_buffer_length).to eq(4)
4234
+ end
4235
+ it 'sets the default value to 0 when its parent doesn\'t implemet #field_length' do
4236
+ expect(subject.object_buffer_length).to eq(0)
4237
+ end
4238
+ end
4239
+
4240
+ context 'with #filler' do
4241
+ it 'is a BinData::Uint32le' do
4242
+ expect(subject.filler).to be_a BinData::Uint32le
4243
+ end
4244
+ it 'returns 0x00000000 by default' do
4245
+ expect(subject.filler).to eq(0x00000000)
4246
+ end
4247
+ end
4248
+
4249
+ it 'reads itself' do
4250
+ values = {object_buffer_length: 4, filler: 0xFFFFFFFF}
4251
+ struct_instance = described_class.new(values)
4252
+ expect(described_class.read(struct_instance.to_binary_s)).to eq(values)
4253
+ end
4254
+ end
4255
+
4256
+ RSpec.describe RubySMB::Dcerpc::Ndr::TypeSerialization1 do
4257
+ it 'is a BinData::Record class' do
4258
+ expect(described_class).to be < BinData::Record
4259
+ end
4260
+ it 'has :byte_align parameter set to the expected value' do
4261
+ expect(described_class.default_parameters[:byte_align]).to eq(8)
4262
+ end
4263
+
4264
+ subject { described_class.new }
4265
+
4266
+ it { is_expected.to respond_to :common_header }
4267
+
4268
+ context 'with #common_header' do
4269
+ it 'is a TypeSerialization1CommonTypeHeader structure' do
4270
+ expect(subject.common_header).to be_a RubySMB::Dcerpc::Ndr::TypeSerialization1CommonTypeHeader
4271
+ end
4272
+ end
4273
+
4274
+ it 'reads itself' do
4275
+ values = {
4276
+ common_header: {version: 4, endianness: 0x33, common_header_length: 44, filler: 0xFFFFFFFF}
4277
+ }
4278
+ struct_instance = described_class.new(values)
4279
+ expect(described_class.read(struct_instance.to_binary_s)).to eq(values)
4280
+ end
4281
+
4282
+ context 'when inherited' do
4283
+ let(:test_struct) do
4284
+ Class.new(RubySMB::Dcerpc::Ndr::NdrStruct) do
4285
+ default_parameters byte_align: 8
4286
+ endian :little
4287
+
4288
+ rpc_unicode_string :full_name
4289
+ ndr_uint32 :user_id
4290
+ end
4291
+ end
4292
+ before :example do
4293
+ BinData::RegisteredClasses.register('test_struct', test_struct)
4294
+ end
4295
+ after :example do
4296
+ BinData::RegisteredClasses.unregister('test_struct')
4297
+ end
4298
+
4299
+ subject do
4300
+ Class.new(described_class) do
4301
+ default_parameter byte_align: 8
4302
+ endian :little
4303
+
4304
+ test_struct :data1
4305
+ uint32 :value1, initial_value: 5
4306
+ uint32 :value2, initial_value: 6
4307
+ test_struct :data2
4308
+ uint32 :value3, initial_value: 7
4309
+ test_struct :data3
4310
+ end.new
4311
+ end
4312
+
4313
+ it { is_expected.to respond_to :common_header }
4314
+ it { is_expected.to respond_to :private_header1 }
4315
+ it { is_expected.to respond_to :data1 }
4316
+ it { is_expected.to respond_to :value1 }
4317
+ it { is_expected.to respond_to :value2 }
4318
+ it { is_expected.to respond_to :private_header2 }
4319
+ it { is_expected.to respond_to :data2 }
4320
+ it { is_expected.to respond_to :value3 }
4321
+ it { is_expected.to respond_to :private_header3 }
4322
+ it { is_expected.to respond_to :data3 }
4323
+
4324
+ it 'sets the expected default values' do
4325
+ data_obj = test_struct.new
4326
+ expect(subject.data1).to eq(data_obj)
4327
+ expect(subject.value1).to eq(5)
4328
+ expect(subject.value2).to eq(6)
4329
+ expect(subject.data2).to eq(data_obj)
4330
+ expect(subject.value3).to eq(7)
4331
+ expect(subject.data3).to eq(data_obj)
4332
+ end
4333
+
4334
+ it 'sets the correct private header\'s object_buffer_length field value' do
4335
+ data1 = test_struct.new(full_name: 'test string')
4336
+ subject.data1 = data1
4337
+ expect(subject.private_header1.object_buffer_length).to eq(data1.num_bytes)
4338
+ data2 = test_struct.new(full_name: 'another test string')
4339
+ subject.data2 = data2
4340
+ expect(subject.private_header2.object_buffer_length).to eq(data2.num_bytes)
4341
+ data3 = test_struct.new(full_name: 'more string!!!')
4342
+ subject.data3 = data3
4343
+ expect(subject.private_header3.object_buffer_length).to eq(data3.num_bytes)
4344
+ end
4345
+ end
4346
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -97,7 +97,7 @@ cert_chain:
97
97
  EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
98
98
  9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
99
99
  -----END CERTIFICATE-----
100
- date: 2023-01-18 00:00:00.000000000 Z
100
+ date: 2023-01-30 00:00:00.000000000 Z
101
101
  dependencies:
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: redcarpet
@@ -1001,7 +1001,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1001
1001
  - !ruby/object:Gem::Version
1002
1002
  version: '0'
1003
1003
  requirements: []
1004
- rubygems_version: 3.3.26
1004
+ rubygems_version: 3.1.4
1005
1005
  signing_key:
1006
1006
  specification_version: 4
1007
1007
  summary: A pure Ruby implementation of the SMB Protocol Family
metadata.gz.sig CHANGED
Binary file