zeek/scripts/base/files/pe/main.bro
2015-04-19 18:41:32 -04:00

128 lines
3.1 KiB
Text

module PE;
export {
redef enum Log::ID += { LOG };
type Info: record {
ts: time &log;
fuid: string &log;
machine: string &log &optional;
compile_ts: time &log &optional;
os: string &log &optional;
subsystem: string &log &optional;
is_exe: bool &log &default=F;
is_dll: bool &log &default=F;
is_64bit: bool &log &default=T;
uses_aslr: bool &log &default=F;
uses_dep: bool &log &default=F;
uses_code_integrity: bool &log &default=F;
uses_seh: bool &log &default=T;
has_import_table: bool &log &optional;
has_export_table: bool &log &optional;
has_cert_table: bool &log &optional;
has_debug_data: bool &log &optional;
section_names: vector of string &log &optional;
};
global set_file: hook(f: fa_file);
}
redef record Info += {
confirmed: bool &default=F;
};
redef record fa_file += {
pe: Info &optional;
};
event bro_init() &priority=5
{
Log::create_stream(LOG, [$columns=Info]);
}
hook set_file(f: fa_file) &priority=5
{
if ( ! f?$pe )
{
local c: set[string] = set();
f$pe = [$ts=network_time(), $fuid=f$id];
}
}
event pe_dos_header(f: fa_file, h: PE::DOSHeader) &priority=5
{
hook set_file(f);
}
event pe_file_header(f: fa_file, h: PE::FileHeader) &priority=5
{
hook set_file(f);
f$pe$compile_ts = h$ts;
f$pe$machine = machine_types[h$machine];
for ( c in h$characteristics )
{
if ( c == 0x2 )
f$pe$is_exe = T;
if ( c == 0x100 )
f$pe$is_64bit = F;
if ( c == 0x2000 )
f$pe$is_dll = T;
}
}
event pe_optional_header(f: fa_file, h: PE::OptionalHeader) &priority=5
{
hook set_file(f);
if ( h$magic == 0x10b || h$magic == 0x20b )
f$pe$confirmed = T;
else
return;
f$pe$os = os_versions[h$os_version_major, h$os_version_minor];
f$pe$subsystem = windows_subsystems[h$subsystem];
for ( c in h$dll_characteristics )
{
if ( c == 0x40 )
f$pe$uses_aslr = T;
if ( c == 0x80 )
f$pe$uses_code_integrity = T;
if ( c == 0x100 )
f$pe$uses_dep = T;
if ( c == 0x400 )
f$pe$uses_seh = F;
}
f$pe$has_export_table = (|h$rvas| > 0 && h$rvas[0] > 0);
f$pe$has_import_table = (|h$rvas| > 1 && h$rvas[1] > 0);
f$pe$has_cert_table = (|h$rvas| > 4 && h$rvas[4] > 0);
f$pe$has_debug_data = (|h$rvas| > 6 && h$rvas[6] > 0);
}
event pe_section_header(f: fa_file, h: PE::SectionHeader) &priority=5
{
hook set_file(f);
if ( ! f$pe?$section_names )
f$pe$section_names = vector();
f$pe$section_names[|f$pe$section_names|] = h$name;
}
event file_state_remove(f: fa_file) &priority=-5
{
if ( f?$pe && f$pe$confirmed )
Log::write(LOG, f$pe);
}
event file_mime_type(f: fa_file, mime_type: string)
{
if ( mime_type == /application\/x-dosexec.*/ )
{
Files::add_analyzer(f, Files::ANALYZER_PE);
}
}