Class: Rex::Proto::Kerberos::Pac::Krb5Pac

Inherits:
BinData::Record
  • Object
show all
Defined in:
lib/rex/proto/kerberos/pac/krb5_pac.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#c_buffersInteger

Returns:

  • (Integer)


867
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 867

uint32 :c_buffers, asserted_value: -> { pac_info_buffers.length }

#pac_info_buffersArray<Krb5PacInfoBuffer>

Returns:



875
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 875

array :pac_info_buffers, type: :krb5_pac_info_buffer, initial_length: :c_buffers

#versionInteger (readonly)

Returns:

  • (Integer)


871
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 871

uint32 :version, asserted_value: 0x00000000

Instance Method Details

#assign(val) ⇒ Object



877
878
879
880
881
882
883
884
885
886
887
888
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 877

def assign(val)
  case val
  when Hash
    pac_infos = val[:pac_elements].map do |pac_element|
      { ul_type: pac_element.ul_type, buffer: { pac_element: pac_element } }
    end
    new_val = val.merge(pac_info_buffers: pac_infos)
    super(new_val)
  else
    super
  end
end

#calculate_checksum(signature_type, key, data) ⇒ Object



953
954
955
956
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 953

def calculate_checksum(signature_type, key, data)
  checksummer = Rex::Proto::Kerberos::Crypto::Checksum.from_checksum_type(signature_type)
  checksummer.checksum(key, Rex::Proto::Kerberos::Crypto::KeyUsage::KERB_NON_KERB_CKSUM_SALT, data)
end

#calculate_checksums!(service_key: nil, krbtgt_key: nil) ⇒ Object

Parameters:

  • service_key (String) (defaults to: nil)

    Service key to calculate the server checksum

  • krbtgt_key (String) (defaults to: nil)

    key to calculate priv server (KDC) and full checksums with, if not specified ‘service_key` is used

Raises:



896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 896

def calculate_checksums!(service_key: nil, krbtgt_key: nil)
  server_checksum = nil
  priv_server_checksum = nil
  full_pac_checksum = nil
  pac_info_buffers.each do |info_buffer|
    pac_element = info_buffer.buffer.pac_element
    case pac_element.ul_type
    when Krb5PacElementType::SERVER_CHECKSUM
      server_checksum = pac_element
    when Krb5PacElementType::PRIVILEGE_SERVER_CHECKSUM
      priv_server_checksum = pac_element
    when Krb5PacElementType::FULL_PAC_CHECKSUM
      full_pac_checksum = pac_element
    else
      next
    end
  end

  missing_checksums = []
  missing_checksums << Krb5PacElementType::SERVER_CHECKSUM if server_checksum.nil?
  missing_checksums << Krb5PacElementType::PRIVILEGE_SERVER_CHECKSUM if priv_server_checksum.nil?
  raise Rex::Proto::Kerberos::Pac::Error::MissingInfoBuffer.new(ul_types: missing_checksums) unless missing_checksums.empty?

  if krbtgt_key.nil?
    krbtgt_key = service_key
  end

  # https://bugzilla.samba.org/show_bug.cgi?id=15231
  # https://i.blackhat.com/EU-22/Thursday-Briefings/EU-22-Tervoort-Breaking-Kerberos-RC4-Cipher-and-Spoofing-Windows-PACs-wp.pdf
  if full_pac_checksum
    full_pac_checksum.signature = calculate_checksum(full_pac_checksum.signature_type, krbtgt_key, to_binary_s)
  end

  server_checksum.signature = calculate_checksum(server_checksum.signature_type, service_key, to_binary_s)

  priv_server_checksum.signature = calculate_checksum(priv_server_checksum.signature_type, krbtgt_key, server_checksum.signature)
end

#calculate_offsets!Object

Calculates the offsets for pac_elements if they haven’t yet been set



935
936
937
938
939
940
941
942
943
944
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 935

def calculate_offsets!
  offset = pac_info_buffers.abs_offset + pac_info_buffers.num_bytes
  pac_info_buffers.each do |pac_info|
    next unless pac_info.offset == 0

    pac_info.offset = offset
    offset += pac_info.cb_buffer_size
    offset += num_bytes_to_align(offset)
  end
end

#sign!(service_key: nil, krbtgt_key: nil) ⇒ Object

Call this when you are done setting fields in the object in order to finalise the data



948
949
950
951
# File 'lib/rex/proto/kerberos/pac/krb5_pac.rb', line 948

def sign!(service_key: nil, krbtgt_key: nil)
  calculate_offsets!
  calculate_checksums!(service_key: service_key, krbtgt_key: krbtgt_key)
end