The More You Bro: Exec Utility

Hello again Bro Community, this is Jeannette
Dopheide, Bro Outreach Coordinator at the National Center for Supercomputing Applications
at the University of Illinois in Urbana-Champaign. In this episode of The More You Bro, I’m going
to show you the the basics of using Bro’s Exec utility. Those of you familiar with other programming
languages will see similarities with the Exec utility in its ability to allow you to execute
programs and scripts not included in the base language. While the sky is the limit with Exec, we’ll
go over some of its common uses. To start using the Exec utility, let’s create
a simple “hello world” script that also serves as a sanity check. In this example all we’re doing is writing
a script that let’s us verify that Bro was able to execute a program successfully. Here I am echoing the output “Hello World”
to a temp file. Now let’s create the program that will execute
our script. Here we’re initiating an event, which is to
run the hello.sh script we just created. And before we execute the script, let’s make
sure there is no hello file in the temp directory. And now we’ll run the script in Bro. And we see our script completed. Let’s check the temp file, and here it is
with the output of “Hello World!” Let’s do another version of “Hello World.” In this example we’re going to make two changes. First, we’ll make the script more portable
by removing the hardcoded path to the program. And second, we’ve converted our hello2.sh
program to read “Standard Input” which we will supply as a string from within Bro. Let’s go through these steps again. We’ll check the temp directory to confirm
the hello file isn’t there. And now we’ll run the hello2 script in Bro. And if we check the output in the temp directory
we can confirm the script completed successfully. Bro is configured monitor network traffic
passively, so it can’t block malicious traffic on its own. However, after Bro makes a decision about
an attacking IP, we can use the Exec utility to send the information to an external network
device, to change access control lists, or simply setup a black hole router. Let’s take that simple hello world script
and turn it into an IP blocking script. Here is our block.sh script. We’ll just double check that it’s executable. We can see that it is. Now we’ll create the program that will execute
the script we just wrote and we’ll call this block.bro. We’re starting with a function defined here to block a host. And we’re giving it an address, which we are
defining in bro_init using this simple address And we’re running the address against the
block function There’s a couple more things to note here. Here is the command execution record, which
shows the script we are going to execute and we put it inside of a format so we can send
it any arguments we need to. In this case it’s the host test address that
we’ve given our function. The result of the execution is going to be
stored in a local result record. And when it executes we can get the exit code. It’s also important to note that the when()
call forks off an asynchronous process and the code within that block will only execute
when the external command runs successfully. So let’s run this against a sample packet
capture. The result record will also contain standard-out
and standard-error as a vector of strings. Let’s go change our output format to a string. Now, instead of printing the exit code, we
see the first line of Standard Output. And if we run this again we see that it blocked
address, which is what we expected. We all know that issues with network connectivity
can occur. Let’s utilize the when() call to give us the
option to specify a timeout. We’ll add timeout of 4 seconds to the block.sh
script. Let’s add a timeout of 3 seconds to the block.bro
script. And we’ll have it print that it couldn’t wait any
longer for the function to finish. And then we’ll execute the Bro script again. Huh, it finished really fast. Since we’re running Bro against a pcap, which
happens a lot during testing, you’ll find that Bro exits on its own before the timeout
is supposed to occur. So let’s see what happens when we run it against
a live interface Okay, that it waited three seconds, broke out
of the process, and informed us it couldn’t wait any longer. A few more things to note about the block
script. The exact contents of the block.sh script
will vary depending on your environment, but many sites use a simple BGP peering. Also, black holing an IP is pretty aggressive. You’ll want to wrap some code around it
to make intelligent blocking decisions and failsafes. Such as not blocking systems local to your
network or systems you’ve setup to do vulnerability scanning on your own environment. For additional references, have a look at
base/utils/exec.bro to see what else is available in the Result and Command records. And whenever you’re executing a script logging
is recommended Thanks for watching our presentation on the
Exec utility. To learn more about using Bro you can check
out our website at bro.org. Follow us on Twitter @Bro_IDS. Or check out more talks and presentations
on our YouTube channel at youtube.com/user/BroPlatform.

Tags: , , , , ,

One Comment

  • Brett Neese says:

    I wanted to add a note here, because the tutorial doesn't make it at all clear until late into the video.

    If you're using a capture to run your "Hello World," you might need to do something like:

    `bro –pseudo-realtime=0.5 -r out.trace hello-world.bro`

    This is because Zeek will exit before it has a chance to run the script. The psuedo-realtime flags slows down the process by half.

    Also, if you want an even more simplified "hello world" – try this:

    “`event bro_init() {
    local cmd = "echo hello world";
    local command = Exec::Command($cmd=cmd);

    when (local result = Exec::run(command) ){
    print result;
    print "I did things!";

Leave a Reply

Your email address will not be published. Required fields are marked *