[Snort-devel] Reference information in rules revisited

Joe McAlerney joey at ...63...
Thu Oct 26 21:53:46 EDT 2000


Hello all,

I thought of a clean way to link rules to ID numbers for various
vulnerability and attack signature databases.  I wrote up a little
plugin that basically lets you specify ID types, and an associated ID
number in a Snort rule.  Output plugins can then map alerts to places to
find additional information.  The plugin currently supports Bugtraq, CVE
(and CAN), and arachNIDS ID's.  It is simple to add additional ID types,
so proprietary identification systems can be plugged in with ease.

Here are a few rule examples using the keywords provided by this plugin:

   alert TCP any any -> any 80 (msg: "IDS128/web-cgi-phf"; flags: AP;
content: "phf"; arachNIDS: IDS128; cve: CVE-1999-0067;)
   alert TCP any any -> any 7070 (msg: "IDS411/dos-realaudio"; flags:
AP; content: "|fff4 fffd 06|"; arachNIDS: IDS411;)
   alert TCP any any -> any 21 (msg:
"IDS287/ftp-wuftp260-venglin-linux"; flags: AP; content: "|31c031db
31c9b046 cd80 31c031db|"; arachNIDS: IDS287; bugtraq: 1387; cve:
CAN-2000-1574; )

Your output plugin can access the data like so:

   arachNIDSData *ad;

   ad = (arachNIDSData *) otn_tmp->ds_list[PLUGIN_ARACHNIDS_NUMBER];
   printf("arachNIDS ID:%s URL:%s\n", ad->id, ad->url);

The same goes for Bugtraq and CVE. Pretty simple

With the help of perl, I was able to tag arachNIDS keywords to every
rule in the vision.conf.  I'm in the process of adding Bugtraq and CVE
id's as well.  If anyone wants a copy of the rule set when I am done,
let me know.  Obviously for this plugin to be widely used, either
someone would have to continue adding the keywords to new rules, or the
rule databases themselves would have to put them in.  I wouldn't expect
the later to happen anytime soon, as it wouldn't work with versions of
Snort that are not using the plugin, and it may be a non trivial process
to integrate in.

In any case, I'm throwing this out to perhaps spark ideas and future
development.  I'm using it for an output plugin that I have been
developing.  If you have a use for this, then that is great.  I'm open
to your opinions and criticism.  I'm not posting to the snort-users
list, because I think most output plugin writers are here, and it seems
silly to post something that doesn't actually _do_ anything to
snort-users. :-)

Thank you,

-Joe M.
-- 
+--                            --+
| Joe McAlerney, Silicon Defense |
| http://www.silicondefense.com/ |
+--                            --+
-------------- next part --------------
/* sp_reference, Joe McAlerney, Silicon Defense, joey at ...63...
 * 
 * Purpose:
 *
 * This plugin allows alerts to be associated with attack signatures in 
 * identification systems.  The plugin currently supports Bugtraq, CVE 
 * (and CAN), and arachNIDS.  It has been built with the ability to add 
 * support for other numbering schemes with ease.  This plugin is to be 
 * used by output plugins to provide a link to additional information about
 * the alert produced.
 * 
 * Arguments:
 *  
 * As this plugin is based on keywords in rules, there are no arguments. The
 * keywords are:
 *     - bugtraq
 *     - cve
 *     - arachNIDS
 *
 * Effect:
 *
 * It stores the ID number and link to the associated alert to be used
 * by output plugins.  Some rule examples:
 *
 * alert TCP any any -> any 80 (msg: "IDS128/web-cgi-phf"; flags: AP; \
 *           content: "phf"; arachNIDS: IDS128; cve: CVE-1999-0067;)
 * alert TCP any any -> any 7070 (msg: "IDS411/dos-realaudio"; flags: \
 *           AP; content:\ "|fff4 fffd 06|"; arachNIDS: IDS411;)
 * alert TCP any any -> any 21 (msg: "IDS287/ftp-wuftp260-venglin-linux"; \
 *           flags: AP; content: "|31c031db 31c9b046 cd80 31c031db|"; \
 *           arachNIDS: IDS287; bugtraq: 1387; cve: CAN-2000-1574; )
 *
 * Comments:
 * 
 * There is not much to show from this plugin unless an output plugin actually
 * uses the data that is collected.  I made this plugin because an output
 * plugin I am working on required the information.  I hope other people
 * can find some way to use this as well.
 *
 */

#include "sp_reference.h"

extern char *file_name;  /* this is the file name from rules.c, generally used
                            for error messages */

extern int file_line;    /* this is the file line number from rules.c that is
                            used to indicate file lines for error messages */


/****************************************************************************
 * 
 * Function: SetupReferenceCheck()
 *
 * Purpose: Registers our keywords
 *
 * Arguments: None.
 *
 * Returns: void function
 *
 ****************************************************************************/
void SetupReference()
{
    /* map the keyword to an initialization/processing function */
    RegisterPlugin("bugtraq", BugtraqInit);
    RegisterPlugin("cve", CVEInit);
    RegisterPlugin("arachNIDS", arachNIDSInit);

#ifdef DEBUG
    printf("Plugin: ReferenceCheck Setup\n");
#endif
}


/****************************************************************************
 * 
 * Functions: BugtraqInit(char *, OptTreeNode *)
 *            CVEInit(char *, OptTreeNode *)
 *            arachNIDSInit(char *, OptTreeNode *)
 *
 * Purpose: rule configuration functions

 * Arguments: data => rule arguments/data
 *            otn => pointer to the current rule option list node
 *
 * Returns: void function
 *
 ****************************************************************************/
void BugtraqInit(char *data, OptTreeNode *otn, int protocol)
{
    /* allocate the data structure and attach it to the
       rule's data struct list */
    otn->ds_list[PLUGIN_BUGTRAQ_NUMBER] = (BugtraqData *) calloc(sizeof(BugtraqData), sizeof(char));

    /* this is where the keyword arguments are processed and placed into the 
       rule option's data structure */
    BugtraqRuleParseFunction(data, otn);
}

void CVEInit(char *data, OptTreeNode *otn, int protocol)
{
    /* allocate the data structure and attach it to the
       rule's data struct list */
    otn->ds_list[PLUGIN_CVE_NUMBER] = (CVEData *) calloc(sizeof(CVEData), sizeof(char));

    /* this is where the keyword arguments are processed and placed into the 
       rule option's data structure */
    CVERuleParseFunction(data, otn);
}

void arachNIDSInit(char *data, OptTreeNode *otn, int protocol)
{
    /* allocate the data structure and attach it to the
       rule's data struct list */
    otn->ds_list[PLUGIN_ARACHNIDS_NUMBER] = (arachNIDSData *) calloc(sizeof(arachNIDSData), sizeof(char));

    /* this is where the keyword arguments are processed and placed into the 
       rule option's data structure */
    arachNIDSRuleParseFunction(data, otn);
}


/****************************************************************************
 * 
 * Functions: BugtraqRuleParseFunction(char *, OptTreeNode *)
 *            CVERuleParseFunction(char *, OptTreeNode *)
 *            arachNIDSRuleParseFunction(char *, OptTreeNode *)
 *
 * Purpose: This is the function that is used to process the option keyword's
 *          arguments and attach them to the rule's data structures.
 *
 * Arguments: data => argument data
 *            otn => pointer to the current rule's OTN
 *
 * Returns: void function
 *
 ****************************************************************************/
void BugtraqRuleParseFunction(char *data, OptTreeNode *otn)
{
    BugtraqData *ds_ptr;  /* data struct pointer */
    char *url;

    /* set the ds pointer to make it easier to reference the option's
       particular data struct */
    ds_ptr = otn->ds_list[PLUGIN_BUGTRAQ_NUMBER];

    while (isspace((int)*data)) data++;
 
    /* manipulate the option arguments here */
    ds_ptr->id = data;
    url = calloc(strlen(BUGTRAQ_URL_HEAD) + strlen(data) + 1, sizeof(char));
    strncat(url,BUGTRAQ_URL_HEAD,strlen(BUGTRAQ_URL_HEAD) + 1);
    strncat(url,data,strlen(data) + 1);
    ds_ptr->url = url;
}

void CVERuleParseFunction(char *data, OptTreeNode *otn)
{
    CVEData *ds_ptr;  /* data struct pointer */
    char *url;

    /* set the ds pointer to make it easier to reference the option's
       particular data struct */
    ds_ptr = otn->ds_list[PLUGIN_CVE_NUMBER];

    while (isspace((int)*data)) data++;

    /* manipulate the option arguments here */
    ds_ptr->id = data;
    url = calloc(strlen(CVE_URL_HEAD) + strlen(data) + 1, sizeof(char));
    strncat(url,CVE_URL_HEAD,strlen(CVE_URL_HEAD) + 1);
    strncat(url,data,strlen(data) + 1);
    ds_ptr->url = url;
}

void arachNIDSRuleParseFunction(char *data, OptTreeNode *otn)
{
    arachNIDSData *ds_ptr;  /* data struct pointer */
    char *url;

    /* set the ds pointer to make it easier to reference the option's
       particular data struct */
    ds_ptr = otn->ds_list[PLUGIN_ARACHNIDS_NUMBER];

    while (isspace((int)*data)) data++;

    /* manipulate the option arguments here */
    ds_ptr->id = data;
    url = calloc(strlen(ARACHNIDS_URL_HEAD) + strlen(data) + 1, sizeof(char));
    strncat(url,ARACHNIDS_URL_HEAD,strlen(ARACHNIDS_URL_HEAD) + 1);
    strncat(url,data,strlen(data) + 1);
    ds_ptr->url = url;
}

-------------- next part --------------
/* sp_reference, Joe McAlerney, Silicon Defense, joey at ...63... */

/* This file gets included in plugbase.h when it is integrated into the rest 
 * of the program.  Sometime in The Future, I'll whip up a bad ass Perl script
 * to handle automatically loading all the required info into the plugbase.*
 * files.
 */

#ifndef __SP_REFERENCE_H__
#define __SP_REFERENCE_H__

#include "snort.h"

#define PLUGIN_BUGTRAQ_NUMBER    20
#define PLUGIN_CVE_NUMBER        21
#define PLUGIN_ARACHNIDS_NUMBER  22

#define BUGTRAQ_URL_HEAD   "http://www.securityfocus.com/bid/"
#define CVE_URL_HEAD       "http://cve.mitre.org/cgi-bin/cvename.cgi?name="
#define ARACHNIDS_URL_HEAD "http://www.whitehats.com/IDS/"

typedef struct _BugtraqData
{
  char *id;
  char *url;

} BugtraqData;

typedef struct _CVEData
{
  char *id;
  char *url;

} CVEData;

typedef struct _arachNIDSData
{
  char *id;
  char *url;

} arachNIDSData;

void SetupReference();

void BugtraqInit(char *, OptTreeNode *, int);
void CVEInit(char *, OptTreeNode *, int);
void arachNIDSInit(char *, OptTreeNode *, int);

void BugtraqRuleParseFunction(char *, OptTreeNode *);
void CVERuleParseFunction(char *, OptTreeNode *);
void arachNIDSRuleParseFunction(char *, OptTreeNode *);


#endif  /* __SP_REFERENCE_H__ */


More information about the Snort-devel mailing list