Tuesday, February 17, 2015

Snort++ Nets and Ports

One of the fundamental differences between Snort and Snort++ concerns configuration related to networks and ports.  Here is a brief review of Snort's configuration for network and service related components:
  • Snort's configuration has a default policy and optional policies selected by VLAN or network (with config binding).
  • Each policy contains a user defined set of preprocessor configurations.
  • Each preprocessor has a default configuration and some support non-default configurations selected by network.
  • Most preprocessors have port configurations.
  • The default policy may also contain a list of ports to ignore.
In Snort++, the above configurations are done in a single module called the binder.  Here is an example:

binder =
{
    -- allow all tcp port 22:
    -- (similar to snort 2.X config ignore_ports)
    { when = { proto = 'tcp', ports = '22' }, use = { action = 'allow' } },

    -- select a config file by vlan
    -- (similar to snort 2.X config binding by vlan)
    { when = { vlans = '1024' }, use = { file = 'vlan.lua' } },

    -- use a non-default HTTP inspector for port 8080:
    -- (similar to a snort 2.X targeted preprocessor config)
    { when = { nets = '192.168.0.0/16', proto = 'tcp', ports = '8080' },
      use = { name = 'alt_http', type = 'http_inspect' } },

    -- use the default inspectors:
    -- (similar to a snort 2.X default preprocessor config)
    { when = { proto = 'tcp' }, use = { type = 'stream_tcp' } },
    { when = { service = 'http' }, use = { type = 'http_inspect' } },

    -- figure out which inspector to run automatically:
    { use = { type = 'wizard' } }
}

Bindings are evaluated when a session starts and again if and when service is identified on the session.  Essentially, the bindings are a list of when-use rules evaluated from top to bottom.  The first matching network and service configurations are applied.  binder.when can contain any
combination of criteria and binder.use can specify an action, config file, or inspector configuration.

Using the wizard enables port-independent configuration and the detection of malware command and control channels.  If the wizard is bound to a session, it peeks at the initial payload to determine the service.  For example, 'GET' would indicate HTTP and 'HELO' would indicate SMTP.  Upon
finding a match, the service bindings are reevaluated so the session can be handed off to the appropriate inspector.  The wizard is still under development; if you find you need to tweak the defaults please let us know.

Additional Details:
  • If the wizard and one or more service inspectors are configured w/o explicitly configuring the binder, default bindings will be generated which should work for most common cases.
  • Also note that while Snort bindings can only be configured in the default policy, each Snort++ policy can contain a binder leading to an arbitrary hierarchy.
  • The entire configuration can be reloaded and hot-swapped during run-time via signal or command in both Snort and Snort++.  Ultimately, Snort++ will support commands to update the binder on the fly, thus enabling incremental reloads of individual inspectors.
  • Both Snort and Snort++ support server specific configurations via a hosts table (XML in Snort and Lua in Snort++).  The table allows you to map network, protocol, and port to a service and policy.  This table can be reloaded and hot-swapped separately from the config file.
  • You can find the specifics on the binder, wizard, and hosts tables in the manual or command line like this:  snort --help-module binder, etc.