How should I be calling an external script from Bro?

New to Bro. Trying to make sure I follow best practice here configuring it for my environment.

Currently Bro generates an email alert for HTTP::SQL_Injection_Attacker from detect-sqli.bro.

I wrote a python script to accept some parameters, including the attacker's IP that will put in a block at my firewall.

I was just going to tail Bro's notice.log and pull out the IP to feed my script anytime a SQL attack was logged there, but I figured it would be better to get Bro to do some of that lifting for me instead.

Being new to bro, I don't know how to do this.

I've googled around a bit and this is my best guess. (definitely a guess)

- Exec module is the best way to go about this?

- If so, I'm going to do what...make a something.bro file that basically says

@load base/utils/exec

when ( <something indicating SQL_Injection_Attacker> happens = Exec::run($cmd="myScript.py 55.66.77.88 -time 720") )

- Then I would @load something.bro in my local.bro file

Hi,

This repo has code in it that does everything you are trying to do:

https://github.com/ncsa/bhr-bro

You should be able to see how to modify it for your environment.

This video details how the Exec works:

https://www.youtube.com/watch?v=oo4zDC24xHU

Justin,

Thanks for the guidance, that got me on the right path.

Here's where I am:

IPBlock.bro
//
module IPBLOCK;

export
{
        redef enum Notice::Action +=
        {
                ACTION_IPBLOCK,
        };

const block_types: set[Notice::Type] = {} &redef;

}

hook Notice::policy(n: Notice::Info)
{
        add n$actions[ACTION_IPBLOCK];

        local cmd = string_cat("/usr/bin/python /usr/local/bro/share/bro/site/scripts/blockIP.py -a Bro -c 'SQL Injection' -t 72", n$src);

        local res = Exec::run([$cmd=cmd]);
}
//

local.bro
//
@load IPBlocker.bro

redef IPBLOCK::block_types +=
{
        HTTP::SQL_Injection_Attacker,
};
//

That's not quite right.. it may run, but it won't do what you want.

You're not looking at block_types inside the notice policy, so that is going to try to block every single host that sets off any notice.

See how in my notice policy the first thing I do is

hook Notice::policy(n: Notice::Info)
{
    if ( n$note !in block_types )
        return;

that prevents it from running for notice types that are not in block_types.

You also shouldn't hardcode SQL Injection, you should grab what is in n$note and use that for the message.

I think you are over thinking things with the when block. That line is just doing

    local res = Exec::run([$cmd=cmd, $stdin=stdin])

Just run is an asynchronous operation so it needs to be wrapped in a when ().