file_analysis: Implement AnalyzerViolation() for file_analysis/Analyzer

Add a test parsing a malformed PE file showing that analyzer_violation_info
is raised with the fa_file object set.

It could be interesting to pass through an optional connection if one
exists, but access is provided through f$conns, too.
This commit is contained in:
Arne Welzel 2022-08-31 18:07:18 +02:00
parent bc8fd5a4c6
commit d5cd023dff
10 changed files with 145 additions and 6 deletions

View file

@ -0,0 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
Files::ANALYZER_PE, Binpac exception: binpac exception: &enforce violation : DOS_Header:AddressOfNewExeHeader, FKPuH630Tmj6UQUMP7, {\x0aPE\x0a}

View file

@ -0,0 +1,10 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path files
#open XXXX-XX-XX-XX-XX-XX
#fields ts fuid uid id.orig_h id.orig_p id.resp_h id.resp_p source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid
#types time string string addr port addr port string count set[string] string string interval bool bool count count count count bool string
XXXXXXXXXX.XXXXXX FKPuH630Tmj6UQUMP7 - - - - - ./myfile.exe 0 PE application/x-dosexec - 0.000000 - - 64 - 0 0 F -

View file

@ -4,15 +4,18 @@ Demo::Foo - A Foo test analyzer (dynamic, version 1.0.0)
[Event] foo_piece
===
analyzer_confirmation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri
foo_piece, FCceqBvpMfirSN0Ri, The National Center
foo_piece, FCceqBvpMfirSN0Ri, net, consult your lo
foo_piece, FCceqBvpMfirSN0Ri, most everything else
foo_piece, FCceqBvpMfirSN0Ri, low:\x0a\x0a /Mac
foo_piece, FCceqBvpMfirSN0Ri, es and directories o
analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 5, es and directori
foo_piece, FCceqBvpMfirSN0Ri, r example, here is a
foo_piece, FCceqBvpMfirSN0Ri, application, StuffIt
foo_piece, FCceqBvpMfirSN0Ri, tion BinHex by doubl
foo_piece, FCceqBvpMfirSN0Ri, laced, or are going
foo_piece, FCceqBvpMfirSN0Ri, sers several documen
analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 10, sers several doc
foo_piece, FCceqBvpMfirSN0Ri, er or can be printed
foo_piece, FCceqBvpMfirSN0Ri, \x0a\x0aBug reports shoul

View file

@ -0,0 +1,24 @@
# @TEST-DOC: Verify analyzer_violation_info is raised for an invalid PE file.
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff .stdout
# @TEST-EXEC: btest-diff files.log
@load base/frameworks/files
@load base/files/pe
event analyzer_violation_info(tag: AllAnalyzers::Tag, info: AnalyzerViolationInfo)
{
print tag, info$reason, info$f$id, cat(info$f$info$analyzers);
}
event zeek_init()
{
local source: string = "./myfile.exe";
Input::add_analysis([$source=source, $name=source]);
}
# This file triggers a binpac exception for PE that is reported through
# analyzer_violation_info
@TEST-START-FILE ./myfile.exe
MZ0000000000000000000000000000000000000000000000000000000000000
@TEST-END-FILE

View file

@ -1,8 +1,8 @@
#include "Foo.h"
#include <zeek/file_analysis/File.h>
#include <zeek/file_analysis/Manager.h>
#include <algorithm>
#include "events.bif.h"
@ -21,7 +21,16 @@ zeek::file_analysis::Analyzer* Foo::Instantiate(zeek::RecordValPtr args,
bool Foo::DeliverStream(const u_char* data, uint64_t len)
{
static int i = 0;
AnalyzerConfirmation();
zeek::event_mgr.Enqueue(foo_piece, GetFile()->ToVal(),
zeek::make_intrusive<zeek::StringVal>(new zeek::String(data, len, 0)));
if ( ++i % 5 == 0 )
{
uint64_t threshold = 16;
AnalyzerViolation(zeek::util::fmt("test violation %d", i),
reinterpret_cast<const char*>(data), std::min(len, threshold));
}
return true;
}

View file

@ -7,12 +7,21 @@
# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff output
event file_new(f: fa_file)
{
Files::add_analyzer(f, Files::ANALYZER_FOO);
}
{
Files::add_analyzer(f, Files::ANALYZER_FOO);
}
event foo_piece(f: fa_file, data: string)
{
print "foo_piece", f$id, sub_bytes(data, 0, 20);
}
event analyzer_confirmation_info(tag: AllAnalyzers::Tag, info: AnalyzerConfirmationInfo)
{
print "analyzer_confirmation_info", tag, info$f$id;
}
event analyzer_violation_info(tag: AllAnalyzers::Tag, info: AnalyzerViolationInfo)
{
print "analyzer_violation_info", tag, info$f$id, info$reason, info$data;
}