ruby_smb 3.2.6 → 3.2.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6220ba1edc47882a9d30dd1937d877c22094ebaf9c2a72cb806489a65598e1ce
4
- data.tar.gz: 1b650bfdd2b6ba8323e9d3e7f4e161c7a659dddbffc7fa21a03d4a2e538f7297
3
+ metadata.gz: e4ddd94d3c783b3091a37c946c5069da85350c23294b33ddabcdc0476f828ec4
4
+ data.tar.gz: 990ad64d98bd60dd957c1b8b6fcf1abdbd6e8a52d408e0e6c03d3694354cb4ad
5
5
  SHA512:
6
- metadata.gz: 9e49bc0af1cd4ad61cba01ec70aecead1adbe3b4d58d6127593878596bdbc7f64c8d50b9aaa396004ffc3a3b5e8cf1806053d0825d44322aa4d4584bdddeced7
7
- data.tar.gz: 36ca2d7c9e6256a0faabac441e89ea86d43ccd8d2de342dba4965679d2e2c4fafa541fbc09c4457d656a2cccef1af53fe5ab487245800914ad8b9a6431679088
6
+ metadata.gz: bc7b1921009d55e8263ecfe3aa282bd4df35636a5055f5126ffa1866ed8140283bbfa14f341a4d791e30a7f51e0df631676ef211961c9712e457e0939983a6c7
7
+ data.tar.gz: 11982c6c2b2fb653756140c7024ccff301c72ee9b5ac44f85a5071f1d2a27dbdcf31b5936bc3ea646ef7219e3c917b5466ec3e6b26bbba116fc7552169244a4a
checksums.yaml.gz.sig CHANGED
Binary file
@@ -11,7 +11,7 @@ module RubySMB
11
11
  end
12
12
 
13
13
  logger.debug("Received #{SMB1::Commands.name(request.smb_header.command)} request for share: #{share_processor.provider.name}")
14
- share_processor.send(__callee__, request)
14
+ share_processor.share_io(__callee__, request)
15
15
  end
16
16
 
17
17
  alias :do_close_smb1 :proxy_share_io_smb1
@@ -29,7 +29,7 @@ module RubySMB
29
29
  end
30
30
 
31
31
  logger.debug("Received #{SMB2::Commands.name(request.smb2_header.command)} request for share: #{share_processor.provider.name}")
32
- share_processor.send(__callee__, request)
32
+ share_processor.share_io(__callee__, request)
33
33
  end
34
34
 
35
35
  alias :do_close_smb2 :proxy_share_io_smb2
@@ -14,13 +14,13 @@ module RubySMB
14
14
  # @param [String] name The name of this share.
15
15
  # @param [String, Pathname] path The local file system path to share. This path must be an absolute path to an existing
16
16
  # directory.
17
- def initialize(name, path)
17
+ def initialize(name, path, hooks: nil)
18
18
  path = Pathname.new(File.expand_path(path)) if path.is_a?(String)
19
19
  raise ArgumentError.new('path must be a directory') unless path.directory? # it needs to exist
20
20
  raise ArgumentError.new('path must be absolute') unless path.absolute? # it needs to be absolute so it is independent of the cwd
21
21
 
22
22
  @path = path
23
- super(name)
23
+ super(name, hooks: hooks)
24
24
  end
25
25
 
26
26
  attr_accessor :path
@@ -80,6 +80,31 @@ module RubySMB
80
80
  @server_client.server
81
81
  end
82
82
 
83
+ # Forward a share IO method for a particular request. This is a choke point to allow any hooks that were
84
+ # registered with the share provider to be executed before and after the specified method is invoked to
85
+ # process the request and generate the response. This is used for both SMB1 and SMB2 requests.
86
+ #
87
+ # @param [Symbol] method_name The method name to forward the request to
88
+ # @param [RubySMB::GenericPacket] request The request packet to be processed
89
+ # @return [RubySMB::GenericPacket]
90
+ def share_io(method_name, request)
91
+ @provider.hooks.each do |hook|
92
+ next unless hook.request_class == request.class && hook.location == :before
93
+
94
+ request = hook.callback.call(@session, request) || request
95
+ end
96
+
97
+ response = send(method_name, request)
98
+
99
+ @provider.hooks.each do |hook|
100
+ next unless hook.request_class == request.class && hook.location == :after
101
+
102
+ response = hook.callback.call(@session, request, response) || response
103
+ end
104
+
105
+ response
106
+ end
107
+
83
108
  # The underlying share provider that this is a processor for.
84
109
  # @!attribute [r] provider
85
110
  # @return [RubySMB::Server::Share::Provider::Base]
@@ -14,9 +14,9 @@ module RubySMB
14
14
  private_constant :HASH_METHODS
15
15
 
16
16
  # @param [String] name The name of this share.
17
- def initialize(name)
17
+ def initialize(name, hooks: nil)
18
18
  @vfs = {}
19
- super(name, add(VirtualPathname.new(self, File::SEPARATOR)))
19
+ super(name, add(VirtualPathname.new(self, File::SEPARATOR)), hooks: hooks)
20
20
  end
21
21
 
22
22
  # Add a dynamic file to the virtual file system. A dynamic file is one whose contents are generated by the
@@ -86,7 +86,7 @@ module RubySMB
86
86
  end
87
87
 
88
88
  def new_processor(server_client, session)
89
- scoped_virtual_disk = self.class.new(@name)
89
+ scoped_virtual_disk = self.class.new(@name, hooks: @hooks)
90
90
  @vfs.each_value do |path|
91
91
  path = path.dup
92
92
  path.virtual_disk = scoped_virtual_disk if path.is_a?(VirtualPathname)
@@ -6,9 +6,51 @@ module RubySMB
6
6
  # type and name. It is shared across all client connections and
7
7
  # sessions.
8
8
  class Base
9
+ Hook = Struct.new(:request_class, :location, :callback)
10
+
9
11
  # @param [String] name The name of this share.
10
- def initialize(name)
12
+ def initialize(name, hooks: nil)
11
13
  @name = name
14
+ @hooks = hooks || []
15
+ end
16
+
17
+ # Add a hook to be called when the specified request class is processed. Any hook that was previously
18
+ # installed for the request class and location will be removed. A hook installed with a location of :before
19
+ # will be called with the session and request as the only two arguments. The return value, if provided, will
20
+ # replace the request that is to be processed. A hook installed with a location of :after will be called with
21
+ # the session, request and response as the only three arguments. The return value, if provided, will replace
22
+ # the response that is to be sent to the client.
23
+ #
24
+ # @param [RubySMB::GenericPacket] request_class The request class to register the hook for.
25
+ # @param [Proc] callback The routine to be executed when the request class is being processed.
26
+ # @param [Symbol] location When the callback should be invoked. Must be either :before or :after.
27
+ def add_hook(request_class, callback: nil, location: :before, &block)
28
+ unless %i[ before after ].include?(location)
29
+ raise ArgumentError, 'the location argument must be :before or :after'
30
+ end
31
+
32
+ unless callback.nil? ^ block.nil?
33
+ raise ArgumentError, 'either a callback or a block must be specified'
34
+ end
35
+
36
+ # Remove any hooks that were previously installed, this enforces that only one hook can be present at a time
37
+ # for any particular request class and location combination.
38
+ remove_hook(request_class, location: location)
39
+ @hooks << Hook.new(request_class, location, callback || block)
40
+
41
+ nil
42
+ end
43
+
44
+ # Remove a hook for the specified request class.
45
+ #
46
+ # @param [RubySMB::GenericPacket] request_class The request class to register the hook for.
47
+ # @param [Symbol] location When the callback should be invoked.
48
+ def remove_hook(request_class, location: :before)
49
+ @hooks.filter! do |hook|
50
+ hook.request_class == request_class && hook.location == location
51
+ end
52
+
53
+ nil
12
54
  end
13
55
 
14
56
  # Create a new, session-specific processor instance for this share.
@@ -28,6 +70,11 @@ module RubySMB
28
70
  # @!attribute [r] name
29
71
  # @return [String]
30
72
  attr_accessor :name
73
+
74
+ # The hooks installed for this share.
75
+ # @!attribute [r] hooks
76
+ # @return [Array]
77
+ attr_accessor :hooks
31
78
  end
32
79
  end
33
80
  end
@@ -35,7 +35,7 @@ module RubySMB
35
35
  end
36
36
 
37
37
  uint64 :allocation_size, label: 'Allocation Size'
38
- smb_ext_file_attributes :ext_file_attributes, label: 'Extented File Attributes'
38
+ smb_ext_file_attributes :ext_file_attributes, label: 'Extended File Attributes'
39
39
  share_access :share_access, label: 'Share Access'
40
40
  # The following constants are defined in RubySMB::Dispositions
41
41
  uint32 :create_disposition, label: 'Create Disposition'
@@ -51,8 +51,11 @@ module RubySMB
51
51
  def calc_buffer_size
52
52
  align = 8
53
53
  size = 0
54
- size += name_length + ((align - name_length % align) % align)
55
- size += data_length + ((align - data_length % align) % align)
54
+ size += name_length
55
+ size += ((align - size % align) % align) if name_offset < data_offset
56
+ size += data_length
57
+ size += ((align - size % align) % align) if data_offset < name_offset
58
+ size += ((align - size % align) % align) if next_offset != 0
56
59
  size
57
60
  end
58
61
 
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.2.6'.freeze
2
+ VERSION = '3.2.8'.freeze
3
3
  end
@@ -8,6 +8,7 @@ RSpec.describe RubySMB::SMB2::CreateContext::CreateContextRequest do
8
8
  it { is_expected.to respond_to :name_length }
9
9
  it { is_expected.to respond_to :data_offset }
10
10
  it { is_expected.to respond_to :data_length }
11
+ it { is_expected.to respond_to :buffer }
11
12
  it { is_expected.to respond_to :name }
12
13
  it { is_expected.to respond_to :data }
13
14
 
@@ -39,4 +40,38 @@ RSpec.describe RubySMB::SMB2::CreateContext::CreateContextRequest do
39
40
  expect(struct.data_offset).to eq 0
40
41
  end
41
42
  end
43
+
44
+ context 'when reading a packet with extra padding' do
45
+ # :name_offset=>120,
46
+ # :name_length=>14,
47
+ # :contexts_offset=>136,
48
+ # :contexts_length=>60,
49
+ # :bytes_remaining=>76,
50
+ # :buffer=> "t\x00e\x00s\x00t\x00.\x00r\x00b\x00\x00\x00\x00\x00\x00[...SNIP...]"
51
+ let(:raw_data) {
52
+ "\x00\x00\x00\x00\x10\x00\x04\x00\x00\x00\x18\x00\x24\x00\x00\x00\x44\x48\x32\x43\x00\x00"\
53
+ "\x00\x00\x04\xfa\xb6\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x43\xe0\x35"\
54
+ "\x5c\x6e\xee\x11\xb8\xbb\x00\x0c\x29\xc1\x13\xd0\x00\x00\x00\x00".b
55
+ }
56
+
57
+ it 'reads without error' do
58
+ expect { described_class.read(raw_data) }.to_not raise_error
59
+ end
60
+
61
+ context 'when getting #name and #data' do
62
+ let(:create_request_packet) { described_class.read(raw_data) }
63
+
64
+ it 'gets the expected #name value' do
65
+ create_request_packet.name.read_now!
66
+ expect(create_request_packet.name).to eq 'DH2C'
67
+ end
68
+
69
+ it 'gets the expected #data value' do
70
+ create_request_packet.data.read_now!
71
+ expected_data = "\x04\xfa\xb6\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x43"\
72
+ "\xe0\x35\x5c\x6e\xee\x11\xb8\xbb\x00\x0c\x29\xc1\x13\xd0\x00\x00\x00\x00".b
73
+ expect(create_request_packet.data).to eq expected_data
74
+ end
75
+ end
76
+ end
42
77
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.6
4
+ version: 3.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -14,90 +14,31 @@ bindir: bin
14
14
  cert_chain:
15
15
  - |
16
16
  -----BEGIN CERTIFICATE-----
17
- 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
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
19
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
37
40
  -----END CERTIFICATE-----
38
- - |
39
- -----BEGIN CERTIFICATE-----
40
- MIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1U0O1b5VQCDANBgkqhkiG9w0BAQsFADBl
41
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
42
- d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
43
- b3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgxMDIyMTIwMDAwWjByMQswCQYDVQQG
44
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
45
- cnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgQ29kZSBT
46
- aWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+NOzHH8O
47
- Ea9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid2zLXcep2nQUut4/6kkPApfmJ1DcZ17aq
48
- 8JyGpdglrA55KDp+6dFn08b7KSfH03sjlOSRI5aQd4L5oYQjZhJUM1B0sSgmuyRp
49
- wsJS8hRniolF1C2ho+mILCCVrhxKhwjfDPXiTWAYvqrEsq5wMWYzcT6scKKrzn/p
50
- fMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzLfnQ5Ng2Q7+S1TqSp6moKq4TzrGdOtcT3
51
- jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR93O8vYWxYoNzQYIH5DiLanMg0A9kczye
52
- n6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV
53
- HQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMweQYIKwYBBQUHAQEEbTBr
54
- MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUH
55
- MAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
56
- RFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2lj
57
- ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6
58
- Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmww
59
- TwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
60
- d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYEFFrEuXsq
61
- CqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgP
62
- MA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1aJLPzItEVyCx8JSl2qB1dHC06GsTvMGHX
63
- fgtg/cM9D8Svi/3vKt8gVTew4fbRknUPUbRupY5a4l4kgU4QpO4/cY5jDhNLrddf
64
- RHnzNhQGivecRk5c/5CxGwcOkRX7uq+1UcKNJK4kxscnKqEpKBo6cSgCPC6Ro8Al
65
- EeKcFEehemhor5unXCBc2XGxDI+7qPjFEmifz0DLQESlE/DmZAwlCEIysjaKJAL+
66
- L3J+HNdJRZboWR3p+nRka7LrZkPas7CM1ekN3fYBIM6ZMWM9CBoYs4GbT8aTEAb8
67
- B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhsRDKyZqHnGKSaZFHv
68
- -----END CERTIFICATE-----
69
- - |
70
- -----BEGIN CERTIFICATE-----
71
- MIIFIzCCBAugAwIBAgIQCMePMbkSxvnPeJhYXIfaxzANBgkqhkiG9w0BAQsFADBy
72
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
73
- d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQg
74
- SUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMTAwNzAwMDAwMFoXDTIzMTEwNjEyMDAw
75
- MFowYDELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNV
76
- BAcTBkJvc3RvbjETMBEGA1UEChMKUmFwaWQ3IExMQzETMBEGA1UEAxMKUmFwaWQ3
77
- IExMQzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNTz4zvAy7h/vQp
78
- 4dr1txXHlABAagkwYYwTMCtHs5PXsJITx/5SAjx5swuaLfze5kPBNF2YImvFlOXY
79
- WaB+0PsOnXnaARsDZU683xFlj8izU6IN6VrAHzDLKFBzruJENrOJD/ikbEtbjO/q
80
- gFbmS9J9v5ohG/pcRSS0t4ZPAwymf8eCp6QsvOKK/Aymp1RhlRaP8N6N5CIpkhz1
81
- 9p968iCE+DjOXVYxcWE+jE/7uB1dbgrXykNBujMSS3GULOvVEY28n6NCmrPlo23g
82
- yRjYVJ2Vy14nBqnxDZ/yRIfWRVjWoT9TsAEbe9gY29oDpSCSs4wSmLQd5zGCpZ9h
83
- r0HDFB8CAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZl
84
- dQ5YMB0GA1UdDgQWBBTLBL7DTwumVEKtdCdpHVYMXOFeDzAOBgNVHQ8BAf8EBAMC
85
- B4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDov
86
- L2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGG
87
- L2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3Js
88
- MEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
89
- d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYw
90
- JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcw
91
- AoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3Vy
92
- ZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEL
93
- BQADggEBAN+GL5/myPWg7oH4mVrG7/OhXF1MoYQF0ddaNiqaweEHMuKJBQCVZRbL
94
- 37HojoKXXv2yyRJBCeTB+ojrxX+5PdLVZa0ss7toWzJ2A1poPXZ1eZvm5xeFD32z
95
- YQaTmmNWNI3PCDTyJ2PXUc+bDiNNwcZ7yc5o78UNRvp9Jxghya17Q76c9Ov9wvnv
96
- dxxQKWGOQy0m4fBrkyjAyH9Djjn81RbQrqYgPuhd5nD0HjN3VUQLhQbIJrk9TVs0
97
- EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
98
- 9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
99
- -----END CERTIFICATE-----
100
- date: 2023-10-25 00:00:00.000000000 Z
41
+ date: 2023-11-13 00:00:00.000000000 Z
101
42
  dependencies:
102
43
  - !ruby/object:Gem::Dependency
103
44
  name: redcarpet
metadata.gz.sig CHANGED
Binary file