From efc76fd052b29cc0b23f89868384587b7d809ac3 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Fri, 22 Feb 2013 02:36:41 -0500 Subject: [PATCH] Initial groundwork for analyzer actions in file analysis framework. --- src/CMakeLists.txt | 5 +++ src/binpac_bro.h | 2 ++ src/file_analysis.bif | 1 + src/file_analysis/Info.cc | 2 ++ src/file_analysis/analyzers/PE.cc | 34 +++++++++++++++++++++ src/file_analysis/analyzers/PE.h | 31 +++++++++++++++++++ src/file_analysis/analyzers/pe-analyzer.pac | 16 ++++++++++ src/file_analysis/analyzers/pe-file.pac | 26 ++++++++++++++++ src/file_analysis/analyzers/pe.pac | 20 ++++++++++++ 9 files changed, 137 insertions(+) create mode 100644 src/file_analysis/analyzers/PE.cc create mode 100644 src/file_analysis/analyzers/PE.h create mode 100644 src/file_analysis/analyzers/pe-analyzer.pac create mode 100644 src/file_analysis/analyzers/pe-file.pac create mode 100644 src/file_analysis/analyzers/pe.pac diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16de055e11..9f8f4106ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -176,6 +176,7 @@ macro(BINPAC_TARGET pacFile) COMMAND ${BinPAC_EXE} ARGS -q -d ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${CMAKE_CURRENT_SOURCE_DIR}/file_analysis/analyzers ${CMAKE_CURRENT_SOURCE_DIR}/${pacFile} DEPENDS ${BinPAC_EXE} ${pacFile} ${BINPAC_AUXSRC} ${ARGN} @@ -222,6 +223,9 @@ binpac_target(syslog.pac binpac_target(modbus.pac modbus-protocol.pac modbus-analyzer.pac) +binpac_target(file_analysis/analyzers/pe.pac + file_analysis/analyzers/pe-file.pac file_analysis/analyzers/pe-analyzer.pac) + ######################################################################## ## bro target @@ -453,6 +457,7 @@ set(bro_SRCS file_analysis/InfoTimer.cc file_analysis/Action.h file_analysis/Extract.cc + file_analysis/analyzers/PE.cc nb_dns.c digest.h diff --git a/src/binpac_bro.h b/src/binpac_bro.h index dcdbe94f57..1f63808c10 100644 --- a/src/binpac_bro.h +++ b/src/binpac_bro.h @@ -7,6 +7,7 @@ class PortVal; #include "util.h" #include "Analyzer.h" +#include "file_analysis/Action.h" #include "Val.h" #include "event.bif.func_h" @@ -15,6 +16,7 @@ class PortVal; namespace binpac { typedef Analyzer* BroAnalyzer; +typedef file_analysis::Action BroFileAnalyzer; typedef Val* BroVal; typedef PortVal* BroPortVal; typedef StringVal* BroStringVal; diff --git a/src/file_analysis.bif b/src/file_analysis.bif index 546ac5103c..9afa2d96ab 100644 --- a/src/file_analysis.bif +++ b/src/file_analysis.bif @@ -57,6 +57,7 @@ enum Trigger %{ enum Action %{ ACTION_EXTRACT, + ACTION_PE_ANALYZER, %} function FileAnalysis::postpone_timeout%(file_id: string%): bool diff --git a/src/file_analysis/Info.cc b/src/file_analysis/Info.cc index 60729cd590..e7d8f7ada0 100644 --- a/src/file_analysis/Info.cc +++ b/src/file_analysis/Info.cc @@ -7,12 +7,14 @@ #include "Action.h" #include "Extract.h" +#include "analyzers/PE.h" using namespace file_analysis; // keep in order w/ declared enum values in file_analysis.bif static ActionInstantiator action_factory[] = { Extract::Instantiate, + PE_Analyzer::Instantiate, }; static TableVal* empty_conn_id_set() diff --git a/src/file_analysis/analyzers/PE.cc b/src/file_analysis/analyzers/PE.cc new file mode 100644 index 0000000000..66954ffa3e --- /dev/null +++ b/src/file_analysis/analyzers/PE.cc @@ -0,0 +1,34 @@ +#include + +#include "PE.h" +#include "pe_pac.h" +#include "util.h" + +using namespace file_analysis; + +PE_Analyzer::PE_Analyzer(Info* arg_info) + : Action(arg_info) + { + interp = new binpac::PE::File(this); + + // Close the reverse flow. + interp->FlowEOF(false); + } + +PE_Analyzer::~PE_Analyzer() + { + delete interp; + } + +Action* PE_Analyzer::Instantiate(const RecordVal* args, Info* info) + { + return new PE_Analyzer(info); + } + +void PE_Analyzer::DeliverStream(const u_char* data, uint64 len) + { + Action::DeliverStream(data, len); + + // Data is exclusively sent into the "up" flow. + interp->NewData(true, data, data + len); + } diff --git a/src/file_analysis/analyzers/PE.h b/src/file_analysis/analyzers/PE.h new file mode 100644 index 0000000000..34840c0e3b --- /dev/null +++ b/src/file_analysis/analyzers/PE.h @@ -0,0 +1,31 @@ +#ifndef FILE_ANALYSIS_PE_H +#define FILE_ANALYSIS_PE_H + +#include + +#include "Val.h" +#include "../Info.h" +#include "pe_pac.h" + +namespace file_analysis { + +/** + * An action to simply extract files to disk. + */ +class PE_Analyzer : Action { +public: + static Action* Instantiate(const RecordVal* args, Info* info); + + ~PE_Analyzer(); + + virtual void DeliverStream(const u_char* data, uint64 len); + +protected: + + PE_Analyzer(Info* arg_info); + binpac::PE::File* interp; +}; + +} // namespace file_analysis + +#endif diff --git a/src/file_analysis/analyzers/pe-analyzer.pac b/src/file_analysis/analyzers/pe-analyzer.pac new file mode 100644 index 0000000000..1a295f2d30 --- /dev/null +++ b/src/file_analysis/analyzers/pe-analyzer.pac @@ -0,0 +1,16 @@ + + +refine connection File += { + + function proc_sig(sig: bytestring) : bool + %{ + if ( strcmp("MZ", (const char *) ${sig}.data()) == 0 ) + printf("yep: %s\n", ${sig}.data()); + return true; + %} + +}; + +refine typeattr DOSStub += &let { + proc : bool = $context.connection.proc_sig(signature); +}; diff --git a/src/file_analysis/analyzers/pe-file.pac b/src/file_analysis/analyzers/pe-file.pac new file mode 100644 index 0000000000..4cec173ae3 --- /dev/null +++ b/src/file_analysis/analyzers/pe-file.pac @@ -0,0 +1,26 @@ + +type TheFile() = record { + barf: DOSStub; +} &byteorder=bigendian &length=-1; + +type DOSStub() = record { + signature : bytestring &length=2; + UsedBytesInTheLastPage : uint16; + FileSizeInPages : uint16; + NumberOfRelocationItems : uint16; + HeaderSizeInParagraphs : uint16; + MinimumExtraParagraphs : uint16; + MaximumExtraParagraphs : uint16; + InitialRelativeSS : uint16; + InitialSP : uint16; + Checksum : uint16; + InitialIP : uint16; + InitialRelativeCS : uint16; + AddressOfRelocationTable : uint16; + OverlayNumber : uint16; + Reserved : uint16[4]; + OEMid : uint16; + OEMinfo : uint16; + Reserved2 : uint16[10]; + AddressOfNewExeHeader : uint32; +} &byteorder=bigendian; \ No newline at end of file diff --git a/src/file_analysis/analyzers/pe.pac b/src/file_analysis/analyzers/pe.pac new file mode 100644 index 0000000000..be91643b21 --- /dev/null +++ b/src/file_analysis/analyzers/pe.pac @@ -0,0 +1,20 @@ +%include binpac.pac +%include bro.pac + +analyzer PE withcontext { + connection: File; + flow: Bytes; +}; + +connection File(bro_analyzer: BroFileAnalyzer) { + upflow = Bytes(true); + downflow = Bytes(false); +}; + +%include pe-file.pac + +flow Bytes(is_orig: bool) { + flowunit = TheFile() withcontext(connection, this); +} + +%include pe-analyzer.pac