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