Fix specs to pass again

bug/bundler_fix
jvazquez-r7 2015-10-15 09:40:39 -05:00
parent fa9a33cae8
commit 8057b3edae
No known key found for this signature in database
GPG Key ID: 38D99152B9352D83
15 changed files with 881 additions and 836 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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