Module: Msf::Exploit::Remote::Kerberos::Client::TgsRequest

Included in:
Msf::Exploit::Remote::Kerberos::Client
Defined in:
lib/msf/core/exploit/kerberos/client/tgs_request.rb

Instance Method Summary collapse

Instance Method Details

#build_ap_req(opts = {}) ⇒ Rex::Proto::Kerberos::Model::EncryptionKey

Builds a KRB_AP_REQ message

Parameters:

Options Hash (opts):

Returns:

Raises:

  • (RuntimeError)

    if ticket option isn't provided

See Also:


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 128

def build_ap_req(opts = {})
  pvno = opts[:pvno] || Rex::Proto::Kerberos::Model::VERSION
  msg_type = opts[:msg_type] || Rex::Proto::Kerberos::Model::AP_REQ
  options = opts[:ap_req_options] || 0
  ticket = opts[:ticket]
  authenticator = opts[:authenticator] || build_authenticator(opts)
  session_key = opts[:session_key] || build_subkey(opts)

  if ticket.nil?
    raise ::RuntimeError, 'Building a AP-REQ without ticket not supported'
  end

  enc_authenticator = Rex::Proto::Kerberos::Model::EncryptedData.new(
    etype: session_key.type,
    cipher: authenticator.encrypt(session_key.type, session_key.value)
  )

  ap_req = Rex::Proto::Kerberos::Model::ApReq.new(
    pvno: pvno,
    msg_type: msg_type,
    options: options,
    ticket: ticket,
    authenticator: enc_authenticator
  )

  ap_req
end

#build_authenticator(opts = {}) ⇒ Rex::Proto::Kerberos::Model::Authenticator

Builds a kerberos authenticator for a TGS request


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 170

def build_authenticator(opts = {})
  cname = opts[:cname] || build_client_name(opts)
  realm = opts[:realm] || ''
  ctime = opts[:ctime] || Time.now
  cusec = opts[:cusec] || ctime.usec
  checksum = opts[:checksum] || build_tgs_body_checksum(opts)
  subkey = opts[:subkey] || build_subkey(opts)

  authenticator = Rex::Proto::Kerberos::Model::Authenticator.new(
    vno: 5,
    crealm: realm,
    cname: cname,
    checksum: checksum,
    cusec: cusec,
    ctime: ctime,
    subkey: subkey
  )

  authenticator
end

#build_enc_auth_data(opts = {}) ⇒ Rex::Proto::Kerberos::Model::EncryptedData

Builds the encrypted TGS authorization data


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 95

def build_enc_auth_data(opts = {})
  auth_data = opts[:auth_data]

  if auth_data.nil?
    raise ::RuntimeError, 'auth_data option required on #build_enc_auth_data'
  end

  subkey = opts[:subkey] || build_subkey(opts)

  encrypted = auth_data.encrypt(subkey.type, subkey.value)

  e_data = Rex::Proto::Kerberos::Model::EncryptedData.new(
    etype: subkey.type,
    cipher: encrypted
  )

  e_data
end

#build_subkey(opts = {}) ⇒ Rex::Proto::Kerberos::Model::EncryptionKey

Builds an encryption key to protect the data sent in the TGS request.

Parameters:

  • opts (Hash{Symbol => <Integer, String>}) (defaults to: {})

Options Hash (opts):

  • :subkey_type (Integer)
  • :subkey_value (String)

Returns:

See Also:


198
199
200
201
202
203
204
205
206
207
208
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 198

def build_subkey(opts={})
  subkey_type = opts[:subkey_type] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
  subkey_value = opts[:subkey_value] || Rex::Text.rand_text(16)

  subkey = Rex::Proto::Kerberos::Model::EncryptionKey.new(
    type: subkey_type,
    value: subkey_value
  )

  subkey
end

#build_tgs_body_checksum(opts = {}) ⇒ Rex::Proto::Kerberos::Model::Checksum

Builds a Kerberos TGS Request body checksum


262
263
264
265
266
267
268
269
270
271
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 262

def build_tgs_body_checksum(opts = {})
  body = opts[:body] || build_tgs_request_body(opts)
  checksum_body = body.checksum(Rex::Proto::Kerberos::Crypto::RSA_MD5)
  checksum = Rex::Proto::Kerberos::Model::Checksum.new(
    type: 7,
    checksum: checksum_body
  )

  checksum
end

#build_tgs_request(opts = {}) ⇒ Rex::Proto::Kerberos::Model::KdcRequest

Builds the encrypted Kerberos TGS request


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 29

def build_tgs_request(opts = {})
  subkey = opts[:subkey] || build_subkey(opts)

  if opts[:enc_auth_data]
    enc_auth_data = opts[:enc_auth_data]
  elsif opts[:auth_data]
    enc_auth_data = build_enc_auth_data(
      auth_data: opts[:auth_data],
      subkey: subkey
    )
  else
    enc_auth_data = nil
  end

  body = build_tgs_request_body(opts.merge(
    enc_auth_data: enc_auth_data
  ))

  checksum = opts[:checksum] || build_tgs_body_checksum(:body => body)

  if opts[:auhtenticator]
    authenticator = opts[:authenticator]
  else
    authenticator = build_authenticator(opts.merge(
      subkey: subkey,
      checksum: checksum
    ))
  end

  if opts[:ap_req]
    ap_req = opts[:ap_req]
  else
    ap_req = build_ap_req(opts.merge(:authenticator => authenticator))
  end

  pa_ap_req = Rex::Proto::Kerberos::Model::PreAuthData.new(
    type: Rex::Proto::Kerberos::Model::PA_TGS_REQ,
    value: ap_req.encode
  )

  pa_data = []
  pa_data.push(pa_ap_req)
  if opts[:pa_data]
    opts[:pa_data].each { |pa| pa_data.push(pa) }
  end

  request = Rex::Proto::Kerberos::Model::KdcRequest.new(
    pvno: 5,
    msg_type: Rex::Proto::Kerberos::Model::TGS_REQ,
    pa_data: pa_data,
    req_body: body
  )

  request
end

#build_tgs_request_body(opts = {}) ⇒ Rex::Proto::Kerberos::Model::KdcRequestBody

Builds a kerberos TGS request body

Parameters:

Options Hash (opts):

Returns:

See Also:


227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/msf/core/exploit/kerberos/client/tgs_request.rb', line 227

def build_tgs_request_body(opts = {})
  options = opts[:options] || 0x50800000 # Forwardable, Proxiable, Renewable
  from = opts[:from] || Time.utc('1970-01-01-01 00:00:00')
  till = opts[:till] || Time.utc('1970-01-01-01 00:00:00')
  rtime = opts[:rtime] || Time.utc('1970-01-01-01 00:00:00')
  nonce = opts[:nonce] || Rex::Text.rand_text_numeric(6).to_i
  etype = opts[:etype] || [Rex::Proto::Kerberos::Crypto::RC4_HMAC]
  cname = opts[:cname] || build_client_name(opts)
  realm = opts[:realm] || ''
  sname = opts[:sname] || build_server_name(opts)
  enc_auth_data = opts[:enc_auth_data] || nil

  body = Rex::Proto::Kerberos::Model::KdcRequestBody.new(
    options: options,
    cname: cname,
    realm: realm,
    sname: sname,
    from: from,
    till: till,
    rtime: rtime,
    nonce: nonce,
    etype: etype,
    enc_auth_data: enc_auth_data
  )

  body
end