ruby_smb 3.3.19 → 3.3.21
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
- data/examples/anonymous_auth.rb +5 -0
- data/examples/append_file.rb +57 -14
- data/examples/authenticate.rb +64 -16
- data/examples/delete_file.rb +53 -11
- data/examples/dump_secrets_from_sid.rb +43 -8
- data/examples/enum_domain_users.rb +51 -8
- data/examples/enum_registry_key.rb +51 -7
- data/examples/enum_registry_values.rb +51 -9
- data/examples/get_computer_info.rb +48 -8
- data/examples/list_directory.rb +54 -12
- data/examples/negotiate.rb +54 -42
- data/examples/negotiate_with_netbios_service.rb +55 -16
- data/examples/net_share_enum_all.rb +47 -8
- data/examples/pipes.rb +51 -7
- data/examples/query_service_status.rb +51 -8
- data/examples/read_file_encryption.rb +71 -26
- data/examples/read_registry_key_value.rb +54 -9
- data/examples/rename_file.rb +58 -15
- data/examples/write_file.rb +58 -15
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info.rb +31 -0
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb +4 -0
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb +12 -4
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_level.rb +28 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request.rb +90 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response.rb +56 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_information_level.rb +35 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_path_information_request.rb +75 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_path_information_response.rb +51 -0
- data/lib/ruby_smb/smb1/packet/trans2.rb +8 -0
- data/lib/ruby_smb/smb1/tree.rb +124 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request_spec.rb +6 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb +52 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb +29 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb +114 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +124 -0
- metadata +17 -2
|
@@ -582,6 +582,130 @@ RSpec.describe RubySMB::SMB1::Tree do
|
|
|
582
582
|
end
|
|
583
583
|
end
|
|
584
584
|
|
|
585
|
+
describe '#set_unix_link' do
|
|
586
|
+
let(:set_path_response) { RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse.new }
|
|
587
|
+
|
|
588
|
+
before :each do
|
|
589
|
+
# Stub out the CIFS UNIX Extensions handshake — covered separately below.
|
|
590
|
+
allow(tree).to receive(:enable_cifs_unix_extensions)
|
|
591
|
+
allow(client).to receive(:send_recv)
|
|
592
|
+
allow(RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse).to receive(:read).and_return(set_path_response)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
it 'performs the CIFS UNIX Extensions handshake before issuing the symlink request' do
|
|
596
|
+
call_order = []
|
|
597
|
+
allow(tree).to receive(:enable_cifs_unix_extensions) { call_order << :handshake }
|
|
598
|
+
allow(client).to receive(:send_recv) { call_order << :set_path; '' }
|
|
599
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
600
|
+
expect(call_order).to eq([:handshake, :set_path])
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
it 'sends a Trans2 SetPathInformationRequest with the UNIX_LINK info level' do
|
|
604
|
+
allow(client).to receive(:send_recv) do |request|
|
|
605
|
+
expect(request).to be_a(RubySMB::SMB1::Packet::Trans2::SetPathInformationRequest)
|
|
606
|
+
expect(request.data_block.trans2_parameters.information_level).to(
|
|
607
|
+
eq(RubySMB::SMB1::Packet::Trans2::SetInformationLevel::SMB_SET_FILE_UNIX_LINK)
|
|
608
|
+
)
|
|
609
|
+
end
|
|
610
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
it 'sets the Tree ID on the request' do
|
|
614
|
+
allow(client).to receive(:send_recv) do |request|
|
|
615
|
+
expect(request.smb_header.tid).to eq(tree.id)
|
|
616
|
+
end
|
|
617
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
it 'encodes the symlink path and target as raw byte strings (non-unicode)' do
|
|
621
|
+
allow(client).to receive(:send_recv) do |request|
|
|
622
|
+
raw = request.to_binary_s
|
|
623
|
+
expect(request.smb_header.flags2.unicode).to eq(0)
|
|
624
|
+
expect(raw).to include('escape'.b)
|
|
625
|
+
expect(raw).to include('../../etc'.b)
|
|
626
|
+
expect(raw).not_to include('escape'.encode('UTF-16LE').b)
|
|
627
|
+
end
|
|
628
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
it 'returns STATUS_SUCCESS on a successful response' do
|
|
632
|
+
expect(tree.set_unix_link(symlink: 'escape', target: '../../etc'))
|
|
633
|
+
.to eq(WindowsError::NTStatus::STATUS_SUCCESS)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
context 'when the server returns a non-Trans2 response packet' do
|
|
637
|
+
it 'raises InvalidPacket' do
|
|
638
|
+
allow(set_path_response).to receive(:valid?).and_return(false)
|
|
639
|
+
expect {
|
|
640
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
641
|
+
}.to raise_error(RubySMB::Error::InvalidPacket)
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
context 'when the response has a non-success status code' do
|
|
646
|
+
it 'raises UnexpectedStatusCode' do
|
|
647
|
+
set_path_response.smb_header.nt_status =
|
|
648
|
+
WindowsError::NTStatus::STATUS_ACCESS_DENIED.value
|
|
649
|
+
expect {
|
|
650
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
651
|
+
}.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
describe '#enable_cifs_unix_extensions' do
|
|
657
|
+
let(:query_response) { RubySMB::SMB1::Packet::Trans2::QueryFsInformationResponse.new }
|
|
658
|
+
let(:set_response) { RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse.new }
|
|
659
|
+
|
|
660
|
+
before :each do
|
|
661
|
+
# Server advertises major=1, minor=0, caps=0x0000_0000_0000_017B
|
|
662
|
+
info = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.new
|
|
663
|
+
info.major_version = 1
|
|
664
|
+
info.minor_version = 0
|
|
665
|
+
info.capabilities = 0x17B
|
|
666
|
+
query_response.data_block.trans2_data.buffer = info.to_binary_s
|
|
667
|
+
allow(RubySMB::SMB1::Packet::Trans2::QueryFsInformationResponse).to receive(:read).and_return(query_response)
|
|
668
|
+
allow(RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse).to receive(:read).and_return(set_response)
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
it 'queries the server for CIFS UNIX info and then echoes the capability bits back via SET_CIFS_UNIX_INFO' do
|
|
672
|
+
sent = []
|
|
673
|
+
allow(client).to receive(:send_recv) do |req|
|
|
674
|
+
sent << req
|
|
675
|
+
''
|
|
676
|
+
end
|
|
677
|
+
tree.enable_cifs_unix_extensions
|
|
678
|
+
|
|
679
|
+
expect(sent[0]).to be_a(RubySMB::SMB1::Packet::Trans2::QueryFsInformationRequest)
|
|
680
|
+
expect(sent[0].data_block.trans2_parameters.information_level).to(
|
|
681
|
+
eq(RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::SMB_QUERY_CIFS_UNIX_INFO)
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
expect(sent[1]).to be_a(RubySMB::SMB1::Packet::Trans2::SetFsInformationRequest)
|
|
685
|
+
expect(sent[1].data_block.trans2_parameters.information_level).to(
|
|
686
|
+
eq(RubySMB::SMB1::Packet::Trans2::SetFsInformationLevel::SMB_SET_CIFS_UNIX_INFO)
|
|
687
|
+
)
|
|
688
|
+
echoed = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.read(
|
|
689
|
+
sent[1].data_block.trans2_data.buffer
|
|
690
|
+
)
|
|
691
|
+
expect(echoed.major_version).to eq(1)
|
|
692
|
+
expect(echoed.minor_version).to eq(0)
|
|
693
|
+
expect(echoed.capabilities).to eq(0x17B)
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
it 'raises UnexpectedStatusCode when the QUERY leg fails' do
|
|
697
|
+
query_response.smb_header.nt_status = WindowsError::NTStatus::STATUS_ACCESS_DENIED.value
|
|
698
|
+
allow(client).to receive(:send_recv).and_return('')
|
|
699
|
+
expect { tree.enable_cifs_unix_extensions }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
it 'raises UnexpectedStatusCode when the SET leg fails' do
|
|
703
|
+
set_response.smb_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_PARAMETER.value
|
|
704
|
+
allow(client).to receive(:send_recv).and_return('')
|
|
705
|
+
expect { tree.enable_cifs_unix_extensions }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
706
|
+
end
|
|
707
|
+
end
|
|
708
|
+
|
|
585
709
|
describe '#set_header_fields' do
|
|
586
710
|
let(:modified_request) { tree.set_header_fields(disco_req) }
|
|
587
711
|
it 'adds the TreeID to the header' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_smb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.3.
|
|
4
|
+
version: 3.3.21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Metasploit Hackers
|
|
@@ -13,7 +13,7 @@ authors:
|
|
|
13
13
|
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2026-
|
|
16
|
+
date: 2026-06-08 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: redcarpet
|
|
@@ -571,6 +571,7 @@ files:
|
|
|
571
571
|
- lib/ruby_smb/smb1/packet/trans2/query_file_information_response.rb
|
|
572
572
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb
|
|
573
573
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info.rb
|
|
574
|
+
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info.rb
|
|
574
575
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb
|
|
575
576
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_response.rb
|
|
576
577
|
- lib/ruby_smb/smb1/packet/trans2/query_information_level.rb
|
|
@@ -583,6 +584,12 @@ files:
|
|
|
583
584
|
- lib/ruby_smb/smb1/packet/trans2/response.rb
|
|
584
585
|
- lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb
|
|
585
586
|
- lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb
|
|
587
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_level.rb
|
|
588
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_request.rb
|
|
589
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_response.rb
|
|
590
|
+
- lib/ruby_smb/smb1/packet/trans2/set_information_level.rb
|
|
591
|
+
- lib/ruby_smb/smb1/packet/trans2/set_path_information_request.rb
|
|
592
|
+
- lib/ruby_smb/smb1/packet/trans2/set_path_information_response.rb
|
|
586
593
|
- lib/ruby_smb/smb1/packet/trans2/subcommands.rb
|
|
587
594
|
- lib/ruby_smb/smb1/packet/trans2/win9x_framing.rb
|
|
588
595
|
- lib/ruby_smb/smb1/packet/tree_connect_request.rb
|
|
@@ -922,6 +929,10 @@ files:
|
|
|
922
929
|
- spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb
|
|
923
930
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb
|
|
924
931
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb
|
|
932
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb
|
|
933
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb
|
|
934
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb
|
|
935
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb
|
|
925
936
|
- spec/lib/ruby_smb/smb1/packet/trans2/win9x_framing_spec.rb
|
|
926
937
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb
|
|
927
938
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb
|
|
@@ -1275,6 +1286,10 @@ test_files:
|
|
|
1275
1286
|
- spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb
|
|
1276
1287
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb
|
|
1277
1288
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb
|
|
1289
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb
|
|
1290
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb
|
|
1291
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb
|
|
1292
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb
|
|
1278
1293
|
- spec/lib/ruby_smb/smb1/packet/trans2/win9x_framing_spec.rb
|
|
1279
1294
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb
|
|
1280
1295
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb
|