mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +00:00
Decrypt the krb ticket and send authentication data out.
This commit is contained in:
parent
1f777b57b8
commit
98a430c1eb
9 changed files with 137 additions and 4 deletions
|
@ -4222,6 +4222,7 @@ export {
|
||||||
|
|
||||||
module KRB;
|
module KRB;
|
||||||
export {
|
export {
|
||||||
|
const keytab = "/etc/krb5.keytab" &redef;
|
||||||
## KDC Options. See :rfc:`4120`
|
## KDC Options. See :rfc:`4120`
|
||||||
type KRB::KDC_Options: record {
|
type KRB::KDC_Options: record {
|
||||||
## The ticket to be issued should have its forwardable flag set.
|
## The ticket to be issued should have its forwardable flag set.
|
||||||
|
@ -4344,6 +4345,8 @@ export {
|
||||||
cipher : count;
|
cipher : count;
|
||||||
## Cipher text of the ticket
|
## Cipher text of the ticket
|
||||||
ciphertext : string &optional;
|
ciphertext : string &optional;
|
||||||
|
## Authentication info
|
||||||
|
authenticationinfo: string &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB::Ticket_Vector: vector of KRB::Ticket;
|
type KRB::Ticket_Vector: vector of KRB::Ticket;
|
||||||
|
|
|
@ -9,6 +9,7 @@ bro_plugin_cc(KRB.cc)
|
||||||
bro_plugin_cc(KRB_TCP.cc)
|
bro_plugin_cc(KRB_TCP.cc)
|
||||||
bro_plugin_bif(types.bif)
|
bro_plugin_bif(types.bif)
|
||||||
bro_plugin_bif(events.bif)
|
bro_plugin_bif(events.bif)
|
||||||
|
bro_plugin_link_library(-lkrb5)
|
||||||
bro_plugin_pac(krb.pac krb-protocol.pac krb-analyzer.pac
|
bro_plugin_pac(krb.pac krb-protocol.pac krb-analyzer.pac
|
||||||
krb-asn1.pac
|
krb-asn1.pac
|
||||||
krb-defs.pac
|
krb-defs.pac
|
||||||
|
|
|
@ -7,13 +7,47 @@
|
||||||
using namespace analyzer::krb;
|
using namespace analyzer::krb;
|
||||||
|
|
||||||
KRB_Analyzer::KRB_Analyzer(Connection* conn)
|
KRB_Analyzer::KRB_Analyzer(Connection* conn)
|
||||||
: Analyzer("KRB", conn)
|
: Analyzer("KRB", conn),
|
||||||
|
krb_available(false)
|
||||||
{
|
{
|
||||||
interp = new binpac::KRB::KRB_Conn(this);
|
interp = new binpac::KRB::KRB_Conn(this);
|
||||||
|
|
||||||
|
const char* keytab_filename = BifConst::KRB::keytab->CheckString();
|
||||||
|
if (access(keytab_filename, R_OK) != 0)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Can't access keytab (%s)", keytab_filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code retval = krb5_init_context(&krb_context);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't initialize the context (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
krb_available = true;
|
||||||
|
|
||||||
|
retval = krb5_kt_resolve(krb_context, keytab_filename, &krb_keytab);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't resolve keytab (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KRB_Analyzer::~KRB_Analyzer()
|
KRB_Analyzer::~KRB_Analyzer()
|
||||||
{
|
{
|
||||||
|
if (krb_available)
|
||||||
|
{
|
||||||
|
krb5_error_code retval = krb5_kt_close(krb_context, krb_keytab);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't close keytab (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
}
|
||||||
|
krb5_free_context(krb_context);
|
||||||
|
}
|
||||||
delete interp;
|
delete interp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,3 +71,67 @@ void KRB_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringVal* KRB_Analyzer::GetAuthenticationInfo(const BroString* principal, const BroString* ciphertext, const bro_uint_t enctype)
|
||||||
|
{
|
||||||
|
StringVal* ret = new StringVal("nouser");
|
||||||
|
if (!krb_available)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BroString delim("/");
|
||||||
|
int pos = principal->FindSubstring(&delim);
|
||||||
|
if (pos == -1)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't parse principal (%s)", principal->CheckString());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
BroString* service(principal->GetSubstring(0, pos));
|
||||||
|
BroString* hostname(principal->GetSubstring(pos + 1, -1));
|
||||||
|
if (!service || !hostname)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't parse principal (%s)", principal->CheckString());
|
||||||
|
if (!service)
|
||||||
|
free(service);
|
||||||
|
if (!hostname)
|
||||||
|
free(hostname);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
krb5_principal sprinc;
|
||||||
|
krb5_error_code retval = krb5_sname_to_principal(krb_context, reinterpret_cast<char*>(hostname->Bytes()), reinterpret_cast<char*>(service->Bytes()), KRB5_NT_SRV_HST, &sprinc);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't generate principal name (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
free(service);
|
||||||
|
free(hostname);
|
||||||
|
|
||||||
|
krb5_ticket tkt;
|
||||||
|
tkt.server = sprinc;
|
||||||
|
tkt.enc_part.enctype = enctype;
|
||||||
|
tkt.enc_part.ciphertext.data = reinterpret_cast<char*>(ciphertext->Bytes());
|
||||||
|
tkt.enc_part.ciphertext.length = ciphertext->Len();
|
||||||
|
|
||||||
|
retval = krb5_server_decrypt_ticket_keytab(krb_context, krb_keytab, &tkt);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't decrypt ticket (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cp;
|
||||||
|
retval = krb5_unparse_name(krb_context, tkt.enc_part2->client, &cp);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
reporter->Warning("KRB: Couldn't unparse name (%s)", krb5_get_error_message(krb_context, retval));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
free(ret);
|
||||||
|
ret = new StringVal(cp);
|
||||||
|
|
||||||
|
krb5_free_unparsed_name(krb_context, cp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "krb_pac.h"
|
#include "krb_pac.h"
|
||||||
|
|
||||||
|
#include <krb5.h>
|
||||||
|
|
||||||
namespace analyzer { namespace krb {
|
namespace analyzer { namespace krb {
|
||||||
|
|
||||||
class KRB_Analyzer : public analyzer::Analyzer {
|
class KRB_Analyzer : public analyzer::Analyzer {
|
||||||
|
@ -20,9 +22,15 @@ public:
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
{ return new KRB_Analyzer(conn); }
|
{ return new KRB_Analyzer(conn); }
|
||||||
|
|
||||||
|
StringVal* GetAuthenticationInfo(const BroString* principal, const BroString* ciphertext, const bro_uint_t enctype);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
binpac::KRB::KRB_Conn* interp;
|
binpac::KRB::KRB_Conn* interp;
|
||||||
|
|
||||||
|
bool krb_available;
|
||||||
|
krb5_context krb_context;
|
||||||
|
krb5_keytab krb_keytab;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // namespace analyzer::*
|
} } // namespace analyzer::*
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
// Overriden from tcp::TCP_ApplicationAnalyzer.
|
// Overriden from tcp::TCP_ApplicationAnalyzer.
|
||||||
void EndpointEOF(bool is_orig) override;
|
void EndpointEOF(bool is_orig) override;
|
||||||
|
|
||||||
|
StringVal* GetAuthenticationInfo(const BroString* principal, const BroString* ciphertext, const bro_uint_t enctype) { return new StringVal(""); }
|
||||||
|
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
{ return new KRB_Analyzer(conn); }
|
{ return new KRB_Analyzer(conn); }
|
||||||
|
|
||||||
|
|
|
@ -245,8 +245,11 @@ refine connection KRB_Conn += {
|
||||||
rv->Assign(0, new Val(${msg.ap_options.use_session_key}, TYPE_BOOL));
|
rv->Assign(0, new Val(${msg.ap_options.use_session_key}, TYPE_BOOL));
|
||||||
rv->Assign(1, new Val(${msg.ap_options.mutual_required}, TYPE_BOOL));
|
rv->Assign(1, new Val(${msg.ap_options.mutual_required}, TYPE_BOOL));
|
||||||
|
|
||||||
|
RecordVal* rvticket = proc_ticket(${msg.ticket});
|
||||||
|
StringVal* authenticationinfo = bro_analyzer()->GetAuthenticationInfo(rvticket->Lookup(2)->AsString(), rvticket->Lookup(4)->AsString(), rvticket->Lookup(3)->AsCount());
|
||||||
|
rvticket->Assign(5, authenticationinfo);
|
||||||
BifEvent::generate_krb_ap_request(bro_analyzer(), bro_analyzer()->Conn(),
|
BifEvent::generate_krb_ap_request(bro_analyzer(), bro_analyzer()->Conn(),
|
||||||
proc_ticket(${msg.ticket}), rv);
|
rvticket, rv);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
|
@ -4,14 +4,22 @@
|
||||||
%extern{
|
%extern{
|
||||||
#include "types.bif.h"
|
#include "types.bif.h"
|
||||||
#include "events.bif.h"
|
#include "events.bif.h"
|
||||||
|
|
||||||
|
namespace analyzer { namespace krb { class KRB_Analyzer; } }
|
||||||
|
namespace binpac { namespace KRB { class KRB_Conn; } }
|
||||||
|
typedef analyzer::krb::KRB_Analyzer* KRBAnalyzer;
|
||||||
|
|
||||||
|
#include "KRB.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
extern type KRBAnalyzer;
|
||||||
|
|
||||||
analyzer KRB withcontext {
|
analyzer KRB withcontext {
|
||||||
connection: KRB_Conn;
|
connection: KRB_Conn;
|
||||||
flow: KRB_Flow;
|
flow: KRB_Flow;
|
||||||
};
|
};
|
||||||
|
|
||||||
connection KRB_Conn(bro_analyzer: BroAnalyzer) {
|
connection KRB_Conn(bro_analyzer: KRBAnalyzer) {
|
||||||
upflow = KRB_Flow(true);
|
upflow = KRB_Flow(true);
|
||||||
downflow = KRB_Flow(false);
|
downflow = KRB_Flow(false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,14 +4,22 @@
|
||||||
%extern{
|
%extern{
|
||||||
#include "types.bif.h"
|
#include "types.bif.h"
|
||||||
#include "events.bif.h"
|
#include "events.bif.h"
|
||||||
|
|
||||||
|
namespace analyzer { namespace krb_tcp { class KRB_Analyzer; } }
|
||||||
|
namespace binpac { namespace KRB_TCP { class KRB_Conn; } }
|
||||||
|
typedef analyzer::krb_tcp::KRB_Analyzer* KRBTCPAnalyzer;
|
||||||
|
|
||||||
|
#include "KRB_TCP.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
extern type KRBTCPAnalyzer;
|
||||||
|
|
||||||
analyzer KRB_TCP withcontext {
|
analyzer KRB_TCP withcontext {
|
||||||
connection: KRB_Conn;
|
connection: KRB_Conn;
|
||||||
flow: KRB_Flow;
|
flow: KRB_Flow;
|
||||||
};
|
};
|
||||||
|
|
||||||
connection KRB_Conn(bro_analyzer: BroAnalyzer) {
|
connection KRB_Conn(bro_analyzer: KRBTCPAnalyzer) {
|
||||||
upflow = KRB_Flow(true);
|
upflow = KRB_Flow(true);
|
||||||
downflow = KRB_Flow(false);
|
downflow = KRB_Flow(false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
module KRB;
|
module KRB;
|
||||||
|
|
||||||
|
const keytab: string;
|
||||||
|
|
||||||
type Error_Msg: record;
|
type Error_Msg: record;
|
||||||
type SAFE_Msg: record;
|
type SAFE_Msg: record;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue