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 ().