mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
TLS decryption: refactoring, more comments, less bare pointers
This commit refactors TLS decryption, adds more comments in scripts and in C++ source-code, and removes use of bare pointers, instead relying more on stl data types.
This commit is contained in:
parent
689b06d9bd
commit
b78f30339f
7 changed files with 186 additions and 120 deletions
|
@ -1,4 +1,10 @@
|
|||
#! Decrypt SSL/TLS payloads
|
||||
##! This script allows for the decryption of certain TLS 1.2 connection, if the user is in possession
|
||||
##! of the private key material for the session. Key material can either be provided via a file (useful
|
||||
##! for processing trace files) or via sending events via broker (for live decoding).
|
||||
##!
|
||||
##! Please note that this feature is experimental and can change without guarantees to our typical
|
||||
##! deprecation tieline. Please also note that currently only TLS 1.2 connections that use the
|
||||
##! TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite are supported.
|
||||
|
||||
@load base/frameworks/input
|
||||
@load base/frameworks/notice
|
||||
|
@ -7,49 +13,69 @@
|
|||
|
||||
module SSL;
|
||||
|
||||
export {
|
||||
const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef;
|
||||
|
||||
global secrets: table[string] of string = {} &redef;
|
||||
global keys: table[string] of string = {} &redef;
|
||||
|
||||
global add_keys: event(client_random: string, keys: string);
|
||||
|
||||
global add_secret: event(client_random: string, secret: string);
|
||||
}
|
||||
|
||||
# Do not disable analyzers after detection - otherwise we will not receive
|
||||
# encrypted packets.
|
||||
redef SSL::disable_analyzer_after_detection = F;
|
||||
|
||||
export {
|
||||
## This can be set to a file that contains the session secrets for decryption, when parsing a pcap file.
|
||||
## Please note that, when using this feature, you probably want to pause processing of data till this
|
||||
## file has been read.
|
||||
const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef;
|
||||
|
||||
## Secrets expire after this time of not being used.
|
||||
const secret_expiration = 5 mins &redef;
|
||||
|
||||
## This event can be triggered, e.g., via broker to add known keys to the TLS key database.
|
||||
##
|
||||
## client_random: client random for which the key is set
|
||||
##
|
||||
## keys: key material
|
||||
global add_keys: event(client_random: string, keys: string);
|
||||
|
||||
## This event can be triggered, e.g., via broker to add known secrets to the TLS secret datbase.
|
||||
##
|
||||
## client_random: client random for which the secret is set
|
||||
##
|
||||
## secrets: derived TLS secrets material
|
||||
global add_secret: event(client_random: string, secret: string);
|
||||
}
|
||||
|
||||
@if ( keylog_file == "" )
|
||||
# If a keylog file was given via an environment variable, let's disable secret expiration - that does not
|
||||
# make sense for pcaps.
|
||||
global secrets: table[string] of string = {} &redef;
|
||||
global keys: table[string] of string = {} &redef;
|
||||
@else
|
||||
#global secrets: table[string] of string = {} &read_expire=secret_expiration &redef;
|
||||
#global keys: table[string] of string = {} &read_expire=secret_expiration &redef;
|
||||
@endif
|
||||
|
||||
|
||||
redef record SSL::Info += {
|
||||
# Decryption uses client_random as identifier
|
||||
client_random: string &log &optional;
|
||||
client_random: string &optional;
|
||||
};
|
||||
|
||||
type Idx: record {
|
||||
type SecretsIdx: record {
|
||||
client_random: string;
|
||||
};
|
||||
|
||||
type Val: record {
|
||||
type SecretsVal: record {
|
||||
secret: string;
|
||||
};
|
||||
|
||||
const input_stream_name = "input-tls-keylog-file";
|
||||
const tls_decrypt_stream_name = "tls-keylog-file";
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
# listen for secrets
|
||||
Broker::subscribe("/zeek/tls/decryption");
|
||||
|
||||
# FIXME: is such a functionality helpful?
|
||||
# ingest keylog file if the environment is set
|
||||
if ( keylog_file != "" )
|
||||
{
|
||||
suspend_processing();
|
||||
|
||||
Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]);
|
||||
Input::remove(input_stream_name);
|
||||
Input::add_table([$name=tls_decrypt_stream_name, $source=keylog_file, $destination=secrets, $idx=SecretsIdx, $val=SecretsVal, $want_record=F]);
|
||||
Input::remove(tls_decrypt_stream_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +92,7 @@ event SSL::add_secret(client_random: string, val: string)
|
|||
event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
|
||||
{
|
||||
c$ssl$client_random = client_random;
|
||||
print "Client random!";
|
||||
|
||||
if ( client_random in keys )
|
||||
set_keys(c, keys[client_random]);
|
||||
|
@ -73,7 +100,7 @@ event ssl_client_hello(c: connection, version: count, record_version: count, pos
|
|||
set_secret(c, secrets[client_random]);
|
||||
}
|
||||
|
||||
event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count)
|
||||
event ssl_change_cipher_spec(c: connection, is_orig: bool)
|
||||
{
|
||||
if ( c$ssl?$client_random )
|
||||
{
|
||||
|
@ -81,20 +108,5 @@ event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, co
|
|||
set_keys(c, keys[c$ssl$client_random]);
|
||||
else if ( c$ssl$client_random in secrets )
|
||||
set_secret(c, secrets[c$ssl$client_random]);
|
||||
else
|
||||
{
|
||||
# FIXME: perhaps report that we could not decrypt the session
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event SSL::tls_input_done()
|
||||
{
|
||||
continue_processing();
|
||||
}
|
||||
|
||||
event Input::end_of_data(name: string, source: string)
|
||||
{
|
||||
if ( name == input_stream_name )
|
||||
event SSL::tls_input_done();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue