ruby_smb 2.0.12 → 2.0.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/.github/workflows/verify.yml +1 -1
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/get_computer_info.rb +42 -0
- data/examples/query_service_status.rb +42 -4
- data/lib/ruby_smb/client.rb +3 -14
- data/lib/ruby_smb/dcerpc/bind.rb +28 -20
- data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
- data/lib/ruby_smb/dcerpc/client.rb +542 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
- data/lib/ruby_smb/dcerpc/epm.rb +75 -0
- data/lib/ruby_smb/dcerpc/error.rb +17 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
- data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
- data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
- data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
- data/lib/ruby_smb/dcerpc/request.rb +79 -32
- data/lib/ruby_smb/dcerpc/response.rb +45 -10
- data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
- data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
- data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr.rb +613 -0
- data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
- data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
- data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
- data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
- data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
- data/lib/ruby_smb/dcerpc.rb +41 -11
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/ntlm.rb +18 -2
- data/lib/ruby_smb/smb1/pipe.rb +4 -0
- data/lib/ruby_smb/smb2/pipe.rb +4 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +1 -2
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
- data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
- data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
- data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
- data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
- data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
- data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
- data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
- data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
- data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
- data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
- data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +0 -0
- metadata +96 -5
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dff619ce28b159e4f0829b3e6ab01578831b7ce6ef259f4f006fae819f62c252
|
|
4
|
+
data.tar.gz: cd3755a1fdd80484c04375fde5f19d8867fb004e7152b7e87600f772cc22a6fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2336c7b2bec69f1b86f1b8ef0fc0787793cf6ca4b9212f9f3e6666b94915c77e230aa0f4c583304deaa30a341ee93ebec2b5fc4e9dbabe06ca86403506f2a1df
|
|
7
|
+
data.tar.gz: db316b93e942705596156aa156ecc58167335f05fb4259b93be09afdd618e0725589e10ffc4451947ceb32a1a3c72ee22a8e054cde46e36517a89fc1e426b2d7
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This example script is used for testing DCERPC client and DRSR structures.
|
|
4
|
+
# It will attempt to connect to a host and enumerate user secrets.
|
|
5
|
+
# Example usage: ruby dump_secrets_from_sid.rb 192.168.172.138 msfadmin msfadmin MYDOMAIN S-1-5-21-419547006-9448028-4223375872-500
|
|
6
|
+
# This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin
|
|
7
|
+
# credentials and enumerate secrets of domain user with SID
|
|
8
|
+
# S-1-5-21-419547006-9448028-4223375872-500
|
|
9
|
+
|
|
10
|
+
require 'bundler/setup'
|
|
11
|
+
require 'ruby_smb/dcerpc/client'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
address = ARGV[0]
|
|
15
|
+
username = ARGV[1]
|
|
16
|
+
password = ARGV[2]
|
|
17
|
+
domain = ARGV[3]
|
|
18
|
+
sid = ARGV[4]
|
|
19
|
+
|
|
20
|
+
client = RubySMB::Dcerpc::Client.new(
|
|
21
|
+
address,
|
|
22
|
+
RubySMB::Dcerpc::Drsr,
|
|
23
|
+
username: username,
|
|
24
|
+
password: password,
|
|
25
|
+
)
|
|
26
|
+
client.connect
|
|
27
|
+
puts('Binding to DRSR...')
|
|
28
|
+
client.bind(
|
|
29
|
+
auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
30
|
+
auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
|
|
31
|
+
)
|
|
32
|
+
puts('Bound to DRSR')
|
|
33
|
+
ph_drs = client.drs_bind
|
|
34
|
+
puts "ph_drs: #{ph_drs}"
|
|
35
|
+
puts
|
|
36
|
+
|
|
37
|
+
dc_infos = client.drs_domain_controller_info(ph_drs, domain)
|
|
38
|
+
dc_infos.each do |dc_info|
|
|
39
|
+
dc_info.field_names.each do |field|
|
|
40
|
+
puts "#{field}: #{dc_info.send(field).to_s.encode('utf-8')}"
|
|
41
|
+
end
|
|
42
|
+
puts
|
|
43
|
+
puts
|
|
44
|
+
|
|
45
|
+
crack_names = client.drs_crack_names(ph_drs, rp_names: [sid])
|
|
46
|
+
puts "SID: #{sid}"
|
|
47
|
+
crack_names.each do |crack_name|
|
|
48
|
+
puts "Domain: #{crack_name.p_domain.to_s.encode('utf-8')}"
|
|
49
|
+
puts "Name: #{crack_name.p_name.to_s.encode('utf-8')}"
|
|
50
|
+
|
|
51
|
+
user_record = client.drs_get_nc_changes(
|
|
52
|
+
ph_drs,
|
|
53
|
+
nc_guid: crack_name.p_name.to_s.encode('utf-8'),
|
|
54
|
+
dsa_object_guid: dc_info.ntds_dsa_object_guid,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# self.__decryptHash
|
|
58
|
+
dn = user_record.pmsg_out.msg_getchg.p_nc.string_name.to_ary[0..-1].join.encode('utf-8')
|
|
59
|
+
puts "Decrypting hash for user: #{dn}"
|
|
60
|
+
|
|
61
|
+
entinf_struct = user_record.pmsg_out.msg_getchg.p_objects.entinf
|
|
62
|
+
object_sid = rid = entinf_struct.p_name.sid[-4..-1].unpack('<L').first
|
|
63
|
+
lm_hash = Net::NTLM.lm_hash('')
|
|
64
|
+
nt_hash = Net::NTLM.ntlm_hash('')
|
|
65
|
+
disabled = nil
|
|
66
|
+
computer_account = nil
|
|
67
|
+
password_never_expires = nil
|
|
68
|
+
password_not_required = nil
|
|
69
|
+
pwd_last_set = nil
|
|
70
|
+
last_logon = nil
|
|
71
|
+
expires = nil
|
|
72
|
+
lm_history = []
|
|
73
|
+
nt_history = []
|
|
74
|
+
domain_name = ''
|
|
75
|
+
user = 'unknown'
|
|
76
|
+
kerberos_keys = {}
|
|
77
|
+
clear_text_passwords = []
|
|
78
|
+
|
|
79
|
+
entinf_struct.attr_block.p_attr.each do |attr|
|
|
80
|
+
next unless attr.attr_val.val_count > 0
|
|
81
|
+
# begin
|
|
82
|
+
att_id = user_record.pmsg_out.msg_getchg.oid_from_attid(attr.attr_typ)
|
|
83
|
+
lookup_table = RubySMB::Dcerpc::Drsr::ATTRTYP_TO_ATTID
|
|
84
|
+
# rescue XXXX
|
|
85
|
+
# att_id = attr.attr_typ
|
|
86
|
+
# lookup_table = NAME_TO_ATTRTYP
|
|
87
|
+
# end
|
|
88
|
+
|
|
89
|
+
#puts "#{lookup_table.key(att_id) || 'Unknown'}: #{attr.attr_val.p_aval[0].p_val}"
|
|
90
|
+
|
|
91
|
+
attribute_value = attr.attr_val.p_aval[0].p_val.to_ary.map(&:chr).join
|
|
92
|
+
case att_id
|
|
93
|
+
when lookup_table['dBCSPwd']
|
|
94
|
+
encrypted_lm_hash = client.decrypt_attribute_value(attribute_value)
|
|
95
|
+
lm_hash = client.remove_des_layer(encrypted_lm_hash, rid)
|
|
96
|
+
when lookup_table['unicodePwd']
|
|
97
|
+
encrypted_nt_hash = client.decrypt_attribute_value(attribute_value)
|
|
98
|
+
nt_hash = client.remove_des_layer(encrypted_nt_hash, rid)
|
|
99
|
+
when lookup_table['userPrincipalName']
|
|
100
|
+
domain_name = attribute_value.force_encoding('utf-16le').encode('utf-8').split('@').last
|
|
101
|
+
when lookup_table['sAMAccountName']
|
|
102
|
+
user = attribute_value.force_encoding('utf-16le').encode('utf-8')
|
|
103
|
+
when lookup_table['objectSid']
|
|
104
|
+
object_sid = attribute_value
|
|
105
|
+
when lookup_table['userAccountControl']
|
|
106
|
+
user_account_control = attribute_value.unpack('L<')[0]
|
|
107
|
+
disabled = user_account_control & RubySMB::Dcerpc::Samr::UF_ACCOUNTDISABLE != 0
|
|
108
|
+
computer_account = user_account_control & RubySMB::Dcerpc::Samr::UF_NORMAL_ACCOUNT == 0
|
|
109
|
+
password_never_expires = user_account_control & RubySMB::Dcerpc::Samr::UF_DONT_EXPIRE_PASSWD != 0
|
|
110
|
+
password_not_required = user_account_control & RubySMB::Dcerpc::Samr::UF_PASSWD_NOTREQD != 0
|
|
111
|
+
when lookup_table['pwdLastSet']
|
|
112
|
+
pwd_last_set = Time.at(0)
|
|
113
|
+
time_value = attribute_value.unpack('Q<')[0]
|
|
114
|
+
if time_value > 0
|
|
115
|
+
pwd_last_set = RubySMB::Field::FileTime.new(time_value).to_time.utc
|
|
116
|
+
end
|
|
117
|
+
when lookup_table['accountExpires']
|
|
118
|
+
expires = Time.at(0)
|
|
119
|
+
time_value = attribute_value.unpack('Q<')[0]
|
|
120
|
+
if time_value > 0 && time_value != 0x7FFFFFFFFFFFFFFF
|
|
121
|
+
expires = RubySMB::Field::FileTime.new(time_value).to_time.utc
|
|
122
|
+
end
|
|
123
|
+
when lookup_table['lastLogonTimestamp']
|
|
124
|
+
last_logon = Time.at(0)
|
|
125
|
+
time_value = attribute_value.unpack('Q<')[0]
|
|
126
|
+
if time_value > 0
|
|
127
|
+
last_logon = RubySMB::Field::FileTime.new(time_value).to_time.utc
|
|
128
|
+
end
|
|
129
|
+
when lookup_table['lmPwdHistory']
|
|
130
|
+
tmp_lm_history = client.decrypt_attribute_value(attribute_value)
|
|
131
|
+
tmp_lm_history.bytes.each_slice(16) do |block|
|
|
132
|
+
lm_history << client.remove_des_layer(block.map(&:chr).join, rid)
|
|
133
|
+
end
|
|
134
|
+
when lookup_table['ntPwdHistory']
|
|
135
|
+
tmp_nt_history = client.decrypt_attribute_value(attribute_value)
|
|
136
|
+
tmp_nt_history.bytes.each_slice(16) do |block|
|
|
137
|
+
nt_history << client.remove_des_layer(block.map(&:chr).join, rid)
|
|
138
|
+
end
|
|
139
|
+
when lookup_table['supplementalCredentials']
|
|
140
|
+
# self.__decryptSupplementalInfo
|
|
141
|
+
plain_text = client.decrypt_attribute_value(attribute_value)
|
|
142
|
+
user_properties = RubySMB::Dcerpc::Samr::UserProperties.read(plain_text)
|
|
143
|
+
user_properties.user_properties.each do |user_property|
|
|
144
|
+
case user_property.property_name.encode('utf-8')
|
|
145
|
+
when 'Primary:Kerberos-Newer-Keys'
|
|
146
|
+
value = user_property.property_value
|
|
147
|
+
binary_value = value.chars.each_slice(2).map {|a,b| (a+b).hex.chr}.join
|
|
148
|
+
kerb_stored_credential_new = RubySMB::Dcerpc::Samr::KerbStoredCredentialNew.read(binary_value)
|
|
149
|
+
key_values = kerb_stored_credential_new.get_key_values
|
|
150
|
+
kerb_stored_credential_new.credentials.each_with_index do |credential, i|
|
|
151
|
+
kerberos_type = RubySMB::Dcerpc::Samr::KERBEROS_TYPE[credential.key_type]
|
|
152
|
+
if kerberos_type
|
|
153
|
+
kerberos_keys[kerberos_type] = key_values[i].unpack('H*')[0]
|
|
154
|
+
else
|
|
155
|
+
kerberos_keys["0x#{credential.key_type.to_i.to_s(16)}"] = key_values[i].unpack('H*')[0]
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
when 'Primary:CLEARTEXT'
|
|
159
|
+
# [MS-SAMR] 3.1.1.8.11.5 Primary:CLEARTEXT Property
|
|
160
|
+
# This credential type is the cleartext password. The value format is the UTF-16 encoded cleartext password.
|
|
161
|
+
begin
|
|
162
|
+
clear_text_passwords << user_property.property_value.to_s.force_encoding('utf-16le').encode('utf-8')
|
|
163
|
+
rescue EncodingError
|
|
164
|
+
# This could be because we're decoding a machine password. Printing it hex
|
|
165
|
+
# Keep clear_text_passwords with a ASCII-8BIT encoding
|
|
166
|
+
clear_text_passwords << user_property.property_value.to_s
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
user = "#{domain_name}\\#{user}" unless domain_name.empty?
|
|
174
|
+
|
|
175
|
+
puts "#{user}:#{rid}:#{lm_hash.unpack('H*')[0]}:#{nt_hash.unpack('H*')[0]}:::"
|
|
176
|
+
puts "Object SID: 0x#{object_sid.unpack('H*')[0]}"
|
|
177
|
+
puts "Password last set: #{pwd_last_set && pwd_last_set > Time.at(0) ? pwd_last_set : 'never'}"
|
|
178
|
+
puts "Last logon: #{last_logon && last_logon > Time.at(0) ? last_logon : 'never'}"
|
|
179
|
+
puts "Account disabled: #{disabled.nil? ? 'N/A' : disabled}"
|
|
180
|
+
puts "Computer account: #{computer_account.nil? ? 'N/A' : computer_account}"
|
|
181
|
+
puts "Password never expires: #{password_never_expires.nil? ? 'N/A' : password_never_expires}"
|
|
182
|
+
puts "Password not required: #{password_not_required.nil? ? 'N/A' : password_not_required}"
|
|
183
|
+
puts "Expired: #{!disabled && expires && expires > Time.at(0) && expires < Time.now}"
|
|
184
|
+
if nt_history.size > 1 and lm_history.size > 1
|
|
185
|
+
puts "Password history:"
|
|
186
|
+
nt_history[1..-1].zip(lm_history[1..-1]).each_with_index do |history, i|
|
|
187
|
+
nt_h, lm_h = history
|
|
188
|
+
empty_lm_h = Net::NTLM.lm_hash('')
|
|
189
|
+
puts " #{user}_history#{i}:#{rid}:#{empty_lm_h.unpack('H*')[0]}:#{nt_h.to_s.unpack('H*')[0]}::: (if LMHashes are not stored)"
|
|
190
|
+
puts " #{user}_history#{i}:#{rid}:#{lm_h.to_s.unpack('H*')[0]}:#{nt_h.to_s.unpack('H*')[0]}::: (if LMHashes are stored)"
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
puts "Kerberos keys:"
|
|
194
|
+
kerberos_keys.each do |key_type, key_value|
|
|
195
|
+
puts " #{user}:#{key_type}:#{key_value}"
|
|
196
|
+
end
|
|
197
|
+
puts "Clear passwords:"
|
|
198
|
+
clear_text_passwords.each do |passwd|
|
|
199
|
+
puts " #{user}:CLEARTEXT:#{passwd}"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
client.drs_unbind(ph_drs)
|
|
205
|
+
client.close
|
|
206
|
+
|
|
207
|
+
puts 'Done'
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This example script is used for testing DCERPC SAMR requests.
|
|
4
|
+
# It will attempt to connect to a server object and enumerate domain users.
|
|
5
|
+
# Example usage: ruby enum_domain_users.rb 192.168.172.138 msfadmin msfadmin MyDomain
|
|
6
|
+
|
|
7
|
+
require 'bundler/setup'
|
|
8
|
+
require 'ruby_smb'
|
|
9
|
+
|
|
10
|
+
address = ARGV[0]
|
|
11
|
+
username = ARGV[1]
|
|
12
|
+
password = ARGV[2]
|
|
13
|
+
domain = ARGV[3]
|
|
14
|
+
smb_versions = ARGV[4]&.split(',') || ['1','2','3']
|
|
15
|
+
|
|
16
|
+
sock = TCPSocket.new address, 445
|
|
17
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
|
|
18
|
+
|
|
19
|
+
client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
|
|
20
|
+
protocol = client.negotiate
|
|
21
|
+
status = client.authenticate
|
|
22
|
+
|
|
23
|
+
puts "#{protocol} : #{status}"
|
|
24
|
+
|
|
25
|
+
tree = client.tree_connect("\\\\#{address}\\IPC$")
|
|
26
|
+
samr = tree.open_file(filename: 'samr', write: true, read: true)
|
|
27
|
+
|
|
28
|
+
puts('Binding to \\samr...')
|
|
29
|
+
samr.bind(endpoint: RubySMB::Dcerpc::Samr)
|
|
30
|
+
puts('Bound to \\samr')
|
|
31
|
+
|
|
32
|
+
puts('[+] SAMR Connect')
|
|
33
|
+
server_handle = samr.samr_connect
|
|
34
|
+
|
|
35
|
+
domain_sid = samr.samr_lookup_domain(server_handle: server_handle, name: domain)
|
|
36
|
+
domain_handle = samr.samr_open_domain(server_handle: server_handle, domain_id: domain_sid)
|
|
37
|
+
|
|
38
|
+
builtin_domain_sid = samr.samr_lookup_domain(server_handle: server_handle, name: 'Builtin')
|
|
39
|
+
builtin_domain_handle = samr.samr_open_domain(server_handle: server_handle, domain_id: builtin_domain_sid)
|
|
40
|
+
|
|
41
|
+
users = samr.samr_enumerate_users_in_domain(domain_handle: domain_handle)
|
|
42
|
+
|
|
43
|
+
puts 'RID | SID | Name | Domain Groups | Domain Alias Groups | Builtin Alias Groups'
|
|
44
|
+
puts '--------------------------------------------------------------------------------------------------------------------------------'
|
|
45
|
+
users.each do |rid, name|
|
|
46
|
+
sid = samr.samr_rid_to_sid(object_handle: domain_handle, rid: rid)
|
|
47
|
+
domain_sid = sid.to_s.split('-')[0..-2].join('-')
|
|
48
|
+
|
|
49
|
+
user_handle = samr.samr_open_user(domain_handle: domain_handle, user_id: rid)
|
|
50
|
+
groups = samr.samr_get_group_for_user(user_handle: user_handle)
|
|
51
|
+
groups = groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group.relative_id.to_i}") }
|
|
52
|
+
|
|
53
|
+
alias_groups = samr.samr_get_alias_membership(domain_handle: domain_handle, sids: groups + [sid])
|
|
54
|
+
alias_groups = alias_groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group}") }
|
|
55
|
+
|
|
56
|
+
builtin_alias_groups = samr.samr_get_alias_membership(domain_handle: builtin_domain_handle, sids: groups + [sid])
|
|
57
|
+
builtin_alias_groups = builtin_alias_groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group}") }
|
|
58
|
+
|
|
59
|
+
#TODO: implement [LSAT] LsarLookupSids2 call to get the name of the "Unknown SID"'s
|
|
60
|
+
|
|
61
|
+
output = "#{"%-5s" % rid} | #{"%-43s" % sid} | #{name.encode('UTF-8')}"
|
|
62
|
+
output << " | #{groups.empty? ? 'N/A' : groups.map(&:name).join(', ')}"
|
|
63
|
+
output << " | #{alias_groups.empty? ? 'N/A' : alias_groups.map(&:name).join(', ')}"
|
|
64
|
+
output << " | #{builtin_alias_groups.empty? ? 'N/A' : builtin_alias_groups.map(&:name).join(', ')}"
|
|
65
|
+
puts output
|
|
66
|
+
|
|
67
|
+
samr.close_handle(user_handle)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
samr.close_handle(domain_handle)
|
|
71
|
+
samr.close_handle(builtin_domain_handle)
|
|
72
|
+
samr.close_handle(server_handle)
|
|
73
|
+
|
|
74
|
+
client.disconnect!
|
|
75
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This example script is used for testing DCERPC WKST requests.
|
|
4
|
+
# It will attempt to retrieve configuration information of a remote computer/server.
|
|
5
|
+
# Example usage: ruby enum_domain_users.rb 192.168.172.138 msfadmin msfadmin MyDomain
|
|
6
|
+
|
|
7
|
+
require 'bundler/setup'
|
|
8
|
+
require 'ruby_smb'
|
|
9
|
+
|
|
10
|
+
address = ARGV[0]
|
|
11
|
+
username = ARGV[1]
|
|
12
|
+
password = ARGV[2]
|
|
13
|
+
smb_versions = ARGV[3]&.split(',') || ['1','2','3']
|
|
14
|
+
|
|
15
|
+
sock = TCPSocket.new address, 445
|
|
16
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
|
|
17
|
+
|
|
18
|
+
client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
|
|
19
|
+
protocol = client.negotiate
|
|
20
|
+
status = client.authenticate
|
|
21
|
+
|
|
22
|
+
puts "#{protocol} : #{status}"
|
|
23
|
+
|
|
24
|
+
tree = client.tree_connect("\\\\#{address}\\IPC$")
|
|
25
|
+
wkssvc = tree.open_file(filename: 'wkssvc', write: true, read: true)
|
|
26
|
+
|
|
27
|
+
puts('Binding to \\wkssvc...')
|
|
28
|
+
wkssvc.bind(endpoint: RubySMB::Dcerpc::Wkssvc)
|
|
29
|
+
puts('Bound to \\wkssvc')
|
|
30
|
+
|
|
31
|
+
puts('[+] WKSSVC Connect')
|
|
32
|
+
|
|
33
|
+
info = wkssvc.netr_wksta_get_info
|
|
34
|
+
platform = RubySMB::Dcerpc::Wkssvc::PLATFORM_ID[info.wki100_platform_id]
|
|
35
|
+
puts "Platform: #{platform || 'Unknown'}"
|
|
36
|
+
puts "Computer Name: #{info.wki100_computername.encode('utf-8')}"
|
|
37
|
+
puts "LAN Group: #{info.wki100_langroup.encode('utf-8')}"
|
|
38
|
+
puts "OS Version: #{info.wki100_ver_major}.#{info.wki100_ver_minor}"
|
|
39
|
+
|
|
40
|
+
client.disconnect!
|
|
41
|
+
|
|
42
|
+
|
|
@@ -36,25 +36,63 @@ scm_handle = svcctl.open_sc_manager_w(address)
|
|
|
36
36
|
svc_handle = svcctl.open_service_w(scm_handle, service)
|
|
37
37
|
svc_status = svcctl.query_service_status(svc_handle)
|
|
38
38
|
|
|
39
|
+
puts
|
|
39
40
|
case svc_status.dw_current_state
|
|
40
41
|
when RubySMB::Dcerpc::Svcctl::SERVICE_RUNNING
|
|
41
42
|
puts("Service #{service} is running")
|
|
42
43
|
when RubySMB::Dcerpc::Svcctl::SERVICE_STOPPED
|
|
43
44
|
puts("Service #{service} is in stopped state")
|
|
44
45
|
end
|
|
46
|
+
puts
|
|
45
47
|
|
|
46
48
|
svc_config = svcctl.query_service_config(svc_handle)
|
|
49
|
+
|
|
50
|
+
service_type = 'Service type: '
|
|
51
|
+
case svc_config.dw_service_type
|
|
52
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_KERNEL_DRIVER
|
|
53
|
+
service_type << 'Driver service'
|
|
54
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_FILE_SYSTEM_DRIVER
|
|
55
|
+
service_type << 'File system driver service'
|
|
56
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_WIN32_OWN_PROCESS
|
|
57
|
+
service_type << 'Service that runs in its own process'
|
|
58
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_WIN32_SHARE_PROCESS
|
|
59
|
+
service_type << 'Service that shares a process with other services'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
start_type = 'Service start type: '
|
|
47
63
|
case svc_config.dw_start_type
|
|
48
64
|
when RubySMB::Dcerpc::Svcctl::SERVICE_DISABLED
|
|
49
|
-
|
|
65
|
+
start_type << 'Service is disabled'
|
|
50
66
|
when RubySMB::Dcerpc::Svcctl::SERVICE_BOOT_START, RubySMB::Dcerpc::Svcctl::SERVICE_SYSTEM_START
|
|
51
|
-
|
|
67
|
+
start_type << 'Service starts when the system boots up (driver)'
|
|
52
68
|
when RubySMB::Dcerpc::Svcctl::SERVICE_AUTO_START
|
|
53
|
-
|
|
69
|
+
start_type << 'Service starts automatically during system startup'
|
|
54
70
|
when RubySMB::Dcerpc::Svcctl::SERVICE_DEMAND_START
|
|
55
|
-
|
|
71
|
+
start_type << 'Service starts manually'
|
|
56
72
|
end
|
|
57
73
|
|
|
74
|
+
error_control = 'Error control: '
|
|
75
|
+
case svc_config.dw_error_control
|
|
76
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_IGNORE
|
|
77
|
+
error_control << 'SERVICE_ERROR_IGNORE'
|
|
78
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_NORMAL
|
|
79
|
+
error_control << 'SERVICE_ERROR_NORMAL'
|
|
80
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_SEVERE
|
|
81
|
+
error_control << 'SERVICE_ERROR_SEVERE'
|
|
82
|
+
when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_CRITICAL
|
|
83
|
+
error_control << 'SERVICE_ERROR_CRITICAL'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
puts service_type
|
|
87
|
+
puts start_type
|
|
88
|
+
puts error_control
|
|
89
|
+
puts "Binary path: #{svc_config.lp_binary_path_name.to_s.encode('utf-8')}"
|
|
90
|
+
puts "Load ordering service group: #{svc_config.lp_load_order_group.to_s.encode('utf-8')}"
|
|
91
|
+
puts "Service group tag ID: #{svc_config.dw_tag_id.to_s.encode('utf-8')}"
|
|
92
|
+
puts "Dependencies: #{svc_config.lp_dependencies.to_s.encode('utf-8')}"
|
|
93
|
+
puts "Service start name: #{svc_config.lp_service_start_name.to_s.encode('utf-8')}"
|
|
94
|
+
|
|
95
|
+
|
|
58
96
|
if svcctl
|
|
59
97
|
svcctl.close_service_handle(svc_handle) if svc_handle
|
|
60
98
|
svcctl.close_service_handle(scm_handle) if scm_handle
|
data/lib/ruby_smb/client.rb
CHANGED
|
@@ -279,7 +279,7 @@ module RubySMB
|
|
|
279
279
|
# @param smb2 [Boolean] whether or not to enable SMB2 support
|
|
280
280
|
# @param smb3 [Boolean] whether or not to enable SMB3 support
|
|
281
281
|
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
|
|
282
|
-
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags:
|
|
282
|
+
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
283
283
|
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
|
|
284
284
|
if smb1 == false && smb2 == false && smb3 == false
|
|
285
285
|
raise ArgumentError, 'You must enable at least one Protocol'
|
|
@@ -366,7 +366,7 @@ module RubySMB
|
|
|
366
366
|
# the credentials supplied during initialization, but can take a new set of credentials if needed.
|
|
367
367
|
def login(username: self.username, password: self.password,
|
|
368
368
|
domain: self.domain, local_workstation: self.local_workstation,
|
|
369
|
-
ntlm_flags:
|
|
369
|
+
ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
370
370
|
negotiate
|
|
371
371
|
session_setup(username, password, domain,
|
|
372
372
|
local_workstation: local_workstation,
|
|
@@ -374,7 +374,7 @@ module RubySMB
|
|
|
374
374
|
end
|
|
375
375
|
|
|
376
376
|
def session_setup(user, pass, domain, do_recv=true,
|
|
377
|
-
local_workstation: self.local_workstation, ntlm_flags:
|
|
377
|
+
local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
378
378
|
@domain = domain
|
|
379
379
|
@local_workstation = local_workstation
|
|
380
380
|
@password = pass.encode('utf-8') || ''.encode('utf-8')
|
|
@@ -648,16 +648,5 @@ module RubySMB
|
|
|
648
648
|
)
|
|
649
649
|
end
|
|
650
650
|
|
|
651
|
-
private
|
|
652
|
-
|
|
653
|
-
def default_flags
|
|
654
|
-
negotiate_version_flag = 0x02000000
|
|
655
|
-
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
|
656
|
-
RubySMB::NTLM::NEGOTIATE_FLAGS[:TARGET_INFO] |
|
|
657
|
-
negotiate_version_flag ^
|
|
658
|
-
RubySMB::NTLM::NEGOTIATE_FLAGS[:OEM]
|
|
659
|
-
|
|
660
|
-
flags
|
|
661
|
-
end
|
|
662
651
|
end
|
|
663
652
|
end
|
data/lib/ruby_smb/dcerpc/bind.rb
CHANGED
|
@@ -2,51 +2,59 @@ module RubySMB
|
|
|
2
2
|
module Dcerpc
|
|
3
3
|
# The Bind PDU as defined in
|
|
4
4
|
# [The bind PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_03)
|
|
5
|
-
class PContElemT <
|
|
5
|
+
class PContElemT < Ndr::NdrStruct
|
|
6
|
+
default_parameter byte_align: 4
|
|
6
7
|
endian :little
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
ndr_uint16 :p_cont_id, label: 'Context ID'
|
|
10
|
+
ndr_uint8 :n_transfer_syn, label: 'Number of transfer syntaxes', initial_value: 1
|
|
11
|
+
ndr_uint8 :reserved
|
|
11
12
|
p_syntax_id_t :abstract_syntax, label: 'Abstract syntax',
|
|
12
13
|
uuid: -> { endpoint::UUID },
|
|
13
14
|
ver_major: -> { endpoint::VER_MAJOR },
|
|
14
15
|
ver_minor: -> { endpoint::VER_MINOR }
|
|
15
|
-
array
|
|
16
|
+
array :transfer_syntaxes, label: 'Transfer syntax', type: :p_syntax_id_t,
|
|
16
17
|
initial_length: -> { n_transfer_syn },
|
|
17
18
|
uuid: -> { Ndr::UUID },
|
|
18
19
|
ver_major: -> { Ndr::VER_MAJOR },
|
|
19
|
-
ver_minor: -> { Ndr::VER_MINOR }
|
|
20
|
+
ver_minor: -> { Ndr::VER_MINOR },
|
|
21
|
+
byte_align: 4
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
class PContListT <
|
|
24
|
+
class PContListT < Ndr::NdrStruct
|
|
25
|
+
default_parameter byte_align: 4
|
|
23
26
|
endian :little
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
array
|
|
28
|
+
ndr_uint8 :n_context_elem, label: 'Number of context elements', initial_value: -> { 1 }
|
|
29
|
+
ndr_uint8 :reserved
|
|
30
|
+
ndr_uint16 :reserved2
|
|
31
|
+
array :p_cont_elem, label: 'Presentation context elements', type: :p_cont_elem_t,
|
|
29
32
|
initial_length: -> {n_context_elem},
|
|
30
|
-
endpoint: -> {endpoint}
|
|
33
|
+
endpoint: -> {endpoint},
|
|
34
|
+
byte_align: 4
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
class Bind < BinData::Record
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
pdu_header :pdu_header, label: 'PDU header'
|
|
38
|
+
PTYPE = PTypes::BIND
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
|
40
|
-
uint32 :assoc_group_id, label: 'ncarnation of client-server assoc group'
|
|
40
|
+
endian :little
|
|
41
41
|
|
|
42
|
+
# PDU Header
|
|
43
|
+
pdu_header :pdu_header, label: 'PDU header'
|
|
44
|
+
ndr_uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
|
45
|
+
ndr_uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
|
46
|
+
ndr_uint32 :assoc_group_id, label: 'incarnation of client-server assoc group'
|
|
42
47
|
p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
|
|
43
|
-
|
|
48
|
+
|
|
49
|
+
# Auth Verifier
|
|
50
|
+
sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
|
|
51
|
+
string :auth_value,
|
|
44
52
|
onlyif: -> { pdu_header.auth_length > 0 },
|
|
45
53
|
read_length: -> { pdu_header.auth_length }
|
|
46
54
|
|
|
47
55
|
def initialize_instance
|
|
48
56
|
super
|
|
49
|
-
pdu_header.ptype =
|
|
57
|
+
pdu_header.ptype = PTYPE
|
|
50
58
|
end
|
|
51
59
|
end
|
|
52
60
|
end
|
|
@@ -3,34 +3,39 @@ module RubySMB
|
|
|
3
3
|
# The Bind ACK PDU as defined in
|
|
4
4
|
# [The bind_ack PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_04)
|
|
5
5
|
|
|
6
|
-
class PResultT <
|
|
6
|
+
class PResultT < Ndr::NdrStruct
|
|
7
|
+
default_parameter byte_align: 4
|
|
7
8
|
endian :little
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
p_syntax_id_t
|
|
12
|
-
uuid:
|
|
10
|
+
ndr_uint16 :result, label: 'Presentation context negotiation results'
|
|
11
|
+
ndr_uint16 :reason, label: 'Rejection reason'
|
|
12
|
+
p_syntax_id_t :transfer_syntax, label: 'Presentation syntax ID',
|
|
13
|
+
uuid: -> { Ndr::UUID },
|
|
13
14
|
ver_major: -> { Ndr::VER_MAJOR },
|
|
14
15
|
ver_minor: -> { Ndr::VER_MINOR }
|
|
15
16
|
end
|
|
16
17
|
|
|
17
|
-
class PResultListT <
|
|
18
|
+
class PResultListT < Ndr::NdrStruct
|
|
19
|
+
default_parameter byte_align: 4
|
|
18
20
|
endian :little
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
array
|
|
22
|
+
ndr_uint8 :n_results, label: 'Number of results', initial_value: -> { p_results.size }
|
|
23
|
+
ndr_uint8 :reserved
|
|
24
|
+
ndr_uint16 :reserved2
|
|
25
|
+
array :p_results, label: 'Results', type: :p_result_t, initial_length: -> { n_results }, byte_align: 4
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
class PortAnyT <
|
|
28
|
+
class PortAnyT < Ndr::NdrStruct
|
|
29
|
+
default_parameter byte_align: 2
|
|
27
30
|
endian :little
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
stringz
|
|
32
|
+
ndr_uint16 :str_length, label: 'Length', initial_value: -> { port_spec.to_binary_s.size }
|
|
33
|
+
stringz :port_spec, label: 'Port string spec', byte_align: 2
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
class BindAck < BinData::Record
|
|
37
|
+
PTYPE = PTypes::BIND_ACK
|
|
38
|
+
|
|
34
39
|
# Presentation context negotiation results
|
|
35
40
|
ACCEPTANCE = 0
|
|
36
41
|
USER_REJECTION = 1
|
|
@@ -44,27 +49,23 @@ module RubySMB
|
|
|
44
49
|
|
|
45
50
|
endian :little
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
port_any_t
|
|
53
|
-
string :pad, length: -> { pad_length }
|
|
54
|
-
|
|
52
|
+
# PDU Header
|
|
53
|
+
pdu_header :pdu_header, label: 'PDU header'
|
|
54
|
+
ndr_uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
|
55
|
+
ndr_uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
|
56
|
+
ndr_uint32 :assoc_group_id, label: 'Association group ID'
|
|
57
|
+
port_any_t :sec_addr, label: 'Secondary address'
|
|
55
58
|
p_result_list_t :p_result_list, label: 'Presentation context result list'
|
|
56
|
-
|
|
59
|
+
|
|
60
|
+
# Auth Verifier
|
|
61
|
+
sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
|
|
62
|
+
string :auth_value,
|
|
57
63
|
onlyif: -> { pdu_header.auth_length > 0 },
|
|
58
64
|
read_length: -> { pdu_header.auth_length }
|
|
59
65
|
|
|
60
66
|
def initialize_instance
|
|
61
67
|
super
|
|
62
|
-
pdu_header.ptype =
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def pad_length
|
|
66
|
-
offset = (sec_addr.abs_offset + sec_addr.do_num_bytes) % 4
|
|
67
|
-
(4 - offset) % 4
|
|
68
|
+
pdu_header.ptype = PTYPE
|
|
68
69
|
end
|
|
69
70
|
end
|
|
70
71
|
end
|