Monday, September 13, 2010

Snort, BASE and Bigfix

If you are using Snort, BASE (Basic Analysis and Security Engine for viewing and managing Snort alerts) and you also have Bigfix, maybe you've wondered how to correlate events with the patch information from Bigfix. Often during IDS monitoring, I've wanted to verify that with an alert that is a potential attack, that the server or workstation in question is actually vulnerable to the attack, as a quick way to weed out false positives.

Bigfix provides a web-based interface to generate and access reports on all your assets reporting to Bigfix. Initially, I put a link in the IP details page of BASE (base_stat_ipaddr.php). See below:



This is the code I added to BASE's base_stat_ipaddr.php:

echo '&#60A HREF="http://bigfix.MyCompany.Corp/webreports?page=Report&ReportID=21&ComputerName=';
$bigfix_name = baseGetHostByAddr($ip, $db, $dns_cache_lifetime);
$bigfix_name = substr($bigfix_name,0,strpos($bigfix_name,'.'));
echo $bigfix_name.'" target="_NEW"> bigfix&#60/A> )';


The Bigfix Report that allows you to access computer properties by computer name is here (thanks to the help of the folks on the Bigfix forum!).

&#60html>
    &#60head>
        &#60script type="text/javascript">
            addEvent(window, "load", search);

            var qsParm = new Array();
            
            function qs() {
                var query = window.location.search.substring(1);
                var parms = query.split('&');
                for (var i = 0; i < parms.length; i++) {
                    var pos = parms[i].indexOf('=');
                    if (pos > 0) {
                        var key = parms[i].substring(0, pos);
                        var val = parms[i].substring(pos + 1);
                        qsParm[key] = val;
                    }
                }
            }
 
            function search(){
                qs();
                var rel = '((database name of bes deployment options) & "%252f" & id of it as string) of bes computer whose (name of it as lowercase = "' + qsParm['ComputerName'].toLowerCase() + '")';
                strResponse = EvaluateRelevance(rel);
                window.location = "http://bigfix.MyCompany.Corp/webreports?page=SingleComputerReport&ComputerName=" + strResponse + "&PropertyFilter=";
            }
            
            function addEvent(elm, evType, fn, useCapture)
            {
                if (elm.addEventListener) {
                    elm.addEventListener(evType, fn, useCapture);
                    return true;
                }
                else 
                    if (elm.attachEvent) {
                        var r = elm.attachEvent("on" + evType, fn);
                        return r;
                    }
                    else {
                        alert("Handler could not be removed");
                }
            }

        &#60/script>
    &#60/head>
    &#60body>
        &#60p>This page is intended to be accessed via a directing URL...

        Format:&#60br>
        http://[server]:[port]/webreports?page=Report&ReportID=[report_id]&ComputerName=[computer_name]

&#60/body>
&#60/html>


This helped make the process a bit faster, but I still needed to logon to WebReports the first time I clicked the link, and it displayed the report in a seperate window. A couple of clicks for each computer I wanted to look at, was alright, but still not quite what I wanted.

Bigfix also includes a SOAP API interface to WebReports. Taking a look at this, it appeared that this is exactly what I wanted. With SOAP, I could query the Bigfix WebReports and return only the relevant fixlets (outstanding patches) for the computer in question, and display them right on the BASE page. After doing some research and stealing various scripts from the Bigfix forums (an awesome resource for Bigfix, check it out!) This is much easier to do than at first glance.



Just before the PrintBASESubFooter(); call in base_stat_ipaddr.php I inserted this code:

include_once("$BASE_path/bigfixsoap.php");


Which includes the php code to do the SOAP call to the Bigfix Web Reports server (shown below).

&#60?php
$client = new SoapClient(NULL,
        array(
        "location" => "http://bigfix.mycompany.corp/webreports",
        "uri"      => "http://schemas.bigfix.com/Relevance",
        "style"    => SOAP_RPC,
        "use"      => SOAP_ENCODED,
        "trace"         => 1));

$relevance = '("&#60TD>" & item 0 of item 1 of it & "&#60/TD>&#60TD>" & item 1 of item 1 of it & "&#60/TD>&#60TD>" & item 2 of item 1 of it & "&#60/TD>") of (name of it, (name of it, (if source severity of it = "" then "Unspecified" else source severity of it), (if (exists CVE ID LIST of it) then (CVE ID LIST of it as string) else ("None"))) of relevant fixlets whose ((name of site of it = "Enterprise Security"  OR name of site of it = "Updates for Windows Applications") and fixlet flag of it = true) of it) of bes computers whose (name of it as lowercase = "'.$bigfix_name.'")';

$results = ($client->__soapcall(
        /* SOAP Method Name */
        "GetRelevanceResult",
        /* Parameters */
        array(
            new SoapParam($relevance, "relevanceExpr"),
            new SoapParam("replacewithusername", "username"),
            new SoapParam("replacewithpassword", "password")
            ),
        array(
            /* SOAP Method Namespace */
            "uri" => "http://schemas.bigfix.com/Relevance",
            /* SOAPAction HTTP Header for SOAP Method */
            "soapaction" => "http://schemas.bigfix.com/Relevance/GetRelevanceResult")). "\n");
   
    $str = ($client->__getLastResponse());   
    $str = str_replace("", " ", $str);
    $str = str_replace("", " ", $str);
    $str = str_replace("", "", $str);
    $str = str_replace("", " ", $str);
    $str = str_replace("", " ", $str);
    $xml = simplexml_load_string($str);

    if (!empty($xml)) {
      echo '&#60CENTER>&#60TABLE width="100%" border=1>&#60TR>&#60TD CLASS="plfieldhdr">Fixlet&#60/TD>&#60TD CLASS="plfieldhdr">Severity&#60/TD>&#60TD CLASS="plfieldhdr">CVE ID&#60/TD>&#60/TR>';
      foreach($xml as $soapresponse){
        echo '&#60TR>'.$soapresponse.'&#60/TR>';}
      echo '&#60/TABLE>';
    }  
?>


Much better! Now it's very easy to see if a particular machine is vulnerable to an attack, or whether it should be classified as a false positive.

PS. If you want me to send you the files required, or need help hacking this into BASE yourself, please send me an email.