ruby_smb 3.3.12 → 3.3.13
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/ruby_smb/dcerpc/request.rb +2 -0
- data/lib/ruby_smb/dcerpc/samr/samr_change_password_user_request.rb +31 -0
- data/lib/ruby_smb/dcerpc/samr/samr_change_password_user_response.rb +21 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_members_in_group_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response.rb +21 -0
- data/lib/ruby_smb/dcerpc/samr.rb +201 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/dcerpc/samr/encrypted_nt_owf_password_spec.rb +10 -0
- data/spec/lib/ruby_smb/dcerpc/samr/sampr_encrypted_user_password_spec.rb +9 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_request_spec.rb +28 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_response_spec.rb +16 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response_spec.rb +16 -0
- data.tar.gz.sig +0 -0
- metadata +18 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c74027d4436875845c9d219abd7cb3243d80acd61fbaeabb9c1256571354634
|
4
|
+
data.tar.gz: 8dbe5857343dbb8e1b163c29a7d3ef8d8e30aa06dc7527195772a058f4022321
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ed11e51a9babe4a7e478e4903dd4c201c8e714288ab49766e62ba3c01cf9b8358899276ecece683dbb586777739a016579e06a9dd9e6581e03a408a6a27cf5c
|
7
|
+
data.tar.gz: a7bf609a4b94040075adda0c17728ef306d780d28db06f47fa2d1c9b6729821309c3c5395c5bb8d22ad76fe693f7f7b21a2de9f9239211af64417ef35da16e37
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -79,6 +79,8 @@ module RubySMB
|
|
79
79
|
samr_set_information_user2_request Samr::SAMR_SET_INFORMATION_USER2
|
80
80
|
samr_delete_user_request Samr::SAMR_DELETE_USER
|
81
81
|
samr_query_information_domain_request Samr::SAMR_QUERY_INFORMATION_DOMAIN
|
82
|
+
samr_unicode_change_password_user2_request Samr::SAMR_UNICODE_CHANGE_PASSWORD_USER2
|
83
|
+
samr_change_password_user_request Samr::SAMR_CHANGE_PASSWORD_USER
|
82
84
|
string :default
|
83
85
|
end
|
84
86
|
choice 'Wkssvc', selection: -> { opnum } do
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Samr
|
4
|
+
|
5
|
+
# [3.1.5.10.1 SamrChangePasswordUser (Opnum 38)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9699d8ca-e1a4-433c-a8c3-d7bebeb01476)
|
6
|
+
class SamrChangePasswordUserRequest < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
sampr_handle :user_handle
|
12
|
+
ndr_uint8 :lm_present
|
13
|
+
pencrypted_nt_owf_password :old_lm_encrypted_with_new_lm
|
14
|
+
pencrypted_nt_owf_password :new_lm_encrypted_with_old_lm
|
15
|
+
ndr_uint8 :nt_present
|
16
|
+
pencrypted_nt_owf_password :old_nt_encrypted_with_new_nt
|
17
|
+
pencrypted_nt_owf_password :new_nt_encrypted_with_old_nt
|
18
|
+
ndr_uint8 :nt_cross_encryption_present
|
19
|
+
pencrypted_nt_owf_password :new_nt_encrypted_with_new_nt
|
20
|
+
ndr_uint8 :lm_cross_encryption_present
|
21
|
+
pencrypted_nt_owf_password :new_lm_encrypted_with_new_nt
|
22
|
+
|
23
|
+
def initialize_instance
|
24
|
+
super
|
25
|
+
@opnum = SAMR_CHANGE_PASSWORD_USER
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Samr
|
4
|
+
|
5
|
+
# [3.1.5.10.1 SamrChangePasswordUser (Opnum 38)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9699d8ca-e1a4-433c-a8c3-d7bebeb01476)
|
6
|
+
class SamrChangePasswordUserResponse < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
ndr_uint32 :error_status
|
12
|
+
|
13
|
+
def initialize_instance
|
14
|
+
super
|
15
|
+
@opnum = SAMR_CHANGE_PASSWORD_USER
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -14,7 +14,7 @@ module RubySMB
|
|
14
14
|
extend Ndr::PointerClassPlugin
|
15
15
|
end
|
16
16
|
|
17
|
-
# [
|
17
|
+
# [3.1.5.8.3 SamrGetMembersInGroup (Opnum 25)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/3ed5030d-88a3-42ca-a6e0-8c12aa2fdfbd)
|
18
18
|
class SamrGetMembersInGroupResponse < BinData::Record
|
19
19
|
attr_reader :opnum
|
20
20
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Samr
|
4
|
+
|
5
|
+
# [3.1.5.10.3 SamrUnicodeChangePasswordUser2 (Opnum 55)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/acb3204a-da8b-478e-9139-1ea589edb880)
|
6
|
+
class SamrUnicodeChangePasswordUser2Request < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
prpc_unicode_string :server_name
|
12
|
+
rpc_unicode_string :user_name
|
13
|
+
psampr_encrypted_user_password :new_password_encrypted_with_old_nt
|
14
|
+
pencrypted_nt_owf_password :old_nt_owf_password_encrypted_with_new_nt
|
15
|
+
ndr_uint8 :lm_present
|
16
|
+
psampr_encrypted_user_password :new_password_encrypted_with_old_lm
|
17
|
+
pencrypted_nt_owf_password :old_lm_owf_password_encrypted_with_new_nt
|
18
|
+
|
19
|
+
def initialize_instance
|
20
|
+
super
|
21
|
+
@opnum = SAMR_UNICODE_CHANGE_PASSWORD_USER2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Samr
|
4
|
+
|
5
|
+
# [3.1.5.10.3 SamrUnicodeChangePasswordUser2 (Opnum 55)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/acb3204a-da8b-478e-9139-1ea589edb880)
|
6
|
+
class SamrUnicodeChangePasswordUser2Response < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
ndr_uint32 :error_status
|
12
|
+
|
13
|
+
def initialize_instance
|
14
|
+
super
|
15
|
+
@opnum = SAMR_UNICODE_CHANGE_PASSWORD_USER2
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ruby_smb/dcerpc/samr.rb
CHANGED
@@ -24,8 +24,10 @@ module RubySMB
|
|
24
24
|
SAMR_GET_MEMBERS_IN_GROUP = 0x0019
|
25
25
|
SAMR_OPEN_USER = 0x0022
|
26
26
|
SAMR_DELETE_USER = 0x0023
|
27
|
+
SAMR_CHANGE_PASSWORD_USER = 0x0026
|
27
28
|
SAMR_GET_GROUPS_FOR_USER = 0x0027
|
28
29
|
SAMR_CREATE_USER2_IN_DOMAIN = 0x0032
|
30
|
+
SAMR_UNICODE_CHANGE_PASSWORD_USER2 = 0x0037
|
29
31
|
SAMR_SET_INFORMATION_USER2 = 0x003a
|
30
32
|
SAMR_CONNECT5 = 0x0040
|
31
33
|
SAMR_RID_TO_SID = 0x0041
|
@@ -318,6 +320,58 @@ module RubySMB
|
|
318
320
|
extend Ndr::PointerClassPlugin
|
319
321
|
end
|
320
322
|
|
323
|
+
# [2.2.7.3 ENCRYPTED_NT_OWF_PASSWORD](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/ce061fef-6d4f-4802-bd5d-26b11f14f4a6)
|
324
|
+
class EncryptedNtOwfPassword < Ndr::NdrStruct
|
325
|
+
default_parameter byte_align: 4
|
326
|
+
ndr_fixed_byte_array :buffer, initial_length: 16
|
327
|
+
|
328
|
+
# [2.2.11.1.2 Encrypting a 64-bit block with a 7-byte key](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/ebdb15df-8d0d-4347-9d62-082e6eccac40)
|
329
|
+
def self.to_output_key(input_key)
|
330
|
+
output_key = []
|
331
|
+
input_key = input_key.unpack('C'*7)
|
332
|
+
output_key.append(input_key[0] >> 0x01)
|
333
|
+
output_key.append(((input_key[0]&0x01)<<6) | (input_key[1]>>2))
|
334
|
+
output_key.append(((input_key[1]&0x03)<<5) | (input_key[2]>>3))
|
335
|
+
output_key.append(((input_key[2]&0x07)<<4) | (input_key[3]>>4))
|
336
|
+
output_key.append(((input_key[3]&0x0F)<<3) | (input_key[4]>>5))
|
337
|
+
output_key.append(((input_key[4]&0x1F)<<2) | (input_key[5]>>6))
|
338
|
+
output_key.append(((input_key[5]&0x3F)<<1) | (input_key[6]>>7))
|
339
|
+
output_key.append(input_key[6] & 0x7F)
|
340
|
+
|
341
|
+
output_key = output_key.map {|x| (x << 1) & 0xFE}
|
342
|
+
|
343
|
+
output_key.pack('C'*8)
|
344
|
+
end
|
345
|
+
|
346
|
+
# [2.2.11.1 DES-ECB-LM](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/3f5ec79d-b449-4ab2-9423-c4dccbe0b184)
|
347
|
+
def self.encrypt_hash(hash:, key:)
|
348
|
+
block1 = hash[0..7]
|
349
|
+
block2 = hash[8..]
|
350
|
+
key1 = to_output_key(key[0..6])
|
351
|
+
key2 = to_output_key(key[7..13]) # The last two bytes are ignored
|
352
|
+
|
353
|
+
cipher1 = OpenSSL::Cipher.new('des-ecb').tap do |cipher|
|
354
|
+
cipher.encrypt
|
355
|
+
cipher.key = key1
|
356
|
+
end
|
357
|
+
|
358
|
+
cipher2 = OpenSSL::Cipher.new('des-ecb').tap do |cipher|
|
359
|
+
cipher.encrypt
|
360
|
+
cipher.key = key2
|
361
|
+
end
|
362
|
+
|
363
|
+
cipher1.update(block1) + cipher2.update(block2)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
EncryptedLmOwfPassword = EncryptedNtOwfPassword
|
368
|
+
|
369
|
+
class PencryptedNtOwfPassword < EncryptedNtOwfPassword
|
370
|
+
extend Ndr::PointerClassPlugin
|
371
|
+
end
|
372
|
+
|
373
|
+
PencryptedLmOwfPassword = PencryptedNtOwfPassword
|
374
|
+
|
321
375
|
# [2.2.7.4 SAMPR_ULONG_ARRAY](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2feb3806-4db2-45b7-90d2-86c8336a31ba)
|
322
376
|
class SamprUlongArray < Ndr::NdrStruct
|
323
377
|
default_parameter byte_align: 4
|
@@ -333,6 +387,28 @@ module RubySMB
|
|
333
387
|
ndr_uint16_array_ptr :buffer
|
334
388
|
end
|
335
389
|
|
390
|
+
# [2.2.6.21 SAMPR_ENCRYPTED_USER_PASSWORD](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/23f9ef4c-cf3e-4330-9287-ea4799b03201)
|
391
|
+
class SamprEncryptedUserPassword < Ndr::NdrStruct
|
392
|
+
default_parameter byte_align: 4
|
393
|
+
ndr_fixed_byte_array :buffer, initial_length: 516
|
394
|
+
|
395
|
+
def self.encrypt_password(password, old_password_nt)
|
396
|
+
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/5fe3c4c4-e71b-440d-b2fd-8448bfaf6e04
|
397
|
+
password = password.encode('UTF-16LE').force_encoding('ASCII-8BIT')
|
398
|
+
buffer = password.rjust(512, "\x00") + [ password.length ].pack('V')
|
399
|
+
cipher = OpenSSL::Cipher.new('RC4').tap do |cipher|
|
400
|
+
cipher.encrypt
|
401
|
+
cipher.key = old_password_nt
|
402
|
+
end
|
403
|
+
cipher.update(buffer)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
class PsamprEncryptedUserPassword < SamprEncryptedUserPassword
|
408
|
+
extend Ndr::PointerClassPlugin
|
409
|
+
end
|
410
|
+
|
411
|
+
|
336
412
|
# [2.2.6.22 SAMPR_ENCRYPTED_USER_PASSWORD_NEW](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/112ecc94-1cbe-41cd-b669-377402c20786)
|
337
413
|
class SamprEncryptedUserPasswordNew < BinData::Record
|
338
414
|
ndr_fixed_byte_array :buffer, initial_length: 532
|
@@ -413,12 +489,22 @@ module RubySMB
|
|
413
489
|
ndr_uint32 :user_account_control
|
414
490
|
end
|
415
491
|
|
492
|
+
# [2.2.6.25 SAMPR_USER_INTERNAL1_INFORMATION](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/50d17755-c6b8-40bd-8cac-bd6cfa31adf2)
|
493
|
+
class SamprUserInternal1Information < BinData::Record
|
494
|
+
encrypted_nt_owf_password :encrypted_nt_owf_password
|
495
|
+
encrypted_nt_owf_password :encrypted_lm_owf_password
|
496
|
+
ndr_uint8 :nt_password_present
|
497
|
+
ndr_uint8 :lm_password_present
|
498
|
+
ndr_uint8 :password_expired
|
499
|
+
end
|
500
|
+
|
416
501
|
# [2.2.6.29 SAMPR_USER_INFO_BUFFER](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9496c26e-490b-4e76-827f-2695fc216f35)
|
417
502
|
class SamprUserInfoBuffer < BinData::Record
|
418
503
|
ndr_uint16 :tag
|
419
504
|
choice :member, selection: :tag do
|
420
505
|
user_control_information USER_CONTROL_INFORMATION
|
421
506
|
sampr_user_internal4_information_new USER_INTERNAL4_INFORMATION_NEW
|
507
|
+
sampr_user_internal1_information USER_INTERNAL1_INFORMATION
|
422
508
|
end
|
423
509
|
end
|
424
510
|
|
@@ -523,6 +609,10 @@ module RubySMB
|
|
523
609
|
require 'ruby_smb/dcerpc/samr/samr_get_groups_for_user_response'
|
524
610
|
require 'ruby_smb/dcerpc/samr/samr_set_information_user2_request'
|
525
611
|
require 'ruby_smb/dcerpc/samr/samr_set_information_user2_response'
|
612
|
+
require 'ruby_smb/dcerpc/samr/samr_change_password_user_request'
|
613
|
+
require 'ruby_smb/dcerpc/samr/samr_change_password_user_response'
|
614
|
+
require 'ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request'
|
615
|
+
require 'ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response'
|
526
616
|
require 'ruby_smb/dcerpc/samr/samr_delete_user_request'
|
527
617
|
require 'ruby_smb/dcerpc/samr/samr_delete_user_response'
|
528
618
|
require 'ruby_smb/dcerpc/samr/samr_query_information_domain_request'
|
@@ -882,6 +972,117 @@ module RubySMB
|
|
882
972
|
nil
|
883
973
|
end
|
884
974
|
|
975
|
+
# Change the password on a user object.
|
976
|
+
#
|
977
|
+
# @param user_handle [SamprHandle] Handle representing the user to change the password for
|
978
|
+
# @param old_password [String] The previous password (either this or old_nt_hash must be specified)
|
979
|
+
# @param new_password [String] The password to set on the account
|
980
|
+
# @param new_nt_hash [String] The new password's NT hash
|
981
|
+
# @param new_lm_hash [String] The new password's LM hash
|
982
|
+
# @param old_nt_hash [String] The previous password's NT hash (either this or old_password must be specified)
|
983
|
+
# @param old_lm_hash [String] The previous password's LM hash (currently ignored)
|
984
|
+
# @return nothing is returned on success
|
985
|
+
# @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
|
986
|
+
# is not STATUS_SUCCESS
|
987
|
+
def samr_change_password_user(user_handle:, old_password:nil, new_password:nil, new_nt_hash:nil, new_lm_hash:nil, old_nt_hash:nil, old_lm_hash:nil)
|
988
|
+
if new_password.nil? == new_nt_hash.nil?
|
989
|
+
raise ArgumentError.new('Provide either new password or new password hashes, but not both')
|
990
|
+
end
|
991
|
+
|
992
|
+
if old_password.nil? == old_nt_hash.nil?
|
993
|
+
raise ArgumentError.new('Provide either old password or old password hashes, but not both')
|
994
|
+
end
|
995
|
+
|
996
|
+
if old_password
|
997
|
+
old_lm_hash = Net::NTLM.lm_hash(old_password[0..13])
|
998
|
+
old_nt_hash = Net::NTLM.ntlm_hash(old_password)
|
999
|
+
end
|
1000
|
+
|
1001
|
+
if new_nt_hash.nil?
|
1002
|
+
new_nt_hash = Net::NTLM::ntlm_hash(new_password)
|
1003
|
+
new_lm_hash = Net::NTLM.lm_hash(new_password[0..13])
|
1004
|
+
elsif new_lm_hash.nil?
|
1005
|
+
new_lm_hash = Net::NTLM.lm_hash('')
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
samr_change_password_user_request = SamrChangePasswordUserRequest.new(
|
1009
|
+
user_handle: user_handle,
|
1010
|
+
lm_present: 0,
|
1011
|
+
old_lm_encrypted_with_new_lm: nil,
|
1012
|
+
new_lm_encrypted_with_old_lm: nil,
|
1013
|
+
nt_present: 1,
|
1014
|
+
old_nt_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: old_nt_hash, key: new_nt_hash)),
|
1015
|
+
new_nt_encrypted_with_old_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: new_nt_hash, key: old_nt_hash)),
|
1016
|
+
nt_cross_encryption_present: 0,
|
1017
|
+
new_nt_encrypted_with_new_lm: nil,
|
1018
|
+
lm_cross_encryption_present: 1,
|
1019
|
+
new_lm_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: new_lm_hash, key: new_nt_hash)),
|
1020
|
+
)
|
1021
|
+
response = dcerpc_request(samr_change_password_user_request)
|
1022
|
+
begin
|
1023
|
+
samr_unicode_change_password_user2_response = SamrChangePasswordUserResponse.read(response)
|
1024
|
+
rescue IOError
|
1025
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrUnicodeChangePasswordUser2Response'
|
1026
|
+
end
|
1027
|
+
unless samr_unicode_change_password_user2_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
|
1028
|
+
raise RubySMB::Dcerpc::Error::SamrError,
|
1029
|
+
"Error returned while changing user password: "\
|
1030
|
+
"#{WindowsError::NTStatus.find_by_retval(samr_unicode_change_password_user2_response.error_status.value).join(',')}"
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
nil
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
|
1037
|
+
# Change the password on a user.
|
1038
|
+
#
|
1039
|
+
# @param server_name [String] The server name; can be ignored by the server
|
1040
|
+
# @param target_username [String] The user for which we're changing the password
|
1041
|
+
# @param old_password [String] The previous password (either this or old_nt_hash must be specified)
|
1042
|
+
# @param new_password [String] The password to set on the account
|
1043
|
+
# @param old_nt_hash [String] The previous password's NT hash (either this or old_password must be specified)
|
1044
|
+
# @param old_lm_hash [String] The previous password's LM hash (currently ignored)
|
1045
|
+
# @return nothing is returned on success
|
1046
|
+
# @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
|
1047
|
+
# is not STATUS_SUCCESS
|
1048
|
+
def samr_unicode_change_password_user2(server_name: "", target_username:, old_password:nil, new_password:, old_nt_hash:nil, old_lm_hash:nil)
|
1049
|
+
#if old_lm_hash.nil? != old_nt_hash.nil?
|
1050
|
+
# raise ArgumentError.new('If providing the previous NT/LM hash, must provide both')
|
1051
|
+
#end
|
1052
|
+
if old_password.nil? == old_nt_hash.nil?
|
1053
|
+
raise ArgumentError.new('Provide either old password or old password hashes, but not both')
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
if old_password
|
1057
|
+
old_lm_hash = Net::NTLM.lm_hash(old_password[0..13])
|
1058
|
+
old_nt_hash = Net::NTLM.ntlm_hash(old_password)
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
new_nt_hash = Net::NTLM::ntlm_hash(new_password)
|
1062
|
+
|
1063
|
+
samr_unicode_change_password_user2_request = SamrUnicodeChangePasswordUser2Request.new(
|
1064
|
+
server_name: server_name,
|
1065
|
+
user_name: target_username,
|
1066
|
+
new_password_encrypted_with_old_nt: SamprEncryptedUserPassword.new(buffer: SamprEncryptedUserPassword.encrypt_password(new_password, old_nt_hash)),
|
1067
|
+
old_nt_owf_password_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: old_nt_hash, key: new_nt_hash)),
|
1068
|
+
lm_present: 0
|
1069
|
+
)
|
1070
|
+
samr_unicode_change_password_user2_request
|
1071
|
+
response = dcerpc_request(samr_unicode_change_password_user2_request)
|
1072
|
+
begin
|
1073
|
+
samr_unicode_change_password_user2_response = SamrUnicodeChangePasswordUser2Response.read(response)
|
1074
|
+
rescue IOError
|
1075
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrUnicodeChangePasswordUser2Response'
|
1076
|
+
end
|
1077
|
+
unless samr_unicode_change_password_user2_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
|
1078
|
+
raise RubySMB::Dcerpc::Error::SamrError,
|
1079
|
+
"Error returned while changing user password: "\
|
1080
|
+
"#{WindowsError::NTStatus.find_by_retval(samr_unicode_change_password_user2_response.error_status.value).join(',')}"
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
nil
|
1084
|
+
end
|
1085
|
+
|
885
1086
|
# Closes (that is, releases server-side resources used by) any context
|
886
1087
|
# handle obtained from this RPC interface
|
887
1088
|
#
|
data/lib/ruby_smb/version.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::EncryptedNtOwfPassword do
|
2
|
+
it 'Creates output key' do
|
3
|
+
expect(described_class.to_output_key('ABCDEFG')).to eq ["40a09068442A188E"].pack('H*')
|
4
|
+
expect(described_class.to_output_key('AAAAAAA')).to eq ["40A05028140A0482"].pack('H*')
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'Encrypts a hash' do
|
8
|
+
expect(described_class.encrypt_hash(hash: 'AAAAAAAAAAAAAAAA', key: 'BBBBBBBBBBBBBB')).to eq ["8cd90c3de08ecda28cd90c3de08ecda2"].pack('H*')
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::SamprEncryptedUserPassword do
|
2
|
+
|
3
|
+
it 'Encrypts correctly' do
|
4
|
+
password = 'newPassword1!'
|
5
|
+
old_password_nt = 'AAAAAAAAAAAAAAAA'
|
6
|
+
expected = ['c2cbe63dc0a3cda1baab695ce4f0352b774592b214a905796a6ba9fd30e0ffc56d60812bfd7f45420f5332922b50cfdcde3133e3e45c5eb6c16023006cb4ff7d41f54fa009a64fa66b00fa41094d7db6c4cc9a430a7ad43122047b696d934645974fee7551dcafac28c0869106417fd3fbfc34a87a56d6141aac2b6d134723f2224791b39749bc93f4405f78ba09dcd9b4d29e72ae0c873a8d468323793fffccc2a9d8dc4d975c42064208d898df71ef0889b2e5a9cfa6c8c2758eb15b6fdd332d6d7d2829f3a3bc2a7ecd7f87d1fd4aed25d93de6a7baf8e0247e2f5b831ca7646eef7a11e2f9410574707ef85c9db8cc125fb6254fe1e111a662006343299fcb8f8fb641cb1d188ff6e5c50334ca199603a93907093e6d35d80b2dade79360bc672870d29cdf5f80120ac53e9ce3c3718d0f8097cdae2318b8e27108fc1066491e5b034f55c1e8ff00a53d2eb7b0e0ffc10236a5a530795b84f33d66eb51388d6da112886c8ea482af0ec7e9c0a549a561244ee9185b5387b05d3c5e74d88e355aef22dab1d5039d0a0caa22437f6e520121ef5d21da729bb0cdee5cbb3b450bf1d0fcafad5ac518b0535628e2a96a2d0d2f8acd3e42147e700c2889cbc92c5533f1889b49d41c0ae9a05fc0a754060c0680296de5c712a3299cdd5c646582348fc2e32a68ae4fc2a3b91fb423adc617a20b28c1d6297f14a870329e6aa802d22ba97c'].pack('H*')
|
7
|
+
expect(described_class.encrypt_password(password, old_password_nt)).to eq expected
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::SamrChangePasswordUserRequest do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
describe '#initialize_instance' do
|
5
|
+
it 'sets #opnum to SAMR_CHANGE_PASSWORD_USER constant' do
|
6
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::Samr::SAMR_CHANGE_PASSWORD_USER)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'reads itself' do
|
11
|
+
uuid = RubySMB::Dcerpc::Uuid.new
|
12
|
+
uuid.set(SecureRandom.uuid)
|
13
|
+
new_packet = described_class.new({
|
14
|
+
user_handle: RubySMB::Dcerpc::Samr::SamprHandle.new(context_handle_attributes: 42, :context_handle_uuid => uuid),
|
15
|
+
lm_present: 1,
|
16
|
+
old_lm_encrypted_with_new_lm: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
17
|
+
new_lm_encrypted_with_old_lm: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
18
|
+
nt_present: 1,
|
19
|
+
old_nt_encrypted_with_new_nt: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
20
|
+
new_nt_encrypted_with_old_nt: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
21
|
+
nt_cross_encryption_present: 1,
|
22
|
+
new_nt_encrypted_with_new_nt: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
23
|
+
lm_cross_encryption_present: 1,
|
24
|
+
new_lm_encrypted_with_new_nt: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16))
|
25
|
+
})
|
26
|
+
expect(packet.read(new_packet.to_binary_s)).to eq(new_packet)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::SamrChangePasswordUserResponse do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
describe '#initialize_instance' do
|
5
|
+
it 'sets #opnum to SAMR_CHANGE_PASSWORD_USER constant' do
|
6
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::Samr::SAMR_CHANGE_PASSWORD_USER)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'reads itself' do
|
11
|
+
new_packet = described_class.new({
|
12
|
+
error_status: 4
|
13
|
+
})
|
14
|
+
expect(packet.read(new_packet.to_binary_s)).to eq(new_packet)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::SamrUnicodeChangePasswordUser2Request do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
describe '#initialize_instance' do
|
5
|
+
it 'sets #opnum to SAMR_UNICODE_CHANGE_PASSWORD_USER2 constant' do
|
6
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::Samr::SAMR_UNICODE_CHANGE_PASSWORD_USER2)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'reads itself' do
|
11
|
+
new_packet = described_class.new({
|
12
|
+
server_name: 'my-server',
|
13
|
+
user_name: 'user.person',
|
14
|
+
new_password_encrypted_with_old_nt: RubySMB::Dcerpc::Samr::PsamprEncryptedUserPassword.new(buffer: SecureRandom::bytes(516)),
|
15
|
+
pencrypted_nt_owf_password: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
16
|
+
lm_present: 1,
|
17
|
+
new_password_encrypted_with_old_lm: RubySMB::Dcerpc::Samr::PsamprEncryptedUserPassword.new(buffer: SecureRandom::bytes(516)),
|
18
|
+
old_lm_owf_password_encrypted_with_new_nt: RubySMB::Dcerpc::Samr::PencryptedNtOwfPassword.new(buffer: SecureRandom::bytes(16)),
|
19
|
+
})
|
20
|
+
expect(packet.read(new_packet.to_binary_s)).to eq(new_packet)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Samr::SamrUnicodeChangePasswordUser2Response do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
describe '#initialize_instance' do
|
5
|
+
it 'sets #opnum to SAMR_UNICODE_CHANGE_PASSWORD_USER2 constant' do
|
6
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::Samr::SAMR_UNICODE_CHANGE_PASSWORD_USER2)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'reads itself' do
|
11
|
+
new_packet = described_class.new({
|
12
|
+
error_status: 4
|
13
|
+
})
|
14
|
+
expect(packet.read(new_packet.to_binary_s)).to eq(new_packet)
|
15
|
+
end
|
16
|
+
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.3.
|
4
|
+
version: 3.3.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Metasploit Hackers
|
@@ -39,7 +39,7 @@ cert_chain:
|
|
39
39
|
DgscAao7wB3xW2BWEp1KnaDWkf1x9ttgoBEYyuYwU7uatB67kBQG1PKvLt79wHvz
|
40
40
|
Dxs+KOjGbBRfMnPgVGYkORKVrZIwlaboHbDKxcVW5xv+oZc7KYXWGg==
|
41
41
|
-----END CERTIFICATE-----
|
42
|
-
date: 2024-
|
42
|
+
date: 2024-12-06 00:00:00.000000000 Z
|
43
43
|
dependencies:
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: redcarpet
|
@@ -328,6 +328,8 @@ files:
|
|
328
328
|
- lib/ruby_smb/dcerpc/samr.rb
|
329
329
|
- lib/ruby_smb/dcerpc/samr/rpc_sid.rb
|
330
330
|
- lib/ruby_smb/dcerpc/samr/sampr_domain_info_buffer.rb
|
331
|
+
- lib/ruby_smb/dcerpc/samr/samr_change_password_user_request.rb
|
332
|
+
- lib/ruby_smb/dcerpc/samr/samr_change_password_user_response.rb
|
331
333
|
- lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb
|
332
334
|
- lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb
|
333
335
|
- lib/ruby_smb/dcerpc/samr/samr_connect_request.rb
|
@@ -362,6 +364,8 @@ files:
|
|
362
364
|
- lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb
|
363
365
|
- lib/ruby_smb/dcerpc/samr/samr_set_information_user2_request.rb
|
364
366
|
- lib/ruby_smb/dcerpc/samr/samr_set_information_user2_response.rb
|
367
|
+
- lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request.rb
|
368
|
+
- lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response.rb
|
365
369
|
- lib/ruby_smb/dcerpc/sec_trailer.rb
|
366
370
|
- lib/ruby_smb/dcerpc/srvsvc.rb
|
367
371
|
- lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb
|
@@ -713,7 +717,11 @@ files:
|
|
713
717
|
- spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb
|
714
718
|
- spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb
|
715
719
|
- spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb
|
720
|
+
- spec/lib/ruby_smb/dcerpc/samr/encrypted_nt_owf_password_spec.rb
|
716
721
|
- spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb
|
722
|
+
- spec/lib/ruby_smb/dcerpc/samr/sampr_encrypted_user_password_spec.rb
|
723
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_request_spec.rb
|
724
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_response_spec.rb
|
717
725
|
- spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb
|
718
726
|
- spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb
|
719
727
|
- spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb
|
@@ -736,6 +744,8 @@ files:
|
|
736
744
|
- spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb
|
737
745
|
- spec/lib/ruby_smb/dcerpc/samr/samr_set_information_user2_request_spec.rb
|
738
746
|
- spec/lib/ruby_smb/dcerpc/samr/samr_set_information_user2_response_spec.rb
|
747
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request_spec.rb
|
748
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response_spec.rb
|
739
749
|
- spec/lib/ruby_smb/dcerpc/samr_spec.rb
|
740
750
|
- spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb
|
741
751
|
- spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb
|
@@ -1057,7 +1067,11 @@ test_files:
|
|
1057
1067
|
- spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb
|
1058
1068
|
- spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb
|
1059
1069
|
- spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb
|
1070
|
+
- spec/lib/ruby_smb/dcerpc/samr/encrypted_nt_owf_password_spec.rb
|
1060
1071
|
- spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb
|
1072
|
+
- spec/lib/ruby_smb/dcerpc/samr/sampr_encrypted_user_password_spec.rb
|
1073
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_request_spec.rb
|
1074
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_change_password_user_response_spec.rb
|
1061
1075
|
- spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb
|
1062
1076
|
- spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb
|
1063
1077
|
- spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb
|
@@ -1080,6 +1094,8 @@ test_files:
|
|
1080
1094
|
- spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb
|
1081
1095
|
- spec/lib/ruby_smb/dcerpc/samr/samr_set_information_user2_request_spec.rb
|
1082
1096
|
- spec/lib/ruby_smb/dcerpc/samr/samr_set_information_user2_response_spec.rb
|
1097
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request_spec.rb
|
1098
|
+
- spec/lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response_spec.rb
|
1083
1099
|
- spec/lib/ruby_smb/dcerpc/samr_spec.rb
|
1084
1100
|
- spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb
|
1085
1101
|
- spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb
|
metadata.gz.sig
CHANGED
Binary file
|