[Bro] Dealing with tcp-based Unknown Protocols

Jon Siwek jsiwek at corelight.com
Wed Dec 13 12:14:23 PST 2017

On Tue, Dec 12, 2017 at 11:20 PM, Shuai Hao <haoscs at gmail.com> wrote:
>> event bro_init () {
>>     Log::create_stream(Unknown:LOG, ....)
>> }
>> hook disable_unknown() {
>>     Analyzer::disable_analyzer(Analyzer::ANALYZER_UNKNOWN)
>> }
>> event protocol_confirmation(c: connection, atype: Analyzer:Tag, aid:
>> count) {
>>    hook disable_unknown();
>> }
>> event Unknown_event(c: connection) {
>>    // unknown protocol process
>> }
> If we test with uncommon protocol trace and there is no corresponding
> protocol analyzer, the Unknown_Protocol Analyzer successfully captures the
> stream. However, this Analyzer::disable_analyzer() doesn't work here. With
> normal protocol traces, we still see the analyzer is processing the stream
> and produce the logs.

Yeah, Analyzer::disable_analyzer() doesn't seem like what you want (it
should disable the analyzer, but the not ones associated w/ current
connections, just future ones).

> Any ideas how this Analyzer::disable_analyzer() should be used in such
> scenario?

You might actually need to write your own function (unless I
misremember, it looks like Bro doesn't actually have a generic way to
do that from scripts), though it shouldn't be hard.  Basically I would
try turning your disable_unknown() function into a BIF (there's a
bunch of *.bif files you can use as reference).  E.g. an idea on how
the BIF code would look:

function disable_unknown%(c: connection%) : bool
    auto ua = c->GetRootAnalyzer()->FindChild(ANALYZER_UNKNOWN);

    if ( ! ua )
        return new Val(false, TYPE_BOOL);

    return new Val(true, TYPE_BOOL);

The RemoveChildAnalyzer() call then marks the analyzer as "removed"
and shouldn't receive any further stream data.

- Jon

More information about the Bro mailing list