API changes to file analysis mime type detection.

Removed "file_mime_type" and "file_mime_types" event, replacing them
with a new event called "file_metadata_inferred".  It has a record
argument of type "inferred_file_metadata", which contains the mime type
information that the earlier events used to supply.  The idea here is
that future extensions to the record with new metadata will be less
likely to break user code than the alternatives (adding new events or
new event parameters).

Addresses BIT-1368.
This commit is contained in:
Jon Siwek 2015-04-10 16:26:06 -05:00
parent bd1191c60b
commit a55ce01ef3
20 changed files with 170 additions and 136 deletions

15
NEWS
View file

@ -79,14 +79,17 @@ Changed Functionality
- File analysis - File analysis
* Removed ``fa_file`` record's ``mime_type`` and ``mime_types`` * Removed ``fa_file`` record's ``mime_type`` and ``mime_types``
fields. The events ``file_mime_type`` and ``file_mime_types`` fields. The event ``file_metadata_inferred`` has been added
have been added which contain the same information. The which contain the same information. The ``mime_type`` field of
``mime_type`` field of ``Files::Info`` also still has this info. ``Files::Info`` also still has this info.
* The earliest point that new mime type information is available is * The earliest point that new mime type information is available is
in the ``file_mime_type`` event which comes after the ``file_new`` in the ``file_metadata_inferred`` event which comes after the
and ``file_over_new_connection`` events. Scripts which inspected ``file_new`` and ``file_over_new_connection`` events. Scripts
mime type info within those events will need to be adapted. which inspected mime type info within those events will need to be
adapted. (Note: for users that worked w/ versions of Bro from git,
there was also an event called ``file_mime_type`` which is now
replaced be the ``file_metadata_inferred`` event).
* Removed ``Files::add_analyzers_for_mime_type`` function. * Removed ``Files::add_analyzers_for_mime_type`` function.

View file

@ -1,7 +1,8 @@
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( ! meta?$mime_type ) return;
print "new file", f$id; print "new file", f$id;
if ( mime_type == "text/plain" ) if ( meta$mime_type == "text/plain" )
Files::add_analyzer(f, Files::ANALYZER_MD5); Files::add_analyzer(f, Files::ANALYZER_MD5);
} }

View file

@ -7,15 +7,18 @@ global mime_to_ext: table[string] of string = {
["text/html"] = "html", ["text/html"] = "html",
}; };
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( f$source != "HTTP" ) if ( f$source != "HTTP" )
return; return;
if ( mime_type !in mime_to_ext ) if ( ! meta?$mime_type )
return; return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[mime_type]); if ( meta$mime_type !in mime_to_ext )
return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[meta$mime_type]);
print fmt("Extracting file %s", fname); print fmt("Extracting file %s", fname);
Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]); Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]);
} }

View file

@ -484,16 +484,19 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
add f$info$rx_hosts[f$is_orig ? cid$resp_h : cid$orig_h]; add f$info$rx_hosts[f$is_orig ? cid$resp_h : cid$orig_h];
} }
event file_mime_type(f: fa_file, mime_type: string) &priority=10 event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata) &priority=10
{ {
set_info(f); set_info(f);
f$info$mime_type = mime_type; if ( ! meta?$mime_type )
return;
f$info$mime_type = meta$mime_type;
if ( analyze_by_mime_type_automatically && if ( analyze_by_mime_type_automatically &&
mime_type in mime_type_to_analyzers ) meta$mime_type in mime_type_to_analyzers )
{ {
local analyzers = mime_type_to_analyzers[mime_type]; local analyzers = mime_type_to_analyzers[meta$mime_type];
for ( a in analyzers ) for ( a in analyzers )
{ {
add f$info$analyzers[Files::analyzer_name(a)]; add f$info$analyzers[Files::analyzer_name(a)];

View file

@ -414,6 +414,14 @@ type fa_file: record {
bof_buffer: string &optional; bof_buffer: string &optional;
} &redef; } &redef;
## Metadata that's been inferred about a particular file.
type inferred_file_metadata: record {
## The strongest matching mime type if one was discovered.
mime_type: string &optional;
## All matching mime types if any were discovered.
mime_types: mime_matches &optional;
};
## Fields of a SYN packet. ## Fields of a SYN packet.
## ##
## .. bro:see:: connection_SYN_packet ## .. bro:see:: connection_SYN_packet

View file

@ -63,10 +63,13 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
f$ftp = ftp; f$ftp = ftp;
} }
event file_mime_type(f: fa_file, mime_type: string) &priority=5 event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata) &priority=5
{ {
if ( ! f?$ftp ) if ( ! f?$ftp )
return; return;
f$ftp$mime_type = mime_type; if ( ! meta?$mime_type )
return;
f$ftp$mime_type = meta$mime_type;
} }

View file

@ -93,24 +93,27 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
} }
} }
event file_mime_type(f: fa_file, mime_type: string) &priority=5 event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata) &priority=5
{ {
if ( ! f?$http || ! f?$is_orig ) if ( ! f?$http || ! f?$is_orig )
return; return;
if ( ! meta?$mime_type )
return;
if ( f$is_orig ) if ( f$is_orig )
{ {
if ( ! f$http?$orig_mime_types ) if ( ! f$http?$orig_mime_types )
f$http$orig_mime_types = string_vec(mime_type); f$http$orig_mime_types = string_vec(meta$mime_type);
else else
f$http$orig_mime_types[|f$http$orig_mime_types|] = mime_type; f$http$orig_mime_types[|f$http$orig_mime_types|] = meta$mime_type;
} }
else else
{ {
if ( ! f$http?$resp_mime_types ) if ( ! f$http?$resp_mime_types )
f$http$resp_mime_types = string_vec(mime_type); f$http$resp_mime_types = string_vec(meta$mime_type);
else else
f$http$resp_mime_types[|f$http$resp_mime_types|] = mime_type; f$http$resp_mime_types[|f$http$resp_mime_types|] = meta$mime_type;
} }
} }

View file

@ -42,8 +42,8 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
f$irc = irc; f$irc = irc;
} }
event file_mime_type(f: fa_file, mime_type: string) &priority=5 event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata) &priority=5
{ {
if ( f?$irc ) if ( f?$irc && meta?$mime_type )
f$irc$dcc_mime_type = mime_type; f$irc$dcc_mime_type = meta$mime_type;
} }

View file

@ -10,6 +10,7 @@ RecordType* endpoint;
RecordType* endpoint_stats; RecordType* endpoint_stats;
RecordType* connection_type; RecordType* connection_type;
RecordType* fa_file_type; RecordType* fa_file_type;
RecordType* inferred_file_metadata_type;
RecordType* icmp_conn; RecordType* icmp_conn;
RecordType* icmp_context; RecordType* icmp_context;
RecordType* SYN_packet; RecordType* SYN_packet;
@ -316,6 +317,7 @@ void init_net_var()
endpoint_stats = internal_type("endpoint_stats")->AsRecordType(); endpoint_stats = internal_type("endpoint_stats")->AsRecordType();
connection_type = internal_type("connection")->AsRecordType(); connection_type = internal_type("connection")->AsRecordType();
fa_file_type = internal_type("fa_file")->AsRecordType(); fa_file_type = internal_type("fa_file")->AsRecordType();
inferred_file_metadata_type = internal_type("inferred_file_metadata")->AsRecordType();
icmp_conn = internal_type("icmp_conn")->AsRecordType(); icmp_conn = internal_type("icmp_conn")->AsRecordType();
icmp_context = internal_type("icmp_context")->AsRecordType(); icmp_context = internal_type("icmp_context")->AsRecordType();
signature_state = internal_type("signature_state")->AsRecordType(); signature_state = internal_type("signature_state")->AsRecordType();

View file

@ -13,6 +13,7 @@ extern RecordType* endpoint;
extern RecordType* endpoint_stats; extern RecordType* endpoint_stats;
extern RecordType* connection_type; extern RecordType* connection_type;
extern RecordType* fa_file_type; extern RecordType* fa_file_type;
extern RecordType* inferred_file_metadata_type;
extern RecordType* icmp_conn; extern RecordType* icmp_conn;
extern RecordType* icmp_context; extern RecordType* icmp_context;
extern RecordType* signature_state; extern RecordType* signature_state;

View file

@ -905,8 +905,8 @@ event get_file_handle%(tag: Analyzer::Tag, c: connection, is_orig: bool%);
## ##
## f: The file. ## f: The file.
## ##
## .. bro:see:: file_over_new_connection file_timeout file_gap file_mime_type ## .. bro:see:: file_over_new_connection file_timeout file_gap
## file_state_remove ## file_metadata_inferred file_state_remove
event file_new%(f: fa_file%); event file_new%(f: fa_file%);
## Indicates that a file has been seen being transferred over a connection ## Indicates that a file has been seen being transferred over a connection
@ -918,39 +918,30 @@ event file_new%(f: fa_file%);
## ##
## is_orig: true if the originator of *c* is the one sending the file. ## is_orig: true if the originator of *c* is the one sending the file.
## ##
## .. bro:see:: file_new file_timeout file_gap file_mime_type ## .. bro:see:: file_new file_timeout file_gap file_metadata_inferred
## file_state_remove ## file_state_remove
event file_over_new_connection%(f: fa_file, c: connection, is_orig: bool%); event file_over_new_connection%(f: fa_file, c: connection, is_orig: bool%);
## Provide the most likely matching MIME type for this file. The analysis ## Provide all metadata that has been inferred about a particular file
## can be augmented at this time via :bro:see:`Files::add_analyzer`. ## from inspection of the initial content that been seen at the beginning
## of the file. The analysis can be augmented at this time via
## :bro:see:`Files::add_analyzer`.
## ##
## f: The file. ## f: The file.
## ##
## mime_type: The mime type that was discovered. ## meta: Metadata that's been discovered about the file.
## ##
## .. bro:see:: file_over_new_connection file_timeout file_gap file_mime_type ## .. bro:see:: file_over_new_connection file_timeout file_gap
## file_mime_types file_state_remove ## file_state_remove
event file_mime_type%(f: fa_file, mime_type: string%); event file_metadata_inferred%(f: fa_file, meta: inferred_file_metadata%);
## Provide all matching MIME types for this file. The analysis can be
## augmented at this time via :bro:see:`Files::add_analyzer`.
##
## f: The file.
##
## mime_types: The mime types that were discovered.
##
## .. bro:see:: file_over_new_connection file_timeout file_gap file_mime_type
## file_mime_types file_state_remove
event file_mime_types%(f: fa_file, mime_types: mime_matches%);
## Indicates that file analysis has timed out because no activity was seen ## Indicates that file analysis has timed out because no activity was seen
## for the file in a while. ## for the file in a while.
## ##
## f: The file. ## f: The file.
## ##
## .. bro:see:: file_new file_over_new_connection file_gap file_mime_type ## .. bro:see:: file_new file_over_new_connection file_gap
## file_mime_types file_state_remove default_file_timeout_interval ## file_metadata_inferred file_state_remove default_file_timeout_interval
## Files::set_timeout_interval ## Files::set_timeout_interval
event file_timeout%(f: fa_file%); event file_timeout%(f: fa_file%);
@ -962,8 +953,8 @@ event file_timeout%(f: fa_file%);
## ##
## len: The number of missing bytes. ## len: The number of missing bytes.
## ##
## .. bro:see:: file_new file_over_new_connection file_timeout file_mime_type ## .. bro:see:: file_new file_over_new_connection file_timeout
## file_mime_types file_state_remove file_reassembly_overflow ## file_metadata_inferred file_state_remove file_reassembly_overflow
event file_gap%(f: fa_file, offset: count, len: count%); event file_gap%(f: fa_file, offset: count, len: count%);
## Indicates that the file had an overflow of the reassembly buffer. ## Indicates that the file had an overflow of the reassembly buffer.
@ -978,10 +969,11 @@ event file_gap%(f: fa_file, offset: count, len: count%);
## file data and get back under the reassembly buffer size limit. ## file data and get back under the reassembly buffer size limit.
## This value will also be represented as a gap. ## This value will also be represented as a gap.
## ##
## .. bro:see:: file_new file_over_new_connection file_timeout file_mime_type ## .. bro:see:: file_new file_over_new_connection file_timeout
## file_mime_types file_state_remove file_gap Files::enable_reassembler ## file_metadata_inferred file_state_remove file_gap
## Files::reassembly_buffer_size Files::enable_reassembly ## Files::enable_reassembler Files::reassembly_buffer_size
## Files::disable_reassembly Files::set_reassembly_buffer_size ## Files::enable_reassembly Files::disable_reassembly
## Files::set_reassembly_buffer_size
event file_reassembly_overflow%(f: fa_file, offset: count, skipped: count%); event file_reassembly_overflow%(f: fa_file, offset: count, skipped: count%);
## This event is generated each time file analysis is ending for a given file. ## This event is generated each time file analysis is ending for a given file.
@ -989,7 +981,7 @@ event file_reassembly_overflow%(f: fa_file, offset: count, skipped: count%);
## f: The file. ## f: The file.
## ##
## .. bro:see:: file_new file_over_new_connection file_timeout file_gap ## .. bro:see:: file_new file_over_new_connection file_timeout file_gap
## file_mime_type file_mime_types ## file_metadata_inferred
event file_state_remove%(f: fa_file%); event file_state_remove%(f: fa_file%);
## Generated when an internal DNS lookup produces the same result as last time. ## Generated when an internal DNS lookup produces the same result as last time.

View file

@ -53,31 +53,35 @@ int File::overflow_bytes_idx = -1;
int File::timeout_interval_idx = -1; int File::timeout_interval_idx = -1;
int File::bof_buffer_size_idx = -1; int File::bof_buffer_size_idx = -1;
int File::bof_buffer_idx = -1; int File::bof_buffer_idx = -1;
int File::meta_mime_type_idx = -1;
int File::meta_mime_types_idx = -1;
void File::StaticInit() void File::StaticInit()
{ {
if ( id_idx != -1 ) if ( id_idx != -1 )
return; return;
id_idx = Idx("id"); id_idx = Idx("id", fa_file_type);
parent_id_idx = Idx("parent_id"); parent_id_idx = Idx("parent_id", fa_file_type);
source_idx = Idx("source"); source_idx = Idx("source", fa_file_type);
is_orig_idx = Idx("is_orig"); is_orig_idx = Idx("is_orig", fa_file_type);
conns_idx = Idx("conns"); conns_idx = Idx("conns", fa_file_type);
last_active_idx = Idx("last_active"); last_active_idx = Idx("last_active", fa_file_type);
seen_bytes_idx = Idx("seen_bytes"); seen_bytes_idx = Idx("seen_bytes", fa_file_type);
total_bytes_idx = Idx("total_bytes"); total_bytes_idx = Idx("total_bytes", fa_file_type);
missing_bytes_idx = Idx("missing_bytes"); missing_bytes_idx = Idx("missing_bytes", fa_file_type);
overflow_bytes_idx = Idx("overflow_bytes"); overflow_bytes_idx = Idx("overflow_bytes", fa_file_type);
timeout_interval_idx = Idx("timeout_interval"); timeout_interval_idx = Idx("timeout_interval", fa_file_type);
bof_buffer_size_idx = Idx("bof_buffer_size"); bof_buffer_size_idx = Idx("bof_buffer_size", fa_file_type);
bof_buffer_idx = Idx("bof_buffer"); bof_buffer_idx = Idx("bof_buffer", fa_file_type);
meta_mime_type_idx = Idx("mime_type", inferred_file_metadata_type);
meta_mime_types_idx = Idx("mime_types", inferred_file_metadata_type);
} }
File::File(const string& file_id, const string& source_name, Connection* conn, File::File(const string& file_id, const string& source_name, Connection* conn,
analyzer::Tag tag, bool is_orig) analyzer::Tag tag, bool is_orig)
: id(file_id), val(0), file_reassembler(0), stream_offset(0), : id(file_id), val(0), file_reassembler(0), stream_offset(0),
reassembly_max_buffer(0), did_mime_type(false), reassembly_max_buffer(0), did_metadata_inference(false),
reassembly_enabled(false), postpone_timeout(false), done(false), reassembly_enabled(false), postpone_timeout(false), done(false),
analyzers(this) analyzers(this)
{ {
@ -169,11 +173,13 @@ double File::LookupFieldDefaultInterval(int idx) const
return rval; return rval;
} }
int File::Idx(const string& field) int File::Idx(const string& field, const RecordType* type)
{ {
int rval = fa_file_type->FieldOffset(field.c_str()); int rval = type->FieldOffset(field.c_str());
if ( rval < 0 ) if ( rval < 0 )
reporter->InternalError("Unknown fa_file field: %s", field.c_str()); reporter->InternalError("Unknown %s field: %s", type->GetName().c_str(),
field.c_str());
return rval; return rval;
} }
@ -281,48 +287,46 @@ void File::SetReassemblyBuffer(uint64 max)
reassembly_max_buffer = max; reassembly_max_buffer = max;
} }
bool File::DetectMIME() void File::InferMetadata()
{ {
did_mime_type = true; did_metadata_inference = true;
Val* bof_buffer_val = val->Lookup(bof_buffer_idx); Val* bof_buffer_val = val->Lookup(bof_buffer_idx);
if ( ! bof_buffer_val ) if ( ! bof_buffer_val )
{ {
if ( bof_buffer.size == 0 ) if ( bof_buffer.size == 0 )
return false; return;
BroString* bs = concatenate(bof_buffer.chunks); BroString* bs = concatenate(bof_buffer.chunks);
bof_buffer_val = new StringVal(bs); bof_buffer_val = new StringVal(bs);
val->Assign(bof_buffer_idx, bof_buffer_val); val->Assign(bof_buffer_idx, bof_buffer_val);
} }
if ( ! FileEventAvailable(file_metadata_inferred) )
return;
RuleMatcher::MIME_Matches matches; RuleMatcher::MIME_Matches matches;
const u_char* data = bof_buffer_val->AsString()->Bytes(); const u_char* data = bof_buffer_val->AsString()->Bytes();
uint64 len = bof_buffer_val->AsString()->Len(); uint64 len = bof_buffer_val->AsString()->Len();
len = min(len, LookupFieldDefaultCount(bof_buffer_size_idx)); len = min(len, LookupFieldDefaultCount(bof_buffer_size_idx));
file_mgr->DetectMIME(data, len, &matches); file_mgr->DetectMIME(data, len, &matches);
if ( matches.empty() ) val_list* vl = new val_list();
return false; vl->append(val->Ref());
RecordVal* meta = new RecordVal(inferred_file_metadata_type);
vl->append(meta);
if ( FileEventAvailable(file_mime_type) ) if ( ! matches.empty() )
{ {
val_list* vl = new val_list(); meta->Assign(meta_mime_type_idx,
vl->append(val->Ref()); new StringVal(*(matches.begin()->second.begin())));
vl->append(new StringVal(*(matches.begin()->second.begin()))); meta->Assign(meta_mime_types_idx,
FileEvent(file_mime_type, vl); file_analysis::GenMIMEMatchesVal(matches));
} }
if ( FileEventAvailable(file_mime_types) ) FileEvent(file_metadata_inferred, vl);
{ return;
val_list* vl = new val_list();
vl->append(val->Ref());
vl->append(file_analysis::GenMIMEMatchesVal(matches));
FileEvent(file_mime_types, vl);
}
return true;
} }
bool File::BufferBOF(const u_char* data, uint64 len) bool File::BufferBOF(const u_char* data, uint64 len)
@ -355,9 +359,9 @@ void File::DeliverStream(const u_char* data, uint64 len)
// Buffer enough data for the BOF buffer // Buffer enough data for the BOF buffer
BufferBOF(data, len); BufferBOF(data, len);
if ( ! did_mime_type && bof_buffer.full && if ( ! did_metadata_inference && bof_buffer.full &&
LookupFieldDefaultCount(missing_bytes_idx) == 0 ) LookupFieldDefaultCount(missing_bytes_idx) == 0 )
DetectMIME(); InferMetadata();
DBG_LOG(DBG_FILE_ANALYSIS, DBG_LOG(DBG_FILE_ANALYSIS,
"[%s] %" PRIu64 " stream bytes in at offset %" PRIu64 "; %s [%s%s]", "[%s] %" PRIu64 " stream bytes in at offset %" PRIu64 "; %s [%s%s]",
@ -582,7 +586,7 @@ void File::FileEvent(EventHandlerPtr h, val_list* vl)
mgr.QueueEvent(h, vl); mgr.QueueEvent(h, vl);
if ( h == file_new || h == file_over_new_connection || if ( h == file_new || h == file_over_new_connection ||
h == file_mime_type || h == file_metadata_inferred ||
h == file_timeout || h == file_extraction_limit ) h == file_timeout || h == file_extraction_limit )
{ {
// immediate feedback is required for these events. // immediate feedback is required for these events.

View file

@ -230,12 +230,11 @@ protected:
bool BufferBOF(const u_char* data, uint64 len); bool BufferBOF(const u_char* data, uint64 len);
/** /**
* Does mime type detection via file magic signatures and assigns * Does metadata inference (e.g. mime type detection via file
* strongest matching mime type (if available) to \c mime_type * magic signatures) using data in the BOF (beginning-of-file) buffer
* field in #val. It uses the data in the BOF buffer. * and raises an event with the metadata.
* @return whether a mime type match was found.
*/ */
bool DetectMIME(); void InferMetadata();
/** /**
* Enables reassembly on the file. * Enables reassembly on the file.
@ -266,10 +265,11 @@ protected:
/** /**
* Lookup a record field index/offset by name. * Lookup a record field index/offset by name.
* @param field_name the name of the \c fa_file record field. * @param field_name the name of the record field.
* @param type the record type for which the field will be looked up.
* @return the field offset in #val record corresponding to \a field_name. * @return the field offset in #val record corresponding to \a field_name.
*/ */
static int Idx(const string& field_name); static int Idx(const string& field_name, const RecordType* type);
/** /**
* Initializes static member. * Initializes static member.
@ -282,7 +282,7 @@ protected:
FileReassembler* file_reassembler; /**< A reassembler for the file if it's needed. */ FileReassembler* file_reassembler; /**< A reassembler for the file if it's needed. */
uint64 stream_offset; /**< The offset of the file which has been forwarded. */ uint64 stream_offset; /**< The offset of the file which has been forwarded. */
uint64 reassembly_max_buffer; /**< Maximum allowed buffer for reassembly. */ uint64 reassembly_max_buffer; /**< Maximum allowed buffer for reassembly. */
bool did_mime_type; /**< Whether the mime type ident has already been attempted. */ bool did_metadata_inference; /**< Whether the metadata inference has already been attempted. */
bool reassembly_enabled; /**< Whether file stream reassembly is needed. */ bool reassembly_enabled; /**< Whether file stream reassembly is needed. */
bool postpone_timeout; /**< Whether postponing timeout is requested. */ bool postpone_timeout; /**< Whether postponing timeout is requested. */
bool done; /**< If this object is about to be deleted. */ bool done; /**< If this object is about to be deleted. */
@ -313,6 +313,9 @@ protected:
static int bof_buffer_idx; static int bof_buffer_idx;
static int mime_type_idx; static int mime_type_idx;
static int mime_types_idx; static int mime_types_idx;
static int meta_mime_type_idx;
static int meta_mime_types_idx;
}; };
} // namespace file_analysis } // namespace file_analysis

View file

@ -2,10 +2,11 @@
file_analysis_02.bro file_analysis_02.bro
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( ! meta?$mime_type ) return;
print "new file", f$id; print "new file", f$id;
if ( mime_type == "text/plain" ) if ( meta$mime_type == "text/plain" )
Files::add_analyzer(f, Files::ANALYZER_MD5); Files::add_analyzer(f, Files::ANALYZER_MD5);
} }

View file

@ -11,15 +11,18 @@ global mime_to_ext: table[string] of string = {
["text/html"] = "html", ["text/html"] = "html",
}; };
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( f$source != "HTTP" ) if ( f$source != "HTTP" )
return; return;
if ( mime_type !in mime_to_ext ) if ( ! meta?$mime_type )
return; return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[mime_type]); if ( meta$mime_type !in mime_to_ext )
return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[meta$mime_type]);
print fmt("Extracting file %s", fname); print fmt("Extracting file %s", fname);
Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]); Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]);
} }

View file

@ -201,7 +201,7 @@
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result>
@ -298,7 +298,7 @@
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(PacketFilter::build, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(PacketFilter::build, <frame>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, <frame>, (ip or not ip, and, )) -> <no result> 0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, <frame>, (ip or not ip, and, )) -> <no result>
@ -754,7 +754,7 @@
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG))
@ -851,7 +851,7 @@
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ())
0.000000 MetaHookPre CallFunction(PacketFilter::build, <frame>, ()) 0.000000 MetaHookPre CallFunction(PacketFilter::build, <frame>, ())
0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, <frame>, (ip or not ip, and, )) 0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, <frame>, (ip or not ip, and, ))
@ -1306,7 +1306,7 @@
0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG)
@ -1403,7 +1403,7 @@
0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1427751587.816777, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1428700698.322438, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction Notice::want_pp()
0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::build()
0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, )
@ -1770,7 +1770,7 @@
1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> <no result>
1362692527.009775 MetaHookPost CallFunction(file_mime_type, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(file_metadata_inferred, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> <no result>
1362692527.009775 MetaHookPost CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> <no result>
@ -1779,7 +1779,7 @@
1362692527.009775 MetaHookPost CallFunction(id_string, <frame>, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(id_string, <frame>, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(set_file_handle, <frame>, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(set_file_handle, <frame>, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> <no result>
1362692527.009775 MetaHookPost DrainEvents() -> <void> 1362692527.009775 MetaHookPost DrainEvents() -> <void>
1362692527.009775 MetaHookPost QueueEvent(file_mime_type([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -> false 1362692527.009775 MetaHookPost QueueEvent(file_metadata_inferred([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) -> false
1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) -> false 1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) -> false
1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false
1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false
@ -1795,7 +1795,7 @@
1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>])) 1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>]))
1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) 1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]))
1362692527.009775 MetaHookPre CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) 1362692527.009775 MetaHookPre CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80))
1362692527.009775 MetaHookPre CallFunction(file_mime_type, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) 1362692527.009775 MetaHookPre CallFunction(file_metadata_inferred, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]]))
1362692527.009775 MetaHookPre CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) 1362692527.009775 MetaHookPre CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>]))
1362692527.009775 MetaHookPre CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) 1362692527.009775 MetaHookPre CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp))
1362692527.009775 MetaHookPre CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
@ -1804,7 +1804,7 @@
1362692527.009775 MetaHookPre CallFunction(id_string, <frame>, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) 1362692527.009775 MetaHookPre CallFunction(id_string, <frame>, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp]))
1362692527.009775 MetaHookPre CallFunction(set_file_handle, <frame>, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) 1362692527.009775 MetaHookPre CallFunction(set_file_handle, <frame>, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80))
1362692527.009775 MetaHookPre DrainEvents() 1362692527.009775 MetaHookPre DrainEvents()
1362692527.009775 MetaHookPre QueueEvent(file_mime_type([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) 1362692527.009775 MetaHookPre QueueEvent(file_metadata_inferred([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]]))
1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])) 1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>]))
1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
1362692527.009775 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
@ -1821,7 +1821,7 @@
1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>]) 1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>])
1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]) 1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])
1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) 1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)
1362692527.009775 | HookCallFunction file_mime_type([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain) 1362692527.009775 | HookCallFunction file_metadata_inferred([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])
1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>]) 1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])
1362692527.009775 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) 1362692527.009775 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)
1362692527.009775 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)
@ -1830,7 +1830,7 @@
1362692527.009775 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) 1362692527.009775 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp])
1362692527.009775 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80) 1362692527.009775 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)
1362692527.009775 | HookDrainEvents 1362692527.009775 | HookDrainEvents
1362692527.009775 | HookQueueEvent file_mime_type([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain) 1362692527.009775 | HookQueueEvent file_metadata_inferred([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])
1362692527.009775 | HookQueueEvent file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>]) 1362692527.009775 | HookQueueEvent file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, u2_events=<uninitialized>])
1362692527.009775 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)
1362692527.009775 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)

View file

@ -59,7 +59,7 @@
1254722770.692743 file_over_new_connection 1254722770.692743 file_over_new_connection
1254722770.692743 mime_end_entity 1254722770.692743 mime_end_entity
1254722770.692743 get_file_handle 1254722770.692743 get_file_handle
1254722770.692743 file_mime_type 1254722770.692743 file_metadata_inferred
1254722770.692743 file_state_remove 1254722770.692743 file_state_remove
1254722770.692743 get_file_handle 1254722770.692743 get_file_handle
1254722770.692743 mime_begin_entity 1254722770.692743 mime_begin_entity
@ -70,7 +70,7 @@
1254722770.692743 file_over_new_connection 1254722770.692743 file_over_new_connection
1254722770.692804 mime_end_entity 1254722770.692804 mime_end_entity
1254722770.692804 get_file_handle 1254722770.692804 get_file_handle
1254722770.692804 file_mime_type 1254722770.692804 file_metadata_inferred
1254722770.692804 file_state_remove 1254722770.692804 file_state_remove
1254722770.692804 get_file_handle 1254722770.692804 get_file_handle
1254722770.692804 mime_end_entity 1254722770.692804 mime_end_entity
@ -84,7 +84,7 @@
1254722770.692804 file_new 1254722770.692804 file_new
1254722770.692804 file_over_new_connection 1254722770.692804 file_over_new_connection
1254722770.695115 new_connection 1254722770.695115 new_connection
1254722771.494181 file_mime_type 1254722771.494181 file_metadata_inferred
1254722771.858334 mime_end_entity 1254722771.858334 mime_end_entity
1254722771.858334 get_file_handle 1254722771.858334 get_file_handle
1254722771.858334 file_state_remove 1254722771.858334 file_state_remove

File diff suppressed because one or more lines are too long

View file

@ -2,10 +2,11 @@
file_analysis_02.bro file_analysis_02.bro
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( ! meta?$mime_type ) return;
print "new file", f$id; print "new file", f$id;
if ( mime_type == "text/plain" ) if ( meta$mime_type == "text/plain" )
Files::add_analyzer(f, Files::ANALYZER_MD5); Files::add_analyzer(f, Files::ANALYZER_MD5);
} }

View file

@ -11,15 +11,18 @@ global mime_to_ext: table[string] of string = {
["text/html"] = "html", ["text/html"] = "html",
}; };
event file_mime_type(f: fa_file, mime_type: string) event file_metadata_inferred(f: fa_file, meta: inferred_file_metadata)
{ {
if ( f$source != "HTTP" ) if ( f$source != "HTTP" )
return; return;
if ( mime_type !in mime_to_ext ) if ( ! meta?$mime_type )
return; return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[mime_type]); if ( meta$mime_type !in mime_to_ext )
return;
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[meta$mime_type]);
print fmt("Extracting file %s", fname); print fmt("Extracting file %s", fname);
Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]); Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]);
} }