Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/msf/core/exploit/remote/kerberos/client.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: binary -*-

require 'msf/core/opt_timedelta'
require 'rex/proto/gss/kerberos_token'
require 'rex/proto/kerberos/kerberos_logger_subscriber'

module Msf
Expand All @@ -20,9 +21,9 @@ module Client
include Msf::Exploit::Remote::CertificateTrace

# https://datatracker.ietf.org/doc/html/rfc4121#section-4.1
TOK_ID_KRB_AP_REQ = "\x01\x00"
TOK_ID_KRB_AP_REP = "\x02\x00"
TOK_ID_KRB_ERROR = "\x03\x00"
TOK_ID_KRB_AP_REQ = Rex::Proto::Gss::KerberosToken::TOK_ID_KRB_AP_REQ
TOK_ID_KRB_AP_REP = Rex::Proto::Gss::KerberosToken::TOK_ID_KRB_AP_REP
TOK_ID_KRB_ERROR = Rex::Proto::Gss::KerberosToken::TOK_ID_KRB_ERROR

# https://datatracker.ietf.org/doc/html/rfc4178#section-4.2.2
NEG_TOKEN_ACCEPT_COMPLETED = 0
Expand All @@ -48,7 +49,7 @@ def initialize(info = {})
register_advanced_options(
[
OptTimedelta.new('KrbClockSkew', [true, 'Adjust Kerberos client clock by this offset (e.g. 90s, -5m, 1h)', '0s']),
OptEnum.new('KerberosTicketTrace', [false, 'Kerberos ticket trace mode', 'off', %w[off metadata ticket full]]),
OptEnum.new('KerberosTicketTrace', [false, 'Kerberos protocol trace mode', 'off', %w[off metadata ticket full]]),
OptString.new('KerberosTicketTraceColors', [false, 'Kerberos request and response colors for KerberosTicketTrace (unset to disable)', 'red/blu'])
], self.class
)
Expand Down
41 changes: 17 additions & 24 deletions lib/msf/core/exploit/remote/kerberos/client/ap_request.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# -*- coding: binary -*-

require 'rex/proto/gss/kerberos_token'

module Msf
class Exploit
class Remote
module Kerberos
module Client
# Helpers for constructing and wrapping Kerberos AP-REQ messages.
module ApRequest
# https://datatracker.ietf.org/doc/html/rfc4120#section-5.5.1
AP_USE_SESSION_KEY = 0x40000000
Expand All @@ -28,33 +31,23 @@ def build_service_ap_request(opts = {})
ap_req
end

def encode_gss_kerberos_ap_request(ap_request_asn1)
ap_request_mech = wrap_pseudo_asn1(
::Rex::Proto::Gss::OID_KERBEROS_5,
TOK_ID_KRB_AP_REQ + ap_request_asn1.to_der
# @param ap_request_asn1 [OpenSSL::ASN1::ASN1Data] the ASN.1 AP-REQ
# @param ap_request_der [String, nil] a pre-encoded AP-REQ
# @return [String] a GSS-Kerberos token
# @see https://datatracker.ietf.org/doc/html/rfc1964#section-1.1.1
def encode_gss_kerberos_ap_request(ap_request_asn1, ap_request_der: nil)
Rex::Proto::Gss::KerberosToken.build_gss_ap_req(
ap_request_der || ap_request_asn1.to_der
)
end

# @param ap_request_asn1 [Object] The ASN1 KRB_AP_REQ as defined in https://datatracker.ietf.org/doc/html/rfc1964#section-1.1.1
# @return [String] SPNEGO GSS Blob
def encode_gss_spnego_ap_request(ap_request_asn1)
ap_request_mech = encode_gss_kerberos_ap_request(ap_request_asn1)

OpenSSL::ASN1::ASN1Data.new([
::Rex::Proto::Gss::OID_SPNEGO,
OpenSSL::ASN1::ASN1Data.new([
OpenSSL::ASN1::Sequence.new([
OpenSSL::ASN1::ASN1Data.new([
OpenSSL::ASN1::Sequence.new([
::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5
])
], 0, :CONTEXT_SPECIFIC),
OpenSSL::ASN1::ASN1Data.new([
OpenSSL::ASN1::OctetString.new(ap_request_mech)
], 2, :CONTEXT_SPECIFIC)
])
], 0, :CONTEXT_SPECIFIC)
], 0, :APPLICATION).to_der
# @param ap_request_asn1 [OpenSSL::ASN1::ASN1Data] the ASN.1 KRB_AP_REQ defined in RFC 1964 section 1.1.1
# @param ap_request_mech [String, nil] a pre-encoded GSS-Kerberos AP-REQ token
# @return [String] a SPNEGO GSS blob
# @see https://datatracker.ietf.org/doc/html/rfc4178#section-4.2.1
def encode_gss_spnego_ap_request(ap_request_asn1, ap_request_mech: nil)
ap_request_mech ||= encode_gss_kerberos_ap_request(ap_request_asn1)
Rex::Proto::Gss::KerberosToken.build_spnego_init(ap_request_mech)
end
end
end
Expand Down
Loading
Loading