ruby_smb 3.3.8 → 3.3.10

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: 25bedacb57d3950d1ee6f3bbf731007c4e1f0bd2b8e3f38582679a5cd867793f
4
- data.tar.gz: 1369c85136ad8336371ee55c1f8d90f0e85001b2c0d9e01e46b87e9b382ded16
3
+ metadata.gz: 07f6abd7129c406c8b1c008c686eef226b8fa385fa06be6eec900b95b4f97a32
4
+ data.tar.gz: 4ddc7ee9c516a1649faa15ad4316e36149aa4304c4dc176dfd5234f46f9218be
5
5
  SHA512:
6
- metadata.gz: 66d3566b68b64d0dc2ff8f58b373d8b6026b4980fcccb4b24c6263f59376373dadbc0b52c531ba5c212b255937d34dd281ce827eec111d0e7ef0b1a6dd5973f1
7
- data.tar.gz: 8cee7210c06f8e603342b69706c2779f3e9fef2d46146505154b00bc91d6cc7dbad37735e5e6ae4ac6fac256b0ba6eaf3dda15185c161e992a12bab3b3a91bb1
6
+ metadata.gz: e948d03583b517435a912b4ea07086ee0bff1fc07c0f65f0ea89e51ec10ee4ab2074d33a82c4f774656909c938331a7080fb521e5e65989bb301e10cd80d1bf5
7
+ data.tar.gz: 2f964acae7e74b25cb49e3d47ea125d4f4669f3f8868b9e895bb2f63be9e465e3fc1021e6695a1b837616a0f92419708ff4af6cb894b630d0b6292c95e3b4599
checksums.yaml.gz.sig CHANGED
@@ -1,3 +1,2 @@
1
- vn9x �=4�"s�C���[+Z)m{��G�nv���M58Ӽ���E$�NF��#2�Ζ���&�~�*�3=��Ԣ�.{j�%η0(NI ��;�������oSx�=��#Egl�􏒅 bDۺ�u�\9��Ë OTH;Ua��Z���)N"[t.�!t�?�'���#[�mo��!����jK�����vN����K�lj�m��C�;�)ɼ~�S�
2
- �)Co8���D:�v"�f~�����+|��W�tȔF�1�g�s�l�4��&N��S�4�߿.P%"L�⠺���
3
- ގ�?�jU"#8<�.��N����orp΄�s�Su��+�-I_>�3�j9*!� �Ґ��^�o�C&���ȇ1q�t� �6
1
+ g;j̢����2Dy�o��@}A�!��Y�,Y��RJ��㮿�W�;6)�/�t��z}���$L"9�I&�V@�#8��5<�-6�b����"�ڟ��X&��,vATܰt�[��x'\?�1�� ��k�%��c��'(3���u�l𥧥������P��P�K�����(��uJ�U዗�'>xt��cVD �v�$��R��l�3��X��2�=@�5GOT8�{U�;�P����9ܨoZɀ��"��>5�ӫ.������:垍?ί\�(x��Aj*�ۣ�1�a�H7�!Q��% �Ǘ����.�:[��4V�Tu�%p�6‰:��{�Kc�?x� Z�II{��
2
+ ��Z���^w�VMo�����
@@ -0,0 +1,28 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ module RubySMB
4
+ module Dcerpc
5
+ module Netlogon
6
+
7
+ # [2.2.1.2.1 DOMAIN_CONTROLLER_INFOW](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/9b85a7a4-8d34-4b9e-9500-bf8644ebfc06)
8
+ class DomainControllerInfoW < Ndr::NdrStruct
9
+ default_parameters byte_align: 4
10
+ endian :little
11
+
12
+ ndr_wide_stringz_ptr :domain_controller_name
13
+ ndr_wide_stringz_ptr :domain_controller_address
14
+ ndr_uint32 :domain_controller_address_type
15
+ uuid :domain_guid
16
+ ndr_wide_stringz_ptr :domain_name
17
+ ndr_wide_stringz_ptr :dns_forest_name
18
+ ndr_uint32 :flags
19
+ ndr_wide_stringz_ptr :dc_site_name
20
+ ndr_wide_stringz_ptr :client_site_name
21
+ end
22
+
23
+ class DomainControllerInfoWPtr < DomainControllerInfoW
24
+ extend Ndr::PointerClassPlugin
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ module RubySMB
4
+ module Dcerpc
5
+ module Netlogon
6
+
7
+ # [3.5.4.3.1 DsrGetDcNameEx2 (Opnum 34)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/fb8e1146-a045-4c31-98d1-c68507ad5620)
8
+ class DsrGetDcNameEx2Request < BinData::Record
9
+ attr_reader :opnum
10
+
11
+ endian :little
12
+
13
+ logonsrv_handle :computer_name
14
+ ndr_wide_stringz_ptr :account_name
15
+ ndr_uint32 :allowable_account_control_bits
16
+ ndr_wide_stringz_ptr :domain_name
17
+ uuid_ptr :domain_guid
18
+ ndr_wide_stringz_ptr :site_name
19
+ ndr_uint32 :flags
20
+
21
+ def initialize_instance
22
+ super
23
+ @opnum = DSR_GET_DC_NAME_EX2
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+ require 'ruby_smb/dcerpc/netlogon/domain_controller_infow'
3
+
4
+ module RubySMB
5
+ module Dcerpc
6
+ module Netlogon
7
+
8
+ # [3.5.4.3.1 DsrGetDcNameEx2 (Opnum 34)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/fb8e1146-a045-4c31-98d1-c68507ad5620)
9
+ class DsrGetDcNameEx2Response < BinData::Record
10
+ attr_reader :opnum
11
+
12
+ endian :little
13
+
14
+ domain_controller_info_w_ptr :domain_controller_info
15
+ ndr_uint32 :error_status
16
+
17
+ def initialize_instance
18
+ super
19
+ @opnum = DSR_GET_DC_NAME_EX2
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -11,6 +11,7 @@ module RubySMB
11
11
  NETR_SERVER_REQ_CHALLENGE = 4
12
12
  NETR_SERVER_AUTHENTICATE3 = 26
13
13
  NETR_SERVER_PASSWORD_SET2 = 30
14
+ DSR_GET_DC_NAME_EX2 = 34
14
15
 
15
16
  # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/3b224201-b531-43e2-8c79-b61f6dea8640
16
17
  class LogonsrvHandle < Ndr::NdrWideStringzPtr; end
@@ -65,6 +66,8 @@ module RubySMB
65
66
  require 'ruby_smb/dcerpc/netlogon/netr_server_password_set2_response'
66
67
  require 'ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request'
67
68
  require 'ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response'
69
+ require 'ruby_smb/dcerpc/netlogon/dsr_get_dc_name_ex2_request'
70
+ require 'ruby_smb/dcerpc/netlogon/dsr_get_dc_name_ex2_response'
68
71
 
69
72
  # Calculate the netlogon session key from the provided shared secret and
70
73
  # challenges. The shared secret is an NTLM hash.
@@ -80,7 +80,8 @@ module RubySMB
80
80
  string :default
81
81
  end
82
82
  choice 'Wkssvc', selection: -> { opnum } do
83
- netr_wksta_get_info_request Wkssvc::NETR_WKSTA_GET_INFO
83
+ netr_wksta_get_info_request Wkssvc::NETR_WKSTA_GET_INFO
84
+ netr_wksta_user_enum_request Wkssvc::NETR_WKSTA_USER_ENUM
84
85
  string :default
85
86
  end
86
87
  choice 'Epm', selection: -> { opnum } do
@@ -2,9 +2,6 @@ module RubySMB
2
2
  module Dcerpc
3
3
  module Wkssvc
4
4
 
5
- # [2.2.2.1 WKSSVC_IDENTIFY_HANDLE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/9ef94a11-0e5c-49d7-9ac7-68d6f03565de)
6
- class WkssvcIdentifyHandle < Ndr::NdrWideStringPtr; end
7
-
8
5
  # [3.2.4.1 NetrWkstaGetInfo (Opnum 0)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/4af41d6f-b800-4de1-af5b-0b15a85f8e04)
9
6
  class NetrWkstaGetInfoRequest < BinData::Record
10
7
  attr_reader :opnum
@@ -0,0 +1,25 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Wkssvc
4
+
5
+ # [3.2.4.3 NetrWkstaUserEnum (Opnum 2)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/4af41d6f-b800-4de1-af5b-0b15a85f8e04)
6
+ class NetrWkstaUserEnumRequest < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ wkssvc_identify_handle :server_name
12
+ wksta_user_enum_structure :user_info
13
+ ndr_uint32 :preferred_max_length, initial_value: 0xFFFFFFFF
14
+ ndr_uint32_ptr :result_handle, initial_value: 0
15
+
16
+ def initialize_instance
17
+ super
18
+ @opnum = NETR_WKSTA_USER_ENUM
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,25 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Wkssvc
4
+
5
+ # [3.2.4.3 NetrWkstaUserEnum (Opnum 2)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/4af41d6f-b800-4de1-af5b-0b15a85f8e04)
6
+ class NetrWkstaUserEnumResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ wksta_user_enum_structure :user_info
12
+ ndr_uint32_ptr :total_entries
13
+ ndr_uint32_ptr :result_handle
14
+ ndr_uint32 :error_status
15
+
16
+ def initialize_instance
17
+ super
18
+ @opnum = NETR_WKSTA_USER_ENUM
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
@@ -7,7 +7,8 @@ module RubySMB
7
7
  VER_MINOR = 0
8
8
 
9
9
  # Operation numbers
10
- NETR_WKSTA_GET_INFO = 0x0000
10
+ NETR_WKSTA_GET_INFO = 0x0000
11
+ NETR_WKSTA_USER_ENUM = 0x0002
11
12
 
12
13
  PLATFORM_ID = {
13
14
  0x0000012C => "DOS",
@@ -23,9 +24,85 @@ module RubySMB
23
24
  WKSTA_INFO_102 = 0x00000066
24
25
  #TODO: WKSTA_INFO_502 = 0x000001F6
25
26
 
27
+ # User Enum Information Level
28
+ WKSTA_USER_INFO_0 = 0x00000000
29
+ WKSTA_USER_INFO_1 = 0x00000001
30
+
31
+ # [2.2.2.1 WKSSVC_IDENTIFY_HANDLE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/9ef94a11-0e5c-49d7-9ac7-68d6f03565de)
32
+ class WkssvcIdentifyHandle < Ndr::NdrWideStringzPtr; end
33
+
34
+ # [2.2.5.9 WKSTA_USER_INFO_0](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/b7c53c6f-8b92-4e5d-9a2e-6462cb4ef1ac)
35
+ class WkstaUserInfo0 < Ndr::NdrStruct
36
+ default_parameter byte_align: 4
37
+ endian :little
38
+
39
+ ndr_wide_stringz_ptr :wkui0_username
40
+ end
41
+
42
+ class WkstaUserInfo0ArrayPtr < Ndr::NdrConfArray
43
+ default_parameter type: :wksta_user_info0
44
+ extend Ndr::PointerClassPlugin
45
+ end
46
+
47
+ # [2.2.5.12 WKSTA_USER_INFO_0_CONTAINER](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/0b0cff8f-09bc-43a8-b0d3-88f0bf7e3664)
48
+ class WkstaUserInfo0Container < Ndr::NdrStruct
49
+ default_parameter byte_align: 4
50
+ endian :little
51
+
52
+ ndr_uint32 :wkui0_entries_read
53
+ wksta_user_info0_array_ptr :wkui0_buffer
54
+ end
55
+
56
+ class PwkstaUserInfo0Container < WkstaUserInfo0Container
57
+ extend Ndr::PointerClassPlugin
58
+ end
59
+
60
+ # [2.2.5.10 WKSTA_USER_INFO_1](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/c37b9606-866f-40ac-9490-57b8334968e2)
61
+ class WkstaUserInfo1 < Ndr::NdrStruct
62
+ default_parameter byte_align: 4
63
+ endian :little
64
+
65
+ ndr_wide_stringz_ptr :wkui1_username
66
+ ndr_wide_stringz_ptr :wkui1_logon_domain
67
+ ndr_wide_stringz_ptr :wkui1_oth_domains
68
+ ndr_wide_stringz_ptr :wkui1_logon_server
69
+ end
70
+
71
+ class WkstaUserInfo1ArrayPtr < Ndr::NdrConfArray
72
+ default_parameter type: :wksta_user_info1
73
+ extend Ndr::PointerClassPlugin
74
+ end
75
+
76
+ # [2.2.5.13 WKSTA_USER_INFO_1_CONTAINER](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/22a813e4-fc7d-4fe3-a6d6-78debfd2c0c9)
77
+ class WkstaUserInfo1Container < Ndr::NdrStruct
78
+ default_parameter byte_align: 4
79
+ endian :little
80
+
81
+ ndr_uint32 :wkui1_entries_read
82
+ wksta_user_info1_array_ptr :wkui1_buffer
83
+ end
84
+
85
+ class PwkstaUserInfo1Container < WkstaUserInfo1Container
86
+ extend Ndr::PointerClassPlugin
87
+ end
88
+
89
+ # [2.2.5.14 WKSTA_USER_ENUM_STRUCT](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/4041455a-52be-4389-a4fc-82fea3cb3160)
90
+ class WkstaUserEnumStructure < Ndr::NdrStruct
91
+ default_parameter byte_align: 4
92
+ endian :little
93
+
94
+ ndr_uint32 :level
95
+ ndr_uint32 :tag, value: -> { self.level }
96
+ choice :info, selection: :level, byte_align: 4 do
97
+ pwksta_user_info0_container WKSTA_USER_INFO_0
98
+ pwksta_user_info1_container WKSTA_USER_INFO_1
99
+ end
100
+ end
26
101
 
27
102
  require 'ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request'
28
103
  require 'ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response'
104
+ require 'ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_request'
105
+ require 'ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_response'
29
106
 
30
107
  # Returns details about a computer environment, including
31
108
  # platform-specific information, the names of the domain and local
@@ -33,14 +110,14 @@ module RubySMB
33
110
  #
34
111
  # @param server_name [optional, String] String that identifies the server (optional
35
112
  # since it is ignored by the server)
36
- # @param server_name [optional, Integer] The information level of the data (default: WKSTA_INFO_100)
113
+ # @param level [optional, Integer] The information level of the data (default: WKSTA_INFO_100)
37
114
  # @return [RubySMB::Dcerpc::Wkssvc::WkstaInfo100, RubySMB::Dcerpc::Wkssvc::WkstaInfo101,
38
115
  # RubySMB::Dcerpc::Wkssvc::WkstaInfo102] The structure containing the requested information
39
116
  # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
40
117
  # NetrWkstaGetInfoResponse packet
41
118
  # @raise [RubySMB::Dcerpc::Error::WkssvcError] if the response error status
42
119
  # is not STATUS_SUCCESS
43
- def netr_wksta_get_info(server_name: "\x00", level: WKSTA_INFO_100)
120
+ def netr_wksta_get_info(server_name: '', level: WKSTA_INFO_100)
44
121
  wkst_netr_wksta_get_info_request = NetrWkstaGetInfoRequest.new(
45
122
  server_name: server_name,
46
123
  level: level
@@ -59,6 +136,44 @@ module RubySMB
59
136
  wkst_netr_wksta_get_info_response.wksta_info.info
60
137
  end
61
138
 
139
+ # Returns details about users who are currently active on a remote computer.
140
+ #
141
+ # @param server_name [optional, String] String that identifies the server (optional
142
+ # since it is ignored by the server)
143
+ # @param level [optional, Integer] The information level of the data (default: WKSTA_USER_INFO_0)
144
+ # @return [RubySMB::Dcerpc::Wkssvc::WkstaUserInfo0, RubySMB::Dcerpc::Wkssvc::WkstaUserInfo1]
145
+ # The structure containing the requested information
146
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
147
+ # NetrWkstaGetInfoResponse packet
148
+ # @raise [RubySMB::Dcerpc::Error::WkssvcError] if the response error status
149
+ # is not STATUS_SUCCESS
150
+ def netr_wksta_user_enum(server_name: '', level: WKSTA_USER_INFO_0)
151
+ wkst_netr_wksta_enum_user_request = NetrWkstaUserEnumRequest.new(
152
+ server_name: server_name,
153
+ user_info: {
154
+ level: level,
155
+ tag: level,
156
+ info: {
157
+ wkui0_entries_read: 0,
158
+ },
159
+ },
160
+ preferred_max_length: 0xFFFFFFFF,
161
+ result_handle: 0
162
+ )
163
+ response = dcerpc_request(wkst_netr_wksta_enum_user_request)
164
+ begin
165
+ wkst_netr_wksta_enum_user_response = NetrWkstaUserEnumResponse.read(response)
166
+ rescue IOError
167
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading WkstNetrWkstaUserEnumResponse'
168
+ end
169
+ unless wkst_netr_wksta_enum_user_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
170
+ raise RubySMB::Dcerpc::Error::WkssvcError,
171
+ "Error returned with netr_wksta_enum_user: #{wkst_netr_wksta_enum_user_response.error_status.value} - "\
172
+ "#{WindowsError::NTStatus.find_by_retval(wkst_netr_wksta_enum_user_response.error_status.value).join(',')}"
173
+ end
174
+ wkst_netr_wksta_enum_user_response.user_info.info
175
+ end
176
+
62
177
  end
63
178
  end
64
179
  end
@@ -155,9 +155,9 @@ module RubySMB
155
155
  their_blob = type3_msg.ntlm_response[digest.digest_length..-1]
156
156
 
157
157
  ntlmv2_hash = Net::NTLM.ntlmv2_hash(
158
- RubySMB::Utils.safe_encode(account.username, 'UTF-16LE'),
159
- RubySMB::Utils.safe_encode(account.password, 'UTF-16LE'),
160
- RubySMB::Utils.safe_encode(type3_msg.domain, 'UTF-16LE'), # don't use the account domain because of the special '.' value
158
+ Net::NTLM::EncodeUtil.encode_utf16le(account.username),
159
+ Net::NTLM::EncodeUtil.encode_utf16le(account.password),
160
+ type3_msg.domain.force_encoding('ASCII-8BIT'), # don't use the account domain because of the special '.' value
161
161
  {client_challenge: their_blob[16...24], unicode: true}
162
162
  )
163
163
 
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.3.8'.freeze
2
+ VERSION = '3.3.10'.freeze
3
3
  end
@@ -1,11 +1,3 @@
1
- RSpec.describe RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle do
2
- subject(:packet) { described_class.new }
3
-
4
- it 'is a Ndr::NdrWideStringPtr' do
5
- expect(packet).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringPtr)
6
- end
7
- end
8
-
9
1
  RSpec.describe RubySMB::Dcerpc::Wkssvc::NetrWkstaGetInfoRequest do
10
2
  subject(:packet) { described_class.new }
11
3
 
@@ -305,7 +305,7 @@ RSpec.describe RubySMB::Dcerpc::Wkssvc::LpwkstaInfo do
305
305
  it 'is little endian' do
306
306
  expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
307
307
  end
308
- it 'it is a Ndr::NdrStruct' do
308
+ it 'is a Ndr::NdrStruct' do
309
309
  expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrStruct
310
310
  end
311
311
  describe '#level' do
@@ -0,0 +1,7 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it 'is a Ndr::NdrWideStringPtr' do
5
+ expect(packet).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringPtr)
6
+ end
7
+ end
@@ -0,0 +1,71 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::NetrWkstaUserEnumRequest do
2
+ subject(:packet) { described_class.new }
3
+
4
+ def random_str(nb = 8)
5
+ nb.times.map { rand('a'.ord..'z'.ord).chr }.join
6
+ end
7
+
8
+ it { is_expected.to respond_to :server_name }
9
+ it { is_expected.to respond_to :user_info }
10
+ it { is_expected.to respond_to :preferred_max_length }
11
+ it { is_expected.to respond_to :result_handle }
12
+ it { is_expected.to respond_to :opnum }
13
+
14
+ it 'is little endian' do
15
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
16
+ end
17
+ it 'is a BinData::Record' do
18
+ expect(packet).to be_a(BinData::Record)
19
+ end
20
+ describe '#server_name' do
21
+ it 'is a WkssvcIdentifyHandle structure' do
22
+ expect(packet.server_name).to be_a RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle
23
+ end
24
+ end
25
+ describe '#user_info' do
26
+ it 'is a WkstaUserEnumStructure structure' do
27
+ expect(packet.user_info).to be_a RubySMB::Dcerpc::Wkssvc::WkstaUserEnumStructure
28
+ end
29
+ end
30
+ describe '#preferred_max_length' do
31
+ it 'is a NdrUint32 structure' do
32
+ expect(packet.preferred_max_length).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
33
+ end
34
+
35
+ it 'has a default value of 0xFFFFFFFF' do
36
+ expect(packet.preferred_max_length).to eq(0xFFFFFFFF)
37
+ end
38
+ end
39
+ describe '#result_handle' do
40
+ it 'is a NdrUint32Ptr structure' do
41
+ expect(packet.result_handle).to be_a RubySMB::Dcerpc::Ndr::NdrUint32Ptr
42
+ end
43
+
44
+ it 'has a default value of 0' do
45
+ expect(packet.result_handle).to eq(0)
46
+ end
47
+ end
48
+ describe '#initialize_instance' do
49
+ it 'sets #opnum to NETR_WKSTA_USER_ENUM constant' do
50
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Wkssvc::NETR_WKSTA_USER_ENUM)
51
+ end
52
+ end
53
+ it 'reads itself' do
54
+ packet = described_class.new(
55
+ server_name: 'TestServer',
56
+ user_info: {
57
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_USER_INFO_0,
58
+ info: {
59
+ wkui0_entries_read: 1,
60
+ wkui0_buffer: [{
61
+ wkui0_username: random_str
62
+ }],
63
+ },
64
+ },
65
+ preferred_max_length: 0xFFFFFFFF,
66
+ result_handle: 0
67
+ )
68
+ binary = packet.to_binary_s
69
+ expect(described_class.read(binary)).to eq(packet)
70
+ end
71
+ end
@@ -0,0 +1,65 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::NetrWkstaUserEnumResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ def random_str(nb = 8)
5
+ nb.times.map { rand('a'.ord..'z'.ord).chr }.join
6
+ end
7
+
8
+ it { is_expected.to respond_to :user_info }
9
+ it { is_expected.to respond_to :total_entries }
10
+ it { is_expected.to respond_to :result_handle }
11
+ it { is_expected.to respond_to :error_status }
12
+
13
+ it 'is little endian' do
14
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
15
+ end
16
+ it 'is a BinData::Record' do
17
+ expect(packet).to be_a(BinData::Record)
18
+ end
19
+ describe '#user_info' do
20
+ it 'is a WkstaUserEnumStructure structure' do
21
+ expect(packet.user_info).to be_a RubySMB::Dcerpc::Wkssvc::WkstaUserEnumStructure
22
+ end
23
+ end
24
+ describe '#total_entries' do
25
+ it 'is a NdrUint32Ptr structure' do
26
+ expect(packet.total_entries).to be_a RubySMB::Dcerpc::Ndr::NdrUint32Ptr
27
+ end
28
+ end
29
+ describe '#result_handle' do
30
+ it 'is a NdrUint32Ptr structure' do
31
+ expect(packet.result_handle).to be_a RubySMB::Dcerpc::Ndr::NdrUint32Ptr
32
+ end
33
+ end
34
+ describe '#error_status' do
35
+ it 'is a NdrUint32 structure' do
36
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
37
+ end
38
+ end
39
+ describe '#initialize_instance' do
40
+ it 'sets #opnum to NETR_WKSTA_USER_ENUM constant' do
41
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Wkssvc::NETR_WKSTA_USER_ENUM)
42
+ end
43
+ end
44
+ it 'reads itself' do
45
+ packet = described_class.new(
46
+ user_info: {
47
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_USER_INFO_1,
48
+ info: {
49
+ wkui1_entries_read: 1,
50
+ wkui1_buffer: [{
51
+ wkui1_username: random_str,
52
+ wkui1_logon_domain: random_str,
53
+ wkui1_oth_domains: random_str,
54
+ wkui1_logon_server: random_str
55
+ }],
56
+ },
57
+ },
58
+ total_entries: 1,
59
+ result_handle: 0,
60
+ error_status: 0
61
+ )
62
+ binary = packet.to_binary_s
63
+ expect(described_class.read(binary)).to eq(packet)
64
+ end
65
+ end
@@ -1,3 +1,11 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it 'is a Ndr::NdrWideStringzPtr' do
5
+ expect(packet).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
6
+ end
7
+ end
8
+
1
9
  RSpec.describe RubySMB::Dcerpc::Wkssvc do
2
10
  let(:wkssvc) do
3
11
  RubySMB::SMB1::Pipe.new(
@@ -23,7 +31,7 @@ RSpec.describe RubySMB::Dcerpc::Wkssvc do
23
31
  it 'sets the request with the expected values' do
24
32
  wkssvc.netr_wksta_get_info
25
33
  expect(described_class::NetrWkstaGetInfoRequest).to have_received(:new).with(
26
- server_name: "\x00",
34
+ server_name: '',
27
35
  level: described_class::WKSTA_INFO_100
28
36
  )
29
37
  end
@@ -67,4 +75,53 @@ RSpec.describe RubySMB::Dcerpc::Wkssvc do
67
75
  end
68
76
  end
69
77
  end
78
+
79
+ describe '#netr_wksta_user_enum' do
80
+ let(:wkst_netr_wksta_user_enum_request) { double('NetrWkstaUserEnumRequest') }
81
+ let(:response) { double('Response') }
82
+ let(:wkst_netr_wksta_user_enum_response) { double('NetrWkstaUserEnumResponse') }
83
+ let(:info) { double('info') }
84
+ before :example do
85
+ allow(described_class::NetrWkstaUserEnumRequest).to receive(:new).and_return(wkst_netr_wksta_user_enum_request)
86
+ allow(wkssvc).to receive(:dcerpc_request).and_return(response)
87
+ allow(described_class::NetrWkstaUserEnumResponse).to receive(:read).and_return(wkst_netr_wksta_user_enum_response)
88
+ allow(wkst_netr_wksta_user_enum_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
89
+ allow(wkst_netr_wksta_user_enum_response).to receive_message_chain(:user_info, :info => info)
90
+ end
91
+
92
+ it 'sets the request with the expected values' do
93
+ wkssvc.netr_wksta_user_enum
94
+ expect(described_class::NetrWkstaUserEnumRequest).to have_received(:new).with(
95
+ server_name: '',
96
+ user_info: {
97
+ level: described_class::WKSTA_USER_INFO_0,
98
+ tag: described_class::WKSTA_USER_INFO_0,
99
+ info: {
100
+ wkui0_entries_read: 0,
101
+ },
102
+ },
103
+ preferred_max_length: 0xFFFFFFFF,
104
+ result_handle: 0
105
+ )
106
+ end
107
+ it 'send the expected request structure' do
108
+ wkssvc.netr_wksta_user_enum
109
+ expect(wkssvc).to have_received(:dcerpc_request).with(wkst_netr_wksta_user_enum_request)
110
+ end
111
+ context 'when an IOError occurs while parsing the response' do
112
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
113
+ allow(described_class::NetrWkstaUserEnumResponse).to receive(:read).and_raise(IOError)
114
+ expect { wkssvc.netr_wksta_user_enum }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
115
+ end
116
+ end
117
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
118
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
119
+ allow(wkst_netr_wksta_user_enum_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
120
+ expect { wkssvc.netr_wksta_user_enum }.to raise_error(RubySMB::Dcerpc::Error::WkssvcError)
121
+ end
122
+ end
123
+ it 'returns the expected handler' do
124
+ expect(wkssvc.netr_wksta_user_enum).to eq(info)
125
+ end
126
+ end
70
127
  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.8
4
+ version: 3.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -38,7 +38,7 @@ cert_chain:
38
38
  DgscAao7wB3xW2BWEp1KnaDWkf1x9ttgoBEYyuYwU7uatB67kBQG1PKvLt79wHvz
39
39
  Dxs+KOjGbBRfMnPgVGYkORKVrZIwlaboHbDKxcVW5xv+oZc7KYXWGg==
40
40
  -----END CERTIFICATE-----
41
- date: 2024-05-16 00:00:00.000000000 Z
41
+ date: 2024-09-11 00:00:00.000000000 Z
42
42
  dependencies:
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: redcarpet
@@ -295,6 +295,9 @@ files:
295
295
  - lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_response.rb
296
296
  - lib/ruby_smb/dcerpc/ndr.rb
297
297
  - lib/ruby_smb/dcerpc/netlogon.rb
298
+ - lib/ruby_smb/dcerpc/netlogon/domain_controller_infow.rb
299
+ - lib/ruby_smb/dcerpc/netlogon/dsr_get_dc_name_ex2_request.rb
300
+ - lib/ruby_smb/dcerpc/netlogon/dsr_get_dc_name_ex2_response.rb
298
301
  - lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb
299
302
  - lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb
300
303
  - lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb
@@ -406,6 +409,8 @@ files:
406
409
  - lib/ruby_smb/dcerpc/wkssvc.rb
407
410
  - lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb
408
411
  - lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb
412
+ - lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_request.rb
413
+ - lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_response.rb
409
414
  - lib/ruby_smb/dialect.rb
410
415
  - lib/ruby_smb/dispatcher.rb
411
416
  - lib/ruby_smb/dispatcher/base.rb
@@ -776,6 +781,9 @@ files:
776
781
  - spec/lib/ruby_smb/dcerpc/winreg_spec.rb
777
782
  - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb
778
783
  - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb
784
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_identity_handle.rb
785
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_request_spec.rb
786
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_response_spec.rb
779
787
  - spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb
780
788
  - spec/lib/ruby_smb/dcerpc_spec.rb
781
789
  - spec/lib/ruby_smb/dispatcher/base_spec.rb
@@ -1117,6 +1125,9 @@ test_files:
1117
1125
  - spec/lib/ruby_smb/dcerpc/winreg_spec.rb
1118
1126
  - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb
1119
1127
  - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb
1128
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_identity_handle.rb
1129
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_request_spec.rb
1130
+ - spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_user_enum_response_spec.rb
1120
1131
  - spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb
1121
1132
  - spec/lib/ruby_smb/dcerpc_spec.rb
1122
1133
  - spec/lib/ruby_smb/dispatcher/base_spec.rb
metadata.gz.sig CHANGED
Binary file