Module: RubySMB::Client::Signing

Included in:
RubySMB::Client
Defined in:
lib/ruby_smb/client/signing.rb

Overview

Contains the methods for handling packet signing

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#session_keyString

Returns:

  • (String)


8
9
10
# File 'lib/ruby_smb/client/signing.rb', line 8

def session_key
  @session_key
end

Instance Method Details

#smb1_sign(packet) ⇒ RubySMB::GenericPacket

Take an SMB1 packet and checks to see if it should be signed. If signing is enabled and we have a session key already, then it will sign the packet appropriately.

Parameters:

Returns:



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ruby_smb/client/signing.rb', line 16

def smb1_sign(packet)
  if signing_required && !session_key.empty?
    # Pack the Sequence counter into a int64le
    packed_sequence_counter = [sequence_counter].pack('Q<')
    packet.smb_header.security_features = packed_sequence_counter
    signature = OpenSSL::Digest::MD5.digest(session_key + packet.to_binary_s)[0, 8]
    packet.smb_header.security_features = signature
    self.sequence_counter += 1
  end
  packet
end

#smb2_sign(packet) ⇒ RubySMB::GenericPacket

Take an SMB2 packet and checks to see if it should be signed. If signing is enabled and we have a session key already, then it will sign the packet appropriately.

Parameters:

Returns:



34
35
36
37
38
39
40
41
42
# File 'lib/ruby_smb/client/signing.rb', line 34

def smb2_sign(packet)
  if signing_required && !session_key.empty?
    packet.smb2_header.flags.signed = 1
    packet.smb2_header.signature = "\x00" * 16
    hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, session_key, packet.to_binary_s)
    packet.smb2_header.signature = hmac[0, 16]
  end
  packet
end

#smb3_sign(packet) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ruby_smb/client/signing.rb', line 44

def smb3_sign(packet)
  if !session_key.empty? && (signing_required || packet.is_a?(RubySMB::SMB2::Packet::TreeConnectRequest))
    case @dialect
    when '0x0300', '0x0302'
      signing_key = RubySMB::Crypto::KDF.counter_mode(@session_key, "SMB2AESCMAC\x00", "SmbSign\x00")
    when '0x0311'
      signing_key = RubySMB::Crypto::KDF.counter_mode(@session_key, "SMBSigningKey\x00", @preauth_integrity_hash_value)
    else
      raise RubySMB::Error::SigningError.new('Dialect is incompatible with SMBv3 signing')
    end

    packet.smb2_header.flags.signed = 1
    packet.smb2_header.signature = "\x00" * 16
    hmac = OpenSSL::CMAC.digest('AES', signing_key, packet.to_binary_s)
    packet.smb2_header.signature = hmac[0, 16]
  end
  packet
end