Fix specs to pass again
parent
fa9a33cae8
commit
8057b3edae
|
@ -1,137 +1,143 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
require 'msf/core/exploit/kerberos/client/base'
|
class Remote
|
||||||
require 'msf/core/exploit/kerberos/client/as_request'
|
module Kerberos
|
||||||
require 'msf/core/exploit/kerberos/client/as_response'
|
module Client
|
||||||
require 'msf/core/exploit/kerberos/client/tgs_request'
|
require 'msf/core/exploit/kerberos/client/base'
|
||||||
require 'msf/core/exploit/kerberos/client/tgs_response'
|
require 'msf/core/exploit/kerberos/client/as_request'
|
||||||
require 'msf/core/exploit/kerberos/client/pac'
|
require 'msf/core/exploit/kerberos/client/as_response'
|
||||||
require 'msf/core/exploit/kerberos/client/cache_credential'
|
require 'msf/core/exploit/kerberos/client/tgs_request'
|
||||||
|
require 'msf/core/exploit/kerberos/client/tgs_response'
|
||||||
|
require 'msf/core/exploit/kerberos/client/pac'
|
||||||
|
require 'msf/core/exploit/kerberos/client/cache_credential'
|
||||||
|
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::Base
|
include Msf::Exploit::Remote::Kerberos::Client::Base
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::AsRequest
|
include Msf::Exploit::Remote::Kerberos::Client::AsRequest
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::AsResponse
|
include Msf::Exploit::Remote::Kerberos::Client::AsResponse
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::TgsRequest
|
include Msf::Exploit::Remote::Kerberos::Client::TgsRequest
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::TgsResponse
|
include Msf::Exploit::Remote::Kerberos::Client::TgsResponse
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::Pac
|
include Msf::Exploit::Remote::Kerberos::Client::Pac
|
||||||
include Msf::Exploit::Remote::Kerberos::Client::CacheCredential
|
include Msf::Exploit::Remote::Kerberos::Client::CacheCredential
|
||||||
|
|
||||||
# @!attribute client
|
# @!attribute client
|
||||||
# @return [Rex::Proto::Kerberos::Client] The kerberos client
|
# @return [Rex::Proto::Kerberos::Client] The kerberos client
|
||||||
attr_accessor :client
|
attr_accessor :client
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super
|
super
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
Opt::RHOST,
|
Opt::RHOST,
|
||||||
Opt::RPORT(88),
|
Opt::RPORT(88),
|
||||||
OptInt.new('Timeout', [true, 'The TCP timeout to establish connection and read data', 10])
|
OptInt.new('Timeout', [true, 'The TCP timeout to establish connection and read data', 10])
|
||||||
], self.class
|
], self.class
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the target host
|
# Returns the target host
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def rhost
|
def rhost
|
||||||
datastore['RHOST']
|
datastore['RHOST']
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the remote port
|
# Returns the remote port
|
||||||
#
|
#
|
||||||
# @return [Fixnum]
|
# @return [Fixnum]
|
||||||
def rport
|
def rport
|
||||||
datastore['RPORT']
|
datastore['RPORT']
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the TCP timeout
|
# Returns the TCP timeout
|
||||||
#
|
#
|
||||||
# @return [Fixnum]
|
# @return [Fixnum]
|
||||||
def timeout
|
def timeout
|
||||||
datastore['Timeout']
|
datastore['Timeout']
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the kdc peer
|
# Returns the kdc peer
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def peer
|
def peer
|
||||||
"#{rhost}:#{rport}"
|
"#{rhost}:#{rport}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a kerberos connection
|
# Creates a kerberos connection
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
||||||
# @option opts [String] :rhost
|
# @option opts [String] :rhost
|
||||||
# @option opts [<String, Fixnum>] :rport
|
# @option opts [<String, Fixnum>] :rport
|
||||||
# @return [Rex::Proto::Kerberos::Client]
|
# @return [Rex::Proto::Kerberos::Client]
|
||||||
def connect(opts={})
|
def connect(opts={})
|
||||||
kerb_client = Rex::Proto::Kerberos::Client.new(
|
kerb_client = Rex::Proto::Kerberos::Client.new(
|
||||||
host: opts[:rhost] || rhost,
|
host: opts[:rhost] || rhost,
|
||||||
port: (opts[:rport] || rport).to_i,
|
port: (opts[:rport] || rport).to_i,
|
||||||
timeout: (opts[:timeout] || timeout).to_i,
|
timeout: (opts[:timeout] || timeout).to_i,
|
||||||
context:
|
context:
|
||||||
{
|
{
|
||||||
'Msf' => framework,
|
'Msf' => framework,
|
||||||
'MsfExploit' => self,
|
'MsfExploit' => self,
|
||||||
},
|
},
|
||||||
protocol: 'tcp'
|
protocol: 'tcp'
|
||||||
)
|
)
|
||||||
|
|
||||||
disconnect if client
|
disconnect if client
|
||||||
self.client = kerb_client
|
self.client = kerb_client
|
||||||
|
|
||||||
kerb_client
|
kerb_client
|
||||||
end
|
end
|
||||||
|
|
||||||
# Disconnects the Kerberos client
|
# Disconnects the Kerberos client
|
||||||
#
|
#
|
||||||
# @param kerb_client [Rex::Proto::Kerberos::Client] the client to disconnect
|
# @param kerb_client [Rex::Proto::Kerberos::Client] the client to disconnect
|
||||||
def disconnect(kerb_client = client)
|
def disconnect(kerb_client = client)
|
||||||
kerb_client.close if kerb_client
|
kerb_client.close if kerb_client
|
||||||
|
|
||||||
if kerb_client == client
|
if kerb_client == client
|
||||||
self.client = nil
|
self.client = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs cleanup as necessary, disconnecting the Kerberos client
|
||||||
|
# if it's still established.
|
||||||
|
def cleanup
|
||||||
|
super
|
||||||
|
disconnect
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sends a kerberos AS request and reads the response
|
||||||
|
#
|
||||||
|
# @param opts [Hash]
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::KdcResponse]
|
||||||
|
# @see Msf::Kerberos::Client::AsRequest#build_as_request
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
||||||
|
def send_request_as(opts = {})
|
||||||
|
connect(opts)
|
||||||
|
req = build_as_request(opts)
|
||||||
|
res = client.send_recv(req)
|
||||||
|
disconnect
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sends a kerberos AS request and reads the response
|
||||||
|
#
|
||||||
|
# @param opts [Hash]
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::KdcResponse]
|
||||||
|
# @see Msf::Kerberos::Client::TgsRequest#build_tgs_request
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
||||||
|
def send_request_tgs(opts = {})
|
||||||
|
connect(opts)
|
||||||
|
req = build_tgs_request(opts)
|
||||||
|
res = client.send_recv(req)
|
||||||
|
disconnect
|
||||||
|
res
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Performs cleanup as necessary, disconnecting the Kerberos client
|
|
||||||
# if it's still established.
|
|
||||||
def cleanup
|
|
||||||
super
|
|
||||||
disconnect
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends a kerberos AS request and reads the response
|
|
||||||
#
|
|
||||||
# @param opts [Hash]
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcResponse]
|
|
||||||
# @see Msf::Kerberos::Client::AsRequest#build_as_request
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
|
||||||
def send_request_as(opts = {})
|
|
||||||
connect(opts)
|
|
||||||
req = build_as_request(opts)
|
|
||||||
res = client.send_recv(req)
|
|
||||||
disconnect
|
|
||||||
res
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends a kerberos AS request and reads the response
|
|
||||||
#
|
|
||||||
# @param opts [Hash]
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcResponse]
|
|
||||||
# @see Msf::Kerberos::Client::TgsRequest#build_tgs_request
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
|
||||||
def send_request_tgs(opts = {})
|
|
||||||
connect(opts)
|
|
||||||
req = build_tgs_request(opts)
|
|
||||||
res = client.send_recv(req)
|
|
||||||
disconnect
|
|
||||||
res
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,108 +1,113 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module AsRequest
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module AsRequest
|
||||||
|
# Builds a kerberos AS request
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Array<Rex::Proto::Kerberos::Model::PreAuthData>, Rex::Proto::Kerberos::Model::KdcRequestBody>}]
|
||||||
|
# @option opts [Array<Rex::Proto::Kerberos::Model::PreAuthData>] :pa_data
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::KdcRequestBody] :body
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::KdcRequest]
|
||||||
|
# @see [Rex::Proto::Kerberos::Model::KdcRequest]
|
||||||
|
# @see #build_as_pa_time_stamp
|
||||||
|
# @see #build_as_request_body
|
||||||
|
def build_as_request(opts = {})
|
||||||
|
pa_data = opts[:pa_data] || build_as_pa_time_stamp(opts)
|
||||||
|
body = opts[:body] || build_as_request_body(opts)
|
||||||
|
|
||||||
# Builds a kerberos AS request
|
request = Rex::Proto::Kerberos::Model::KdcRequest.new(
|
||||||
#
|
pvno: 5,
|
||||||
# @param opts [Hash{Symbol => <Array<Rex::Proto::Kerberos::Model::PreAuthData>, Rex::Proto::Kerberos::Model::KdcRequestBody>}]
|
msg_type: Rex::Proto::Kerberos::Model::AS_REQ,
|
||||||
# @option opts [Array<Rex::Proto::Kerberos::Model::PreAuthData>] :pa_data
|
pa_data: pa_data,
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::KdcRequestBody] :body
|
req_body: body
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcRequest]
|
)
|
||||||
# @see [Rex::Proto::Kerberos::Model::KdcRequest]
|
|
||||||
# @see #build_as_pa_time_stamp
|
|
||||||
# @see #build_as_request_body
|
|
||||||
def build_as_request(opts = {})
|
|
||||||
pa_data = opts[:pa_data] || build_as_pa_time_stamp(opts)
|
|
||||||
body = opts[:body] || build_as_request_body(opts)
|
|
||||||
|
|
||||||
request = Rex::Proto::Kerberos::Model::KdcRequest.new(
|
request
|
||||||
pvno: 5,
|
end
|
||||||
msg_type: Rex::Proto::Kerberos::Model::AS_REQ,
|
|
||||||
pa_data: pa_data,
|
|
||||||
req_body: body
|
|
||||||
)
|
|
||||||
|
|
||||||
request
|
# Builds a kerberos PA-ENC-TIMESTAMP pre authenticated structure
|
||||||
end
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Time, Fixnum, String>}]
|
||||||
|
# @option opts [Time] :time_stamp
|
||||||
|
# @option opts [Fixnum] :pausec
|
||||||
|
# @option opts [Fixnum] :etype
|
||||||
|
# @option opts [String] :key
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::PreAuthData]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
||||||
|
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
||||||
|
def build_as_pa_time_stamp(opts = {})
|
||||||
|
time_stamp = opts[:time_stamp] || Time.now
|
||||||
|
pausec = opts[:pausec] || 0
|
||||||
|
etype = opts[:etype] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
|
||||||
|
key = opts[:key] || ''
|
||||||
|
|
||||||
# Builds a kerberos PA-ENC-TIMESTAMP pre authenticated structure
|
pa_time_stamp = Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp.new(
|
||||||
#
|
pa_time_stamp: time_stamp,
|
||||||
# @param opts [Hash{Symbol => <Time, Fixnum, String>}]
|
pausec: pausec
|
||||||
# @option opts [Time] :time_stamp
|
)
|
||||||
# @option opts [Fixnum] :pausec
|
|
||||||
# @option opts [Fixnum] :etype
|
|
||||||
# @option opts [String] :key
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::PreAuthData]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
|
||||||
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
|
||||||
def build_as_pa_time_stamp(opts = {})
|
|
||||||
time_stamp = opts[:time_stamp] || Time.now
|
|
||||||
pausec = opts[:pausec] || 0
|
|
||||||
etype = opts[:etype] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
|
|
||||||
key = opts[:key] || ''
|
|
||||||
|
|
||||||
pa_time_stamp = Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp.new(
|
enc_time_stamp = Rex::Proto::Kerberos::Model::EncryptedData.new(
|
||||||
pa_time_stamp: time_stamp,
|
etype: etype,
|
||||||
pausec: pausec
|
cipher: pa_time_stamp.encrypt(etype, key)
|
||||||
)
|
)
|
||||||
|
|
||||||
enc_time_stamp = Rex::Proto::Kerberos::Model::EncryptedData.new(
|
pa_enc_time_stamp = Rex::Proto::Kerberos::Model::PreAuthData.new(
|
||||||
etype: etype,
|
type: Rex::Proto::Kerberos::Model::PA_ENC_TIMESTAMP,
|
||||||
cipher: pa_time_stamp.encrypt(etype, key)
|
value: enc_time_stamp.encode
|
||||||
)
|
)
|
||||||
|
|
||||||
pa_enc_time_stamp = Rex::Proto::Kerberos::Model::PreAuthData.new(
|
pa_enc_time_stamp
|
||||||
type: Rex::Proto::Kerberos::Model::PA_ENC_TIMESTAMP,
|
end
|
||||||
value: enc_time_stamp.encode
|
|
||||||
)
|
|
||||||
|
|
||||||
pa_enc_time_stamp
|
# Builds a kerberos AS request body
|
||||||
end
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Fixnum, Time, String, Rex::Proto::Kerberos::Model::PrincipalName>}]
|
||||||
|
# @option opts [Fixnum] :options
|
||||||
|
# @option opts [Time] :from
|
||||||
|
# @option opts [Time] :till
|
||||||
|
# @option opts [Time] :rtime
|
||||||
|
# @option opts [Fixnum] :nonce
|
||||||
|
# @option opts [Fixnum] :etype
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
||||||
|
# @option opts [String] :realm
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :sname
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::KdcRequestBody]
|
||||||
|
# @see #build_client_name
|
||||||
|
# @see #build_server_name
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcRequestBody
|
||||||
|
def build_as_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)
|
||||||
|
|
||||||
# Builds a kerberos AS request body
|
body = Rex::Proto::Kerberos::Model::KdcRequestBody.new(
|
||||||
#
|
options: options,
|
||||||
# @param opts [Hash{Symbol => <Fixnum, Time, String, Rex::Proto::Kerberos::Model::PrincipalName>}]
|
cname: cname,
|
||||||
# @option opts [Fixnum] :options
|
realm: realm,
|
||||||
# @option opts [Time] :from
|
sname: sname,
|
||||||
# @option opts [Time] :till
|
from: from,
|
||||||
# @option opts [Time] :rtime
|
till: till,
|
||||||
# @option opts [Fixnum] :nonce
|
rtime: rtime,
|
||||||
# @option opts [Fixnum] :etype
|
nonce: nonce,
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
etype: etype
|
||||||
# @option opts [String] :realm
|
)
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :sname
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcRequestBody]
|
|
||||||
# @see #build_client_name
|
|
||||||
# @see #build_server_name
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcRequestBody
|
|
||||||
def build_as_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)
|
|
||||||
|
|
||||||
body = Rex::Proto::Kerberos::Model::KdcRequestBody.new(
|
body
|
||||||
options: options,
|
end
|
||||||
cname: cname,
|
end
|
||||||
realm: realm,
|
end
|
||||||
sname: sname,
|
|
||||||
from: from,
|
|
||||||
till: till,
|
|
||||||
rtime: rtime,
|
|
||||||
nonce: nonce,
|
|
||||||
etype: etype
|
|
||||||
)
|
|
||||||
|
|
||||||
body
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,43 +1,48 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module AsResponse
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module AsResponse
|
||||||
|
# Extracts the session key from a Kerberos AS Response
|
||||||
|
#
|
||||||
|
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
||||||
|
# @param key [String]
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptedData.decrypt
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
|
def extract_session_key(res, key)
|
||||||
|
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_AS_RESPONSE)
|
||||||
|
enc_kdc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
||||||
|
|
||||||
# Extracts the session key from a Kerberos AS Response
|
enc_kdc_res.key
|
||||||
#
|
end
|
||||||
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
|
||||||
# @param key [String]
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData.decrypt
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
|
||||||
def extract_session_key(res, key)
|
|
||||||
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_AS_RESPONSE)
|
|
||||||
enc_kdc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
|
||||||
|
|
||||||
enc_kdc_res.key
|
# Extracts the logon time from a Kerberos AS Response
|
||||||
end
|
#
|
||||||
|
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
||||||
|
# @param key [String]
|
||||||
|
# @return [Fixnum]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptedData.decrypt
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
||||||
|
def extract_logon_time(res, key)
|
||||||
|
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_AS_RESPONSE)
|
||||||
|
enc_kdc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
||||||
|
|
||||||
# Extracts the logon time from a Kerberos AS Response
|
auth_time = enc_kdc_res.auth_time
|
||||||
#
|
|
||||||
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
|
||||||
# @param key [String]
|
|
||||||
# @return [Fixnum]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcResponse
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData.decrypt
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
|
||||||
def extract_logon_time(res, key)
|
|
||||||
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_AS_RESPONSE)
|
|
||||||
enc_kdc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
|
||||||
|
|
||||||
auth_time = enc_kdc_res.auth_time
|
auth_time.to_i
|
||||||
|
end
|
||||||
auth_time.to_i
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,41 +1,47 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module Base
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module Base
|
||||||
|
|
||||||
# Builds a kerberos Client Name Principal
|
# Builds a kerberos Client Name Principal
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
||||||
# @option opts [String] :client_name the client's name
|
# @option opts [String] :client_name the client's name
|
||||||
# @option opts [Fixnum] :client_type the client's name type
|
# @option opts [Fixnum] :client_type the client's name type
|
||||||
# @return [Rex::Proto::Kerberos::Model::PrincipalName]
|
# @return [Rex::Proto::Kerberos::Model::PrincipalName]
|
||||||
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
||||||
def build_client_name(opts = {})
|
def build_client_name(opts = {})
|
||||||
name = opts[:client_name] || ''
|
name = opts[:client_name] || ''
|
||||||
name_type = opts[:client_type] || Rex::Proto::Kerberos::Model::NT_PRINCIPAL
|
name_type = opts[:client_type] || Rex::Proto::Kerberos::Model::NT_PRINCIPAL
|
||||||
|
|
||||||
Rex::Proto::Kerberos::Model::PrincipalName.new(
|
Rex::Proto::Kerberos::Model::PrincipalName.new(
|
||||||
name_type: name_type,
|
name_type: name_type,
|
||||||
name_string: name.split('/')
|
name_string: name.split('/')
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a kerberos Server Name Principal
|
# Builds a kerberos Server Name Principal
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
||||||
# @option opts [String] :server_name the server's name
|
# @option opts [String] :server_name the server's name
|
||||||
# @option opts [Fixnum] :server_type the server's name type
|
# @option opts [Fixnum] :server_type the server's name type
|
||||||
# @return [Rex::Proto::Kerberos::Model::PrincipalName]
|
# @return [Rex::Proto::Kerberos::Model::PrincipalName]
|
||||||
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
||||||
def build_server_name(opts = {})
|
def build_server_name(opts = {})
|
||||||
name = opts[:server_name] || ''
|
name = opts[:server_name] || ''
|
||||||
name_type = opts[:server_type] || Rex::Proto::Kerberos::Model::NT_PRINCIPAL
|
name_type = opts[:server_type] || Rex::Proto::Kerberos::Model::NT_PRINCIPAL
|
||||||
|
|
||||||
Rex::Proto::Kerberos::Model::PrincipalName.new(
|
Rex::Proto::Kerberos::Model::PrincipalName.new(
|
||||||
name_type: name_type,
|
name_type: name_type,
|
||||||
name_string: name.split('/')
|
name_string: name.split('/')
|
||||||
)
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,145 +1,151 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module CacheCredential
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module CacheCredential
|
||||||
|
|
||||||
# Builds a MIT Credential Cache
|
# Builds a MIT Credential Cache
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => <Fixnum, Array<String>, Rex::Proto::Kerberos::CredentialCache::Principal, Array<Rex::Proto::Kerberos::CredentialCache::Credential>>}]
|
# @param opts [Hash{Symbol => <Fixnum, Array<String>, Rex::Proto::Kerberos::CredentialCache::Principal, Array<Rex::Proto::Kerberos::CredentialCache::Credential>>}]
|
||||||
# @option opts [Fixnum] :version
|
# @option opts [Fixnum] :version
|
||||||
# @option opts [Array<String>] :headers
|
# @option opts [Array<String>] :headers
|
||||||
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] :primary_principal
|
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] :primary_principal
|
||||||
# @option opts [Array<Rex::Proto::Kerberos::CredentialCache::Credential>] :credentials
|
# @option opts [Array<Rex::Proto::Kerberos::CredentialCache::Credential>] :credentials
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::Cache]
|
# @return [Rex::Proto::Kerberos::CredentialCache::Cache]
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::Cache
|
# @see Rex::Proto::Kerberos::CredentialCache::Cache
|
||||||
def create_cache(opts = {})
|
def create_cache(opts = {})
|
||||||
version = opts[:version] || Rex::Proto::Kerberos::CredentialCache::VERSION
|
version = opts[:version] || Rex::Proto::Kerberos::CredentialCache::VERSION
|
||||||
headers = opts[:headers] || [Rex::Proto::Kerberos::CredentialCache::HEADER]
|
headers = opts[:headers] || [Rex::Proto::Kerberos::CredentialCache::HEADER]
|
||||||
primary_principal = opts[:primary_principal] || create_cache_principal(opts)
|
primary_principal = opts[:primary_principal] || create_cache_principal(opts)
|
||||||
credentials = opts[:credentials] || [create_cache_credential(opts)]
|
credentials = opts[:credentials] || [create_cache_credential(opts)]
|
||||||
|
|
||||||
cache = Rex::Proto::Kerberos::CredentialCache::Cache.new(
|
cache = Rex::Proto::Kerberos::CredentialCache::Cache.new(
|
||||||
version: version,
|
version: version,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
primary_principal: primary_principal,
|
primary_principal: primary_principal,
|
||||||
credentials: credentials
|
credentials: credentials
|
||||||
)
|
)
|
||||||
|
|
||||||
cache
|
cache
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a MIT Credential Cache principal
|
# Builds a MIT Credential Cache principal
|
||||||
#
|
#
|
||||||
# @param opts [Hash<{Symbol => <Fixnum, String, Array<String>>}>]
|
# @param opts [Hash<{Symbol => <Fixnum, String, Array<String>>}>]
|
||||||
# @option opts [Fixnum] :name_type
|
# @option opts [Fixnum] :name_type
|
||||||
# @option opts [String] :realm
|
# @option opts [String] :realm
|
||||||
# @option opts [Array<String>] :components
|
# @option opts [Array<String>] :components
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::Principal]
|
# @return [Rex::Proto::Kerberos::CredentialCache::Principal]
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::Principal
|
# @see Rex::Proto::Kerberos::CredentialCache::Principal
|
||||||
def create_cache_principal(opts = {})
|
def create_cache_principal(opts = {})
|
||||||
name_type = opts[:name_type] || 0
|
name_type = opts[:name_type] || 0
|
||||||
realm = opts[:realm] || ''
|
realm = opts[:realm] || ''
|
||||||
components = opts[:components] || ['']
|
components = opts[:components] || ['']
|
||||||
|
|
||||||
principal = Rex::Proto::Kerberos::CredentialCache::Principal.new(
|
principal = Rex::Proto::Kerberos::CredentialCache::Principal.new(
|
||||||
name_type: name_type,
|
name_type: name_type,
|
||||||
realm: realm,
|
realm: realm,
|
||||||
components:components
|
components:components
|
||||||
)
|
)
|
||||||
|
|
||||||
principal
|
principal
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a MIT Credential Cache key block
|
# Builds a MIT Credential Cache key block
|
||||||
#
|
#
|
||||||
# @param opts [Hash<{Symbol => <Fixnum, String>}>]
|
# @param opts [Hash<{Symbol => <Fixnum, String>}>]
|
||||||
# @option opts [Fixnum] :key_type
|
# @option opts [Fixnum] :key_type
|
||||||
# @option opts [Fixnum] :e_type
|
# @option opts [Fixnum] :e_type
|
||||||
# @option opts [String] :key_value
|
# @option opts [String] :key_value
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::KeyBlock]
|
# @return [Rex::Proto::Kerberos::CredentialCache::KeyBlock]
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::KeyBlock
|
# @see Rex::Proto::Kerberos::CredentialCache::KeyBlock
|
||||||
def create_cache_key_block(opts = {})
|
def create_cache_key_block(opts = {})
|
||||||
key_type = opts[:key_type] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
|
key_type = opts[:key_type] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
|
||||||
e_type = opts[:e_type] || 0
|
e_type = opts[:e_type] || 0
|
||||||
key_value = opts[:key_value] || ''
|
key_value = opts[:key_value] || ''
|
||||||
|
|
||||||
key_block = Rex::Proto::Kerberos::CredentialCache::KeyBlock.new(
|
key_block = Rex::Proto::Kerberos::CredentialCache::KeyBlock.new(
|
||||||
key_type: key_type,
|
key_type: key_type,
|
||||||
e_type: e_type,
|
e_type: e_type,
|
||||||
key_value: key_value
|
key_value: key_value
|
||||||
)
|
)
|
||||||
|
|
||||||
key_block
|
key_block
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a times structure linked to a credential in a MIT Credential Cache
|
# Builds a times structure linked to a credential in a MIT Credential Cache
|
||||||
#
|
#
|
||||||
# @param opts [Hash<{Symbol => Fixnum}>]
|
# @param opts [Hash<{Symbol => Fixnum}>]
|
||||||
# @option opts [Fixnum] auth_time
|
# @option opts [Fixnum] auth_time
|
||||||
# @option opts [Fixnum] start_time
|
# @option opts [Fixnum] start_time
|
||||||
# @option opts [Fixnum] end_time
|
# @option opts [Fixnum] end_time
|
||||||
# @option opts [Fixnum] renew_till
|
# @option opts [Fixnum] renew_till
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::Time]
|
# @return [Rex::Proto::Kerberos::CredentialCache::Time]
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::Time
|
# @see Rex::Proto::Kerberos::CredentialCache::Time
|
||||||
def create_cache_times(opts = {})
|
def create_cache_times(opts = {})
|
||||||
auth_time = opts[:auth_time] || 0
|
auth_time = opts[:auth_time] || 0
|
||||||
start_time = opts[:start_time] || 0
|
start_time = opts[:start_time] || 0
|
||||||
end_time = opts[:end_time] || 0
|
end_time = opts[:end_time] || 0
|
||||||
renew_till = opts[:renew_till] || 0
|
renew_till = opts[:renew_till] || 0
|
||||||
|
|
||||||
time = Rex::Proto::Kerberos::CredentialCache::Time.new(
|
time = Rex::Proto::Kerberos::CredentialCache::Time.new(
|
||||||
auth_time: auth_time.to_i,
|
auth_time: auth_time.to_i,
|
||||||
start_time: start_time.to_i,
|
start_time: start_time.to_i,
|
||||||
end_time: end_time.to_i,
|
end_time: end_time.to_i,
|
||||||
renew_till: renew_till.to_i
|
renew_till: renew_till.to_i
|
||||||
)
|
)
|
||||||
|
|
||||||
time
|
time
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a MIT Credential Cache credential
|
# Builds a MIT Credential Cache credential
|
||||||
#
|
#
|
||||||
# @param opts [Hash<{Symbol => <>}>]
|
# @param opts [Hash<{Symbol => <>}>]
|
||||||
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] client
|
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] client
|
||||||
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] server
|
# @option opts [Rex::Proto::Kerberos::CredentialCache::Principal] server
|
||||||
# @option opts [Rex::Proto::Kerberos::CredentialCache::KeyBlock] key
|
# @option opts [Rex::Proto::Kerberos::CredentialCache::KeyBlock] key
|
||||||
# @option opts [Rex::Proto::Kerberos::CredentialCache::Time] time
|
# @option opts [Rex::Proto::Kerberos::CredentialCache::Time] time
|
||||||
# @option opts [Fixnum] is_key
|
# @option opts [Fixnum] is_key
|
||||||
# @option opts [Fixnum] flags
|
# @option opts [Fixnum] flags
|
||||||
# @option opts [Array] addrs
|
# @option opts [Array] addrs
|
||||||
# @option opts [Array] auth_data
|
# @option opts [Array] auth_data
|
||||||
# @option opts [String] ticket
|
# @option opts [String] ticket
|
||||||
# @option opts [String] second_ticket
|
# @option opts [String] second_ticket
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::Credential]
|
# @return [Rex::Proto::Kerberos::CredentialCache::Credential]
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::Credential
|
# @see Rex::Proto::Kerberos::CredentialCache::Credential
|
||||||
def create_cache_credential(opts = {})
|
def create_cache_credential(opts = {})
|
||||||
client = opts[:client] || create_cache_principal(opts)
|
client = opts[:client] || create_cache_principal(opts)
|
||||||
server = opts[:server] || create_cache_principal(opts)
|
server = opts[:server] || create_cache_principal(opts)
|
||||||
key = opts[:key] || create_cache_key_block(opts)
|
key = opts[:key] || create_cache_key_block(opts)
|
||||||
time = opts[:time] || create_cache_times(opts)
|
time = opts[:time] || create_cache_times(opts)
|
||||||
is_skey = opts[:is_skey] || 0
|
is_skey = opts[:is_skey] || 0
|
||||||
tkt_flags = opts[:flags] || 0
|
tkt_flags = opts[:flags] || 0
|
||||||
addrs = opts[:addrs] || []
|
addrs = opts[:addrs] || []
|
||||||
auth_data = opts[:auth_data] || []
|
auth_data = opts[:auth_data] || []
|
||||||
ticket = opts[:ticket] || ''
|
ticket = opts[:ticket] || ''
|
||||||
second_ticket = opts[:second_ticket] || ''
|
second_ticket = opts[:second_ticket] || ''
|
||||||
|
|
||||||
cred = Rex::Proto::Kerberos::CredentialCache::Credential.new(
|
cred = Rex::Proto::Kerberos::CredentialCache::Credential.new(
|
||||||
client: client,
|
client: client,
|
||||||
server: server,
|
server: server,
|
||||||
key: key,
|
key: key,
|
||||||
time: time,
|
time: time,
|
||||||
is_skey: is_skey,
|
is_skey: is_skey,
|
||||||
tkt_flags:tkt_flags,
|
tkt_flags:tkt_flags,
|
||||||
addrs: addrs,
|
addrs: addrs,
|
||||||
auth_data: auth_data,
|
auth_data: auth_data,
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
second_ticket: second_ticket
|
second_ticket: second_ticket
|
||||||
)
|
)
|
||||||
|
|
||||||
cred
|
cred
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,109 +1,114 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module Pac
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module Pac
|
||||||
|
|
||||||
# Builds a kerberos PA-PAC-REQUEST pre authenticated structure
|
# Builds a kerberos PA-PAC-REQUEST pre authenticated structure
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => Boolean}]
|
# @param opts [Hash{Symbol => Boolean}]
|
||||||
# @option opts [Boolean] :pac_request_value
|
# @option opts [Boolean] :pac_request_value
|
||||||
# @return [Rex::Proto::Kerberos::Model::Field::PreAuthData]
|
# @return [Rex::Proto::Kerberos::Model::Field::PreAuthData]
|
||||||
# @see Rex::Proto::Kerberos::Model::PreAuthPacRequest
|
# @see Rex::Proto::Kerberos::Model::PreAuthPacRequest
|
||||||
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
||||||
def build_pa_pac_request(opts = {})
|
def build_pa_pac_request(opts = {})
|
||||||
value = opts[:pac_request_value] || false
|
value = opts[:pac_request_value] || false
|
||||||
pac_request = Rex::Proto::Kerberos::Model::PreAuthPacRequest.new(value: value)
|
pac_request = Rex::Proto::Kerberos::Model::PreAuthPacRequest.new(value: value)
|
||||||
pa_pac_request = Rex::Proto::Kerberos::Model::PreAuthData.new(
|
pa_pac_request = Rex::Proto::Kerberos::Model::PreAuthData.new(
|
||||||
type: Rex::Proto::Kerberos::Model::PA_PAC_REQUEST,
|
type: Rex::Proto::Kerberos::Model::PA_PAC_REQUEST,
|
||||||
value: pac_request.encode
|
value: pac_request.encode
|
||||||
)
|
)
|
||||||
|
|
||||||
pa_pac_request
|
pa_pac_request
|
||||||
|
end
|
||||||
|
|
||||||
|
# Builds a kerberos PACTYPE structure
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <String, Fixnum, Array, Time>}]
|
||||||
|
# @option opts [String] :client_name
|
||||||
|
# @option opts [Fixnum] :user_id the user SID Ex: 1000
|
||||||
|
# @option opts [Fixnum] :group_id Ex: 513 for 'Domain Users'
|
||||||
|
# @option opts [Array<Fixnum>] :group_ids
|
||||||
|
# @option opts [String] :realm
|
||||||
|
# @option opts [String] :domain_id the domain SID Ex: S-1-5-21-1755879683-3641577184-3486455962
|
||||||
|
# @option opts [Time] :logon_time
|
||||||
|
# @return [Rex::Proto::Kerberos::Pac::Type]
|
||||||
|
# @see Rex::Proto::Kerberos::Pac::LogonInfo
|
||||||
|
# @see Rex::Proto::Kerberos::Pac::ClientInfo
|
||||||
|
# @see Rex::Proto::Kerberos::Pac::ServerChecksum
|
||||||
|
# @see Rex::Proto::Kerberos::Pac::PrivSvrChecksum
|
||||||
|
# @see Rex::Proto::Kerberos::Pac::Type
|
||||||
|
def build_pac(opts = {})
|
||||||
|
user_name = opts[:client_name] || ''
|
||||||
|
user_id = opts[:user_id] || Rex::Proto::Kerberos::Pac::DEFAULT_USER_SID
|
||||||
|
primary_group_id = opts[:group_id] || Rex::Proto::Kerberos::Pac::DOMAIN_USERS
|
||||||
|
group_ids = opts[:group_ids] || [Rex::Proto::Kerberos::Pac::DOMAIN_USERS]
|
||||||
|
domain_name = opts[:realm] || ''
|
||||||
|
domain_id = opts[:domain_id] || Rex::Proto::Kerberos::Pac::NT_AUTHORITY_SID
|
||||||
|
logon_time = opts[:logon_time] || Time.now
|
||||||
|
checksum_type = opts[:checksum_type] || Rex::Proto::Kerberos::Crypto::RSA_MD5
|
||||||
|
|
||||||
|
logon_info = Rex::Proto::Kerberos::Pac::LogonInfo.new(
|
||||||
|
logon_time: logon_time,
|
||||||
|
effective_name: user_name,
|
||||||
|
user_id: user_id,
|
||||||
|
primary_group_id: primary_group_id,
|
||||||
|
group_ids: group_ids,
|
||||||
|
logon_domain_name: domain_name,
|
||||||
|
logon_domain_id: domain_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
client_info = Rex::Proto::Kerberos::Pac::ClientInfo.new(
|
||||||
|
client_id: logon_time,
|
||||||
|
name: user_name
|
||||||
|
)
|
||||||
|
|
||||||
|
server_checksum = Rex::Proto::Kerberos::Pac::ServerChecksum.new(
|
||||||
|
checksum: checksum_type
|
||||||
|
)
|
||||||
|
|
||||||
|
priv_srv_checksum = Rex::Proto::Kerberos::Pac::PrivSvrChecksum.new(
|
||||||
|
checksum: checksum_type
|
||||||
|
)
|
||||||
|
|
||||||
|
pac_type = Rex::Proto::Kerberos::Pac::Type.new(
|
||||||
|
buffers: [
|
||||||
|
logon_info,
|
||||||
|
client_info,
|
||||||
|
server_checksum,
|
||||||
|
priv_srv_checksum
|
||||||
|
],
|
||||||
|
checksum: checksum_type
|
||||||
|
)
|
||||||
|
|
||||||
|
pac_type
|
||||||
|
end
|
||||||
|
|
||||||
|
# Builds an kerberos AuthorizationData structure containing a PACTYPE
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => Rex::Proto::Kerberos::Pac::Type}]
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Pac::Type] :pac
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::AuthorizationData]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
||||||
|
def build_pac_authorization_data(opts = {})
|
||||||
|
pac = opts[:pac] || build_pac(opts)
|
||||||
|
|
||||||
|
pac_auth_data = Rex::Proto::Kerberos::Model::AuthorizationData.new(
|
||||||
|
elements: [{:type => Rex::Proto::Kerberos::Pac::AD_WIN2K_PAC, :data => pac.encode}]
|
||||||
|
)
|
||||||
|
authorization_data = Rex::Proto::Kerberos::Model::AuthorizationData.new(
|
||||||
|
elements: [{:type => Rex::Proto::Kerberos::Model::AD_IF_RELEVANT, :data => pac_auth_data.encode}]
|
||||||
|
)
|
||||||
|
|
||||||
|
authorization_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Builds a kerberos PACTYPE structure
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <String, Fixnum, Array, Time>}]
|
|
||||||
# @option opts [String] :client_name
|
|
||||||
# @option opts [Fixnum] :user_id the user SID Ex: 1000
|
|
||||||
# @option opts [Fixnum] :group_id Ex: 513 for 'Domain Users'
|
|
||||||
# @option opts [Array<Fixnum>] :group_ids
|
|
||||||
# @option opts [String] :realm
|
|
||||||
# @option opts [String] :domain_id the domain SID Ex: S-1-5-21-1755879683-3641577184-3486455962
|
|
||||||
# @option opts [Time] :logon_time
|
|
||||||
# @return [Rex::Proto::Kerberos::Pac::Type]
|
|
||||||
# @see Rex::Proto::Kerberos::Pac::LogonInfo
|
|
||||||
# @see Rex::Proto::Kerberos::Pac::ClientInfo
|
|
||||||
# @see Rex::Proto::Kerberos::Pac::ServerChecksum
|
|
||||||
# @see Rex::Proto::Kerberos::Pac::PrivSvrChecksum
|
|
||||||
# @see Rex::Proto::Kerberos::Pac::Type
|
|
||||||
def build_pac(opts = {})
|
|
||||||
user_name = opts[:client_name] || ''
|
|
||||||
user_id = opts[:user_id] || Rex::Proto::Kerberos::Pac::DEFAULT_USER_SID
|
|
||||||
primary_group_id = opts[:group_id] || Rex::Proto::Kerberos::Pac::DOMAIN_USERS
|
|
||||||
group_ids = opts[:group_ids] || [Rex::Proto::Kerberos::Pac::DOMAIN_USERS]
|
|
||||||
domain_name = opts[:realm] || ''
|
|
||||||
domain_id = opts[:domain_id] || Rex::Proto::Kerberos::Pac::NT_AUTHORITY_SID
|
|
||||||
logon_time = opts[:logon_time] || Time.now
|
|
||||||
checksum_type = opts[:checksum_type] || Rex::Proto::Kerberos::Crypto::RSA_MD5
|
|
||||||
|
|
||||||
logon_info = Rex::Proto::Kerberos::Pac::LogonInfo.new(
|
|
||||||
logon_time: logon_time,
|
|
||||||
effective_name: user_name,
|
|
||||||
user_id: user_id,
|
|
||||||
primary_group_id: primary_group_id,
|
|
||||||
group_ids: group_ids,
|
|
||||||
logon_domain_name: domain_name,
|
|
||||||
logon_domain_id: domain_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
client_info = Rex::Proto::Kerberos::Pac::ClientInfo.new(
|
|
||||||
client_id: logon_time,
|
|
||||||
name: user_name
|
|
||||||
)
|
|
||||||
|
|
||||||
server_checksum = Rex::Proto::Kerberos::Pac::ServerChecksum.new(
|
|
||||||
checksum: checksum_type
|
|
||||||
)
|
|
||||||
|
|
||||||
priv_srv_checksum = Rex::Proto::Kerberos::Pac::PrivSvrChecksum.new(
|
|
||||||
checksum: checksum_type
|
|
||||||
)
|
|
||||||
|
|
||||||
pac_type = Rex::Proto::Kerberos::Pac::Type.new(
|
|
||||||
buffers: [
|
|
||||||
logon_info,
|
|
||||||
client_info,
|
|
||||||
server_checksum,
|
|
||||||
priv_srv_checksum
|
|
||||||
],
|
|
||||||
checksum: checksum_type
|
|
||||||
)
|
|
||||||
|
|
||||||
pac_type
|
|
||||||
end
|
|
||||||
|
|
||||||
# Builds an kerberos AuthorizationData structure containing a PACTYPE
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => Rex::Proto::Kerberos::Pac::Type}]
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Pac::Type] :pac
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::AuthorizationData]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
|
||||||
def build_pac_authorization_data(opts = {})
|
|
||||||
pac = opts[:pac] || build_pac(opts)
|
|
||||||
|
|
||||||
pac_auth_data = Rex::Proto::Kerberos::Model::AuthorizationData.new(
|
|
||||||
elements: [{:type => Rex::Proto::Kerberos::Pac::AD_WIN2K_PAC, :data => pac.encode}]
|
|
||||||
)
|
|
||||||
authorization_data = Rex::Proto::Kerberos::Model::AuthorizationData.new(
|
|
||||||
elements: [{:type => Rex::Proto::Kerberos::Model::AD_IF_RELEVANT, :data => pac_auth_data.encode}]
|
|
||||||
)
|
|
||||||
|
|
||||||
authorization_data
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,270 +1,276 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module TgsRequest
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module TgsRequest
|
||||||
|
|
||||||
# Builds the encrypted Kerberos TGS request
|
# Builds the encrypted Kerberos TGS request
|
||||||
#
|
#
|
||||||
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::Element>}]
|
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::Element>}]
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::AuthorizationData] :auth_data
|
# @option opts [Rex::Proto::Kerberos::Model::AuthorizationData] :auth_data
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :enc_auth_data
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :enc_auth_data
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::Checksum] :checksum
|
# @option opts [Rex::Proto::Kerberos::Model::Checksum] :checksum
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::Authenticator] :auhtenticator
|
# @option opts [Rex::Proto::Kerberos::Model::Authenticator] :auhtenticator
|
||||||
# @option opts [Array<Rex::Proto::Kerberos::Model::PreAuthData>] :pa_data
|
# @option opts [Array<Rex::Proto::Kerberos::Model::PreAuthData>] :pa_data
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcRequest]
|
# @return [Rex::Proto::Kerberos::Model::KdcRequest]
|
||||||
# @raise [RuntimeError] if ticket isn't available
|
# @raise [RuntimeError] if ticket isn't available
|
||||||
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
# @see Rex::Proto::Kerberos::Model::Checksum
|
# @see Rex::Proto::Kerberos::Model::Checksum
|
||||||
# @see Rex::Proto::Kerberos::Model::Authenticator
|
# @see Rex::Proto::Kerberos::Model::Authenticator
|
||||||
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
# @see Rex::Proto::Kerberos::Model::PreAuthData
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcRequest
|
# @see Rex::Proto::Kerberos::Model::KdcRequest
|
||||||
def build_tgs_request(opts = {})
|
def build_tgs_request(opts = {})
|
||||||
subkey = opts[:subkey] || build_subkey(opts)
|
subkey = opts[:subkey] || build_subkey(opts)
|
||||||
|
|
||||||
if opts[:enc_auth_data]
|
if opts[:enc_auth_data]
|
||||||
enc_auth_data = opts[:enc_auth_data]
|
enc_auth_data = opts[:enc_auth_data]
|
||||||
elsif opts[:auth_data]
|
elsif opts[:auth_data]
|
||||||
enc_auth_data = build_enc_auth_data(
|
enc_auth_data = build_enc_auth_data(
|
||||||
auth_data: opts[:auth_data],
|
auth_data: opts[:auth_data],
|
||||||
subkey: subkey
|
subkey: subkey
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
enc_auth_data = nil
|
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
|
||||||
|
|
||||||
|
# Builds the encrypted TGS authorization data
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::AuthorizationData, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::AuthorizationData] :auth_data
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::EncryptedData]
|
||||||
|
# @raise [RuntimeError] if auth_data option isn't provided
|
||||||
|
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
||||||
|
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
|
||||||
|
|
||||||
|
# Builds a KRB_AP_REQ message
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Fixnum, Rex::Proto::Kerberos::Model::Ticket, Rex::Proto::Kerberos::Model::EncryptedData, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
||||||
|
# @option opts [Fixnum] :pvno
|
||||||
|
# @option opts [Fixnum] :msg_type
|
||||||
|
# @option opts [Fixnum] :ap_req_options
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::Ticket] :ticket
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :authenticator
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :session_key
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
||||||
|
# @raise [RuntimeError] if ticket option isn't provided
|
||||||
|
# @see Rex::Proto::Kerberos::Model::Ticket
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
|
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
|
||||||
|
|
||||||
|
# Builds a kerberos authenticator for a TGS request
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::PrincipalName, String, Time, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
||||||
|
# @option opts [String] :realm
|
||||||
|
# @option opts [Time] :ctime
|
||||||
|
# @option opts [Fixnum] :cusec
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::Checksum] :checksum
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::Authenticator]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
||||||
|
# @see Rex::Proto::Kerberos::Model::Checksum
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
|
# @see Rex::Proto::Kerberos::Model::Authenticator
|
||||||
|
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
|
||||||
|
|
||||||
|
# Builds an encryption key to protect the data sent in the TGS request.
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Fixnum, String>}]
|
||||||
|
# @option opts [Fixnum] :subkey_type
|
||||||
|
# @option opts [String] :subkey_value
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
# Builds a kerberos TGS request body
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Fixnum, Time, String, Rex::Proto::Kerberos::Model::PrincipalName, Rex::Proto::Kerberos::Model::EncryptedData>}]
|
||||||
|
# @option opts [Fixnum] :options
|
||||||
|
# @option opts [Time] :from
|
||||||
|
# @option opts [Time] :till
|
||||||
|
# @option opts [Time] :rtime
|
||||||
|
# @option opts [Fixnum] :nonce
|
||||||
|
# @option opts [Fixnum] :etype
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
||||||
|
# @option opts [String] :realm
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :sname
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :enc_auth_data
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::KdcRequestBody]
|
||||||
|
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
||||||
|
# @see Rex::Proto::Kerberos::Model::KdcRequestBody
|
||||||
|
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
|
||||||
|
|
||||||
|
# Builds a Kerberos TGS Request body checksum
|
||||||
|
#
|
||||||
|
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::KdcRequestBody, Fixnum>}]
|
||||||
|
# @option opts [Rex::Proto::Kerberos::Model::KdcRequestBody] :body
|
||||||
|
# @return [Rex::Proto::Kerberos::Model::Checksum]
|
||||||
|
# @see #build_tgs_request_body
|
||||||
|
# @see Rex::Proto::Kerberos::Model::Checksum
|
||||||
|
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
|
||||||
|
end
|
||||||
end
|
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
|
|
||||||
|
|
||||||
# Builds the encrypted TGS authorization data
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::AuthorizationData, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::AuthorizationData] :auth_data
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::EncryptedData]
|
|
||||||
# @raise [RuntimeError] if auth_data option isn't provided
|
|
||||||
# @see Rex::Proto::Kerberos::Model::AuthorizationData
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
|
||||||
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
|
|
||||||
|
|
||||||
# Builds a KRB_AP_REQ message
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Fixnum, Rex::Proto::Kerberos::Model::Ticket, Rex::Proto::Kerberos::Model::EncryptedData, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
|
||||||
# @option opts [Fixnum] :pvno
|
|
||||||
# @option opts [Fixnum] :msg_type
|
|
||||||
# @option opts [Fixnum] :ap_req_options
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::Ticket] :ticket
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :authenticator
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :session_key
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
|
||||||
# @raise [RuntimeError] if ticket option isn't provided
|
|
||||||
# @see Rex::Proto::Kerberos::Model::Ticket
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptedData
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
|
||||||
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
|
|
||||||
|
|
||||||
# Builds a kerberos authenticator for a TGS request
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::PrincipalName, String, Time, Rex::Proto::Kerberos::Model::EncryptionKey>}]
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
|
||||||
# @option opts [String] :realm
|
|
||||||
# @option opts [Time] :ctime
|
|
||||||
# @option opts [Fixnum] :cusec
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::Checksum] :checksum
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptionKey] :subkey
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::Authenticator]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
|
||||||
# @see Rex::Proto::Kerberos::Model::Checksum
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
|
||||||
# @see Rex::Proto::Kerberos::Model::Authenticator
|
|
||||||
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
|
|
||||||
|
|
||||||
# Builds an encryption key to protect the data sent in the TGS request.
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Fixnum, String>}]
|
|
||||||
# @option opts [Fixnum] :subkey_type
|
|
||||||
# @option opts [String] :subkey_value
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::EncryptionKey]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::EncryptionKey
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# Builds a kerberos TGS request body
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Fixnum, Time, String, Rex::Proto::Kerberos::Model::PrincipalName, Rex::Proto::Kerberos::Model::EncryptedData>}]
|
|
||||||
# @option opts [Fixnum] :options
|
|
||||||
# @option opts [Time] :from
|
|
||||||
# @option opts [Time] :till
|
|
||||||
# @option opts [Time] :rtime
|
|
||||||
# @option opts [Fixnum] :nonce
|
|
||||||
# @option opts [Fixnum] :etype
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :cname
|
|
||||||
# @option opts [String] :realm
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::PrincipalName] :sname
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::EncryptedData] :enc_auth_data
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::KdcRequestBody]
|
|
||||||
# @see Rex::Proto::Kerberos::Model::PrincipalName
|
|
||||||
# @see Rex::Proto::Kerberos::Model::KdcRequestBody
|
|
||||||
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
|
|
||||||
|
|
||||||
# Builds a Kerberos TGS Request body checksum
|
|
||||||
#
|
|
||||||
# @param opts [Hash{Symbol => <Rex::Proto::Kerberos::Model::KdcRequestBody, Fixnum>}]
|
|
||||||
# @option opts [Rex::Proto::Kerberos::Model::KdcRequestBody] :body
|
|
||||||
# @return [Rex::Proto::Kerberos::Model::Checksum]
|
|
||||||
# @see #build_tgs_request_body
|
|
||||||
# @see Rex::Proto::Kerberos::Model::Checksum
|
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,71 +1,77 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
|
|
||||||
module Msf::Exploit::Remote::Kerberos
|
module Msf
|
||||||
module Client
|
class Exploit
|
||||||
module TgsResponse
|
class Remote
|
||||||
|
module Kerberos
|
||||||
|
module Client
|
||||||
|
module TgsResponse
|
||||||
|
|
||||||
# Extracts the Kerberos credentials, buildint a MIT Cache Credential,
|
# Extracts the Kerberos credentials, buildint a MIT Cache Credential,
|
||||||
# from a Kerberos TGS response.
|
# from a Kerberos TGS response.
|
||||||
#
|
#
|
||||||
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
# @param res [Rex::Proto::Kerberos::Model::KdcResponse]
|
||||||
# @param key [String]
|
# @param key [String]
|
||||||
# @return [Rex::Proto::Kerberos::CredentialCache::Cache]
|
# @return [Rex::Proto::Kerberos::CredentialCache::Cache]
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse
|
||||||
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
# @see Rex::Proto::Kerberos::Model::EncKdcResponse.decode
|
||||||
# @see Msf::Kerberos::Client::CacheCredential
|
# @see Msf::Kerberos::Client::CacheCredential
|
||||||
# @see Rex::Proto::Kerberos::CredentialCache::Cache
|
# @see Rex::Proto::Kerberos::CredentialCache::Cache
|
||||||
def extract_kerb_creds(res, key)
|
def extract_kerb_creds(res, key)
|
||||||
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_TGS_RESPONSE)
|
decrypt_res = res.enc_part.decrypt(key, Rex::Proto::Kerberos::Crypto::ENC_TGS_RESPONSE)
|
||||||
enc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
enc_res = Rex::Proto::Kerberos::Model::EncKdcResponse.decode(decrypt_res)
|
||||||
|
|
||||||
client = create_cache_principal(
|
client = create_cache_principal(
|
||||||
name_type: res.cname.name_type,
|
name_type: res.cname.name_type,
|
||||||
realm: res.crealm,
|
realm: res.crealm,
|
||||||
components: res.cname.name_string
|
components: res.cname.name_string
|
||||||
)
|
)
|
||||||
|
|
||||||
server = create_cache_principal(
|
server = create_cache_principal(
|
||||||
name_type: enc_res.sname.name_type,
|
name_type: enc_res.sname.name_type,
|
||||||
realm: enc_res.srealm,
|
realm: enc_res.srealm,
|
||||||
components: enc_res.sname.name_string
|
components: enc_res.sname.name_string
|
||||||
)
|
)
|
||||||
|
|
||||||
key = create_cache_key_block(
|
key = create_cache_key_block(
|
||||||
key_type: enc_res.key.type,
|
key_type: enc_res.key.type,
|
||||||
key_value: enc_res.key.value
|
key_value: enc_res.key.value
|
||||||
)
|
)
|
||||||
|
|
||||||
times = create_cache_times(
|
times = create_cache_times(
|
||||||
auth_time: enc_res.auth_time,
|
auth_time: enc_res.auth_time,
|
||||||
start_time: enc_res.start_time,
|
start_time: enc_res.start_time,
|
||||||
end_time: enc_res.end_time,
|
end_time: enc_res.end_time,
|
||||||
renew_till: enc_res.renew_till
|
renew_till: enc_res.renew_till
|
||||||
)
|
)
|
||||||
|
|
||||||
credential = create_cache_credential(
|
credential = create_cache_credential(
|
||||||
client: client,
|
client: client,
|
||||||
server: server,
|
server: server,
|
||||||
key: key,
|
key: key,
|
||||||
time: times,
|
time: times,
|
||||||
ticket: res.ticket.encode,
|
ticket: res.ticket.encode,
|
||||||
flags: enc_res.flags
|
flags: enc_res.flags
|
||||||
)
|
)
|
||||||
|
|
||||||
cache_principal = create_cache_principal(
|
cache_principal = create_cache_principal(
|
||||||
name_type: res.cname.name_type, # NT_PRINCIPAL
|
name_type: res.cname.name_type, # NT_PRINCIPAL
|
||||||
#realm: realm,# opts[:realm],
|
#realm: realm,# opts[:realm],
|
||||||
realm: res.crealm,
|
realm: res.crealm,
|
||||||
#components: user # [opts[:cname]]
|
#components: user # [opts[:cname]]
|
||||||
components: res.cname.name_string
|
components: res.cname.name_string
|
||||||
)
|
)
|
||||||
|
|
||||||
cache = create_cache(
|
cache = create_cache(
|
||||||
primary_principal: cache_principal,
|
primary_principal: cache_principal,
|
||||||
credentials: [credential]
|
credentials: [credential]
|
||||||
)
|
)
|
||||||
|
|
||||||
cache
|
cache
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::AsRequest do
|
describe Msf::Exploit::Remote::Kerberos::Client::AsRequest do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::AsResponse do
|
describe Msf::Exploit::Remote::Kerberos::Client::AsResponse do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::Base do
|
describe Msf::Exploit::Remote::Kerberos::Client::Base do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::CacheCredential do
|
describe Msf::Exploit::Remote::Kerberos::Client::CacheCredential do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::Pac do
|
describe Msf::Exploit::Remote::Kerberos::Client::Pac do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::TgsRequest do
|
describe Msf::Exploit::Remote::Kerberos::Client::TgsRequest do
|
||||||
subject(:mod) do
|
subject(:mod) do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
require 'rex/proto/kerberos'
|
require 'rex/proto/kerberos'
|
||||||
require 'msf/kerberos/client'
|
require 'msf/core/exploit/kerberos/client'
|
||||||
|
|
||||||
describe Msf::Kerberos::Client::TgsResponse do
|
describe Msf::Exploit::Remote::Kerberos::Client::TgsResponse do
|
||||||
subject do
|
subject do
|
||||||
mod = ::Msf::Exploit.new
|
mod = ::Msf::Exploit.new
|
||||||
mod.extend ::Msf::Kerberos::Client
|
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||||
mod.send(:initialize)
|
mod.send(:initialize)
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue