1
2---------------------------------------------------------------------
3
4Snort 3 User Manual
5
6---------------------------------------------------------------------
7
8The Snort Team
9
10Revision History
11Revision 3.1.19.0 2021-12-15 06:07:38 EST TST
12
13---------------------------------------------------------------------
14
15Table of Contents
16
171. Overview
18
19    1.1. First Steps
20    1.2. Configuration
21    1.3. Output
22
232. Concepts
24
25    2.1. Terminology
26    2.2. Modules
27    2.3. Parameters
28    2.4. Plugins
29    2.5. Operation
30    2.6. Rules
31    2.7. Pattern Matching
32
333. Tutorial
34
35    3.1. Dependencies
36    3.2. Building
37    3.3. Running
38    3.4. Tips
39    3.5. Common Errors
40    3.6. Gotchas
41    3.7. Known Issues
42
434. Usage
44
45    4.1. Help
46    4.2. Sniffing and Logging
47    4.3. Configuration
48    4.4. IDS mode
49    4.5. Plugins
50    4.6. Output Files
51    4.7. DAQ Alternatives
52    4.8. Logger Alternatives
53    4.9. Shell
54    4.10. Signals
55
565. Features
57
58    5.1. Active Response
59    5.2. AppId
60    5.3. Binder
61    5.4. Byte rule options
62    5.5. Consolidated Config
63    5.6. DCE Inspectors
64    5.7. File Processing
65    5.8. High Availability
66    5.9. FTP
67    5.10. HTTP Inspector
68    5.11. HTTP/2 Inspector
69    5.12. IEC104 Inspector
70    5.13. Performance Monitor
71    5.14. POP and IMAP
72    5.15. Port Scan
73    5.16. Sensitive Data Filtering
74    5.17. SMTP
75    5.18. Telnet
76    5.19. Trace
77    5.20. Wizard
78
796. DAQ Configuration and Modules
80
81    6.1. Building the DAQ Library and Its Bundled DAQ Modules
82    6.2. Configuration
83    6.3. Interaction With Multiple Packet Threads
84    6.4. DAQ Modules Included With Snort 3
85
86Snorty
87
88---------------------------------------------------------------------
89
901. Overview
91
92---------------------------------------------------------------------
93
94Snort 3.0 is an updated version of the Snort Intrusion Prevention
95System (IPS) which features a new design that provides a superset of
96Snort 2.X functionality with better throughput, detection,
97scalability, and usability. Some of the key features of Snort 3.0
98are:
99
100  * Support multiple packet processing threads
101  * Use a shared configuration and attribute table
102  * Autodetect services for portless configuration
103  * Modular design
104  * Plugin framework with over 200 plugins
105  * More scalable memory profile
106  * LuaJIT configuration, loggers, and rule options
107  * Hyperscan support
108  * Rewritten TCP handling
109  * New rule parser and syntax
110  * Service rules like alert http
111  * Rule "sticky" buffers
112  * Way better SO rules
113  * New HTTP inspector
114  * New performance monitor
115  * New time and space profiling
116  * New latency monitoring and enforcement
117  * Piglets to facilitate component testing
118  * Inspection Events
119  * Autogenerate reference documentation
120
121Additional features are on the road map:
122
123  * Use a shared network map
124  * Support hardware offload for fast pattern acceleration
125  * Provide support for DPDK and ODP
126  * Support pipelining of packet processing
127  * Support proxy mode
128  * Multi-tennant support
129  * Incremental reload
130  * New serialization of perf data and events
131  * Enhanced rule processing
132  * Windows support
133  * Anomaly detection
134  * and more!
135
136The remainder of this section provides a high level survey of the
137inputs, processing, and outputs available with Snort 3.0.
138
139Snort++ is the project that is creating Snort 3.0. In this manual
140"Snort" or "Snort 3" refers to the 3.0 version and earlier versions
141will be referred to as "Snort 2" where the distinction is relevant.
142
143
1441.1. First Steps
145
146--------------
147
148Snort can be configured to perform complex packet processing and deep
149packet inspection but it is best start simply and work up to more
150interesting tasks. Snort won’t do anything you didn’t specifically
151ask it to do so it is safe to just try things out and see what
152happens. Let’s start by just running Snort with no arguments:
153
154$ snort
155
156That will output usage information including some basic help
157commands. You should run all of these commands now to see what is
158available:
159
160$ snort -V
161$ snort -?
162$ snort --help
163
164Note that Snort has extensive command line help available so if
165anything below isn’t clear, there is probably a way to get the exact
166information you need from the command line.
167
168Now let’s examine the packets in a capture file (pcap):
169
170$ snort -r a.pcap
171
172Snort will decode and count the packets in the file and output some
173statistics. Note that the output excludes non-zero numbers so it is
174easy to see what is there.
175
176You may have noticed that there are command line options to limit the
177number of packets examined or set a filter to select particular
178packets. Now is a good time to experiment with those options.
179
180If you want to see details on each packet, you can dump the packets
181to console like this:
182
183$ snort -r a.pcap -L dump
184
185Add the -d option to see the TCP and UDP payload. Now let’s switch to
186live traffic. Replace eth0 in the below command with an available
187network interface:
188
189$ snort -i eth0 -L dump
190
191Unless the interface is taken down, Snort will just keep running, so
192enter Control-C to terminate or use the -n option to limit the number
193of packets.
194
195Generally it is better to capture the packets for later analysis like
196this:
197
198$ snort -i eth0 -L pcap -n 10
199
200Snort will write 10 packets to log.pcap.# where # is a timestamp
201value. You can read these back with -r and dump to console or pcap
202with -L. You get the idea.
203
204Note that you can do similar things with other tools like tcpdump or
205Wireshark however these commands are very useful when you want to
206check your Snort setup.
207
208The examples above use the default pcap DAQ. Snort supports non-pcap
209interfaces as well via the DAQ (data acquisition) library. Other DAQs
210provide additional functionality such as inline operation and/or
211higher performance. There are even DAQs that support raw file
212processing (ie without packets), socket processing, and plain text
213packets. To load external DAQ libraries and see available DAQs or
214select a particular DAQ use one of these commands:
215
216$ snort --daq-dir <path> --daq-list
217$ snort --daq-dir <path> --daq <type>
218
219Be sure to put the --daq-dir option ahead of the --daq-list option or
220the external DAQs won’t appear in the list.
221
222To leverage intrusion detection features of Snort you will need to
223provide some configuration details. The next section breaks down what
224must be done.
225
226
2271.2. Configuration
228
229--------------
230
231Effective configuration of Snort is done via the environment, command
232line, a Lua configuration file, and a set of rules.
233
234Note that backwards compatibility with Snort 2 was sacrificed to
235obtain new and improved functionality. While Snort 3 leverages some
236of the Snort 2 code base, a lot has changed. The configuration of
237Snort 3 is done with Lua, so your old conf won’t work as is. Rules
238are still text based but with syntax tweaks, so your 2.X rules must
239be fixed up. However, snort2lua will help you convert your conf and
240rules to the new format.
241
2421.2.1. Command Line
243
244A simple command line might look like this:
245
246snort -c snort.lua -R cool.rules -r some.pcap -A cmg
247
248To understand what that does, you can start by just running snort
249with no arguments by running snort --help. Help for all configuration
250and rule options is available via a suitable command line. In this
251case:
252
253-c snort.lua is the main configuration file. This is a Lua script
254that is executed when loaded.
255
256-R cool.rules contains some detection rules. You can write your own
257or obtain them from Talos (native 3.0 rules are not yet available
258from Talos so you must convert them with snort2lua). You can also put
259your rules directly in your configuration file.
260
261-r some.pcap tells Snort to read network traffic from the given
262packet capture file. You could instead use -i eth0 to read from a
263live interface. There many other options available too depending on
264the DAQ you use.
265
266-A cmg says to output intrusion events in "cmg" format, which has
267basic header details followed by the payload in hex and text.
268
269Note that you add to and/or override anything in your configuration
270file by using the --lua command line option. For example:
271
272--lua 'ips = { enable_builtin_rules = true }'
273
274will load the built-in decoder and inspector rules. In this case, ips
275is overwritten with the config you see above. If you just want to
276change the config given in your configuration file you would do it
277like this:
278
279--lua 'ips.enable_builtin_rules = true'
280
2811.2.2. Configuration File
282
283The configuration file gives you complete control over how Snort
284processes packets. Start with the default snort.lua included in the
285distribution because that contains some key ingredients. Note that
286most of the configurations look like:
287
288stream = { }
289
290This means enable the stream module using internal defaults. To see
291what those are, you could run:
292
293snort --help-config stream
294
295Snort is organized into a collection of builtin and plugin modules.
296If a module has parameters, it is configured by a Lua table of the
297same name. For example, we can see what the active module has to
298offer with this command:
299
300$ snort --help-module active
301
302What: configure responses
303
304Type: basic
305
306Configuration:
307
308int active.attempts = 0: number of TCP packets sent per response (with
309varying sequence numbers) { 0:20 }
310
311string active.device: use 'ip' for network layer responses or 'eth0' etc
312for link layer
313
314string active.dst_mac: use format '01:23:45:67:89:ab'
315
316int active.max_responses = 0: maximum number of responses { 0: }
317
318int active.min_interval = 255: minimum number of seconds between
319responses { 1: }
320
321This says active is a basic module that has several parameters. For
322each, you will see:
323
324type module.name = default: help { range }
325
326For example, the active module has a max_responses parameter that
327takes non-negative integer values and defaults to zero. We can change
328that in Lua as follows:
329
330active = { max_responses = 1 }
331
332or:
333
334active = { }
335active.max_responses = 1
336
337If we also wanted to limit retries to at least 5 seconds, we could
338do:
339
340active = { max_responses = 1, min_interval = 5 }
341
3421.2.3. Lua Variables
343
344The following Global Lua Variables are available when Snort is run
345with a lua config using -c option.
346
347  * SNORT_VERSION: points to a string containing snort version and
348    build as follows:
349
350    SNORT_VERSION = "3.0.2-x"
351
352  * SNORT_MAJOR_VERSION: Snort version’s major number.
353
354    SNORT_MAJOR_VERSION = 3
355
356  * SNORT_MINOR_VERSION: Snort version’s minor number.
357
358    SNORT_MINOR_VERSION = 0
359
360  * SNORT_PATCH_VERSION: Snort version’s patch number.
361
362    SNORT_PATCH_VERSION = 2
363
3641.2.4. Whitelist
365
366When Snort is run with the --warn-conf-strict option, warnings will
367be generated for all Lua tables present in the configuration files
368that do not map to Snort module names. Like with other warnings,
369these will upgraded to errors when Snort is run in pedantic mode.
370
371To dynamically add exceptions that should bypass this strict
372validation, two Lua functions are made available to be called during
373the evaluation of Snort configuration files: snort_whitelist_append()
374and snort_whitelist_add_prefix(). Each function takes a
375whitespace-delimited list, the former a list of exact table names and
376the latter a list of table name prefixes to allow.
377
378Examples: snort_whitelist_append("table1 table2")
379snort_whitelist_add_prefix("local_ foobar_")
380
381The accumulated contents of the whitelist (both exact and prefix)
382will be dumped when Snort is run in verbose mode (-v).
383
3841.2.5. Rules
385
386Rules determine what Snort is looking for. They can be put directly
387in your Lua configuration file with the ips module, on the command
388line with --lua, or in external files. Generally you will have many
389rules obtained from various sources such as Talos and loading
390external files is the way to go so we will summarize that here. Add
391this to your Lua configuration:
392
393ips = { include = 'rules.txt' }
394
395to load the external rules file named rules.txt. You can only specify
396one file this way but rules files can include other rules files with
397the include statement. In addition you can load rules like:
398
399$ sort -c snort.lua -R rules.txt
400
401You can use both approaches together.
402
4031.2.6. Includes
404
405Your configuration file may include other files, either directly via
406Lua or via various parameters. Snort will find relative includes in
407the following order:
408
409 1. If you specify --include-path, this directory will be tried
410    first.
411 2. Snort will try the directory containing the including file.
412 3. Snort will try the directory containing the -c configuration
413    file.
414
415Some things to keep in mind:
416
417  * If you use the Lua dofile function, then you must specify
418    absolute paths or paths relative to your working directory since
419    Lua will execute the include before Snort sees the file contents.
420  * For best results, use include in place of dofile. This function
421    is provided to follow Snort’s include logic.
422  * As of now, appid and reputation paths must be absolute or
423    relative to the working directory. These will be updated in a
424    future release.
425
4261.2.7. Converting Your 2.X Configuration
427
428If you have a working 2.X configuration snort2lua makes it easy to
429get up and running with Snort 3. This tool will convert your
430configuration and/or rules files automatically. You will want to
431clean up the results and double check that it is doing exactly what
432you need.
433
434snort2lua -c snort.conf
435
436The above command will generate snort.lua based on your 2.X
437configuration. For more information and options for more
438sophisticated use cases, see the Snort2Lua section later in the
439manual.
440
441
4421.3. Output
443
444--------------
445
446Snort can produce quite a lot of data. In the following we will
447summarize the key aspects of the core output types. Additional data
448such as from appid is covered later.
449
4501.3.1. Basic Statistics
451
452At shutdown, Snort will output various counts depending on
453configuration and the traffic processed. Generally, you may see:
454
455  * Packet Statistics - this includes data from the DAQ and decoders
456    such as the number of packets received and number of UDP packets.
457  * Module Statistics - each module tracks activity via a set of peg
458    counts that indicate how many times something was observed or
459    performed. This might include the number of HTTP GET requests
460    processed and the number of TCP reset packets trimmed.
461  * File Statistics - look here for a breakdown of file type, bytes,
462    signatures.
463  * Summary Statistics - this includes total runtime for packet
464    processing and the packets per second. Profiling data will appear
465    here as well if configured.
466
467Note that only the non-zero counts are output. Run this to see the
468available counts:
469
470$ snort --help-counts
471
4721.3.2. Alerts
473
474If you configured rules, you will need to configure alerts to see the
475details of detection events. Use the -A option like this:
476
477$ snort -c snort.lua -r a.pcap -A cmg
478
479There are many types of alert outputs possible. Here is a brief list:
480
481  * -A cmg is the same as -A fast -d -e and will show information
482    about the alert along with packet headers and payload.
483  * -A u2 is the same as -A unified2 and will log events and
484    triggering packets in a binary file that you can feed to other
485    tools for post processing. Note that Snort 3 does not provide the
486    raw packets for alerts on PDUs; you will get the actual buffer
487    that alerted.
488  * -A csv will output various fields in comma separated value
489    format. This is entirely customizable and very useful for pcap
490    analysis.
491
492To see the available alert types, you can run this command:
493
494$ snort --list-plugins | grep logger
495
4961.3.3. Files and Paths
497
498Note that output is specific to each packet thread. If you run 4
499packet threads with u2 output, you will get 4 different u2 files. The
500basic structure is:
501
502<logdir>/[<run_prefix>][<id#>][<X>]<name>
503
504where:
505
506  * logdir is set with -l and defaults to ./
507  * run_prefix is set with --run-prefix else not used
508  * id# is the packet thread number that writes the file; with one
509    packet thread, id# (zero) is omitted without --id-zero
510  * X is / if you use --id-subdir, else _ if id# is used
511  * name is based on module name that writes the file
512
513Additional considerations:
514
515  * There is no way to explicitly configure a full path to avoid
516    issues with multiple packet threads.
517  * All text mode outputs default to stdout
518
5191.3.4. Performance Statistics
520
521Still more data is available beyond the above.
522
523  * By configuring the perf_monitor module you can capture a
524    configurable set of peg counts during runtime. This is useful to
525    feed to an external program so you can see what is happening
526    without stopping Snort.
527  * The profiler module allows you to track time and space used by
528    module and rules. Use this data to tune your system for best
529    performance. The output will show up under Summary Statistics at
530    shutdown.
531
532
533---------------------------------------------------------------------
534
5352. Concepts
536
537---------------------------------------------------------------------
538
539This section provides background on essential aspects of Snort’s
540operation.
541
542
5432.1. Terminology
544
545--------------
546
547  * basic module: a module integrated into Snort that does not come
548    from a plugin.
549  * binder: inspector that maps configuration to traffic
550  * builtin rules: codec and inspector rules for anomalies detected
551    internally.
552  * codec: short for coder / decoder. These plugins are used for
553    basic protocol decoding, anomaly detection, and construction of
554    active responses.
555  * data module: an adjunct configuration plugin for use with certain
556    inspectors.
557  * dynamic rules: plugin rules loaded at runtime. See SO rules.
558  * fast pattern: the content in an IPS rule that must be found by
559    the search engine in order for a rule to be evaluated.
560  * fast pattern matcher: see search engine.
561  * hex: a type of protocol magic that the wizard uses to identify
562    binary protocols.
563  * inspector: plugin that processes packets (similar to the Snort 2
564    preprocessor)
565  * IPS: intrusion prevention system, like Snort.
566  * IPS action: plugin that allows you to perform custom actions when
567    events are generated. Unlike loggers, these are invoked before
568    thresholding and can be used to control external agents or send
569    active responses.
570  * IPS option: this plugin is the building blocks of IPS rules.
571  * logger: a plugin that performs output of events and packets.
572    Events are thresholded before reaching loggers.
573  * module: the user facing portion of a Snort component. Modules
574    chiefly provide configuration parameters, but may also provide
575    commands, builtin rules, profiling statistics, peg counts, etc.
576    Note that not all modules are plugins and not all plugins have
577    modules.
578  * peg count: the number of times a given event or condition occurs.
579  * plugin: one of several types of software components that can be
580    loaded from a dynamic library when Snort starts up. Some plugins
581    are coupled with the main engine in such a way that they must be
582    built statically, but a newer version can be loaded dynamically.
583  * search engine: a plugin that performs multipattern searching of
584    packets and payload to find rules that should be evaluated. There
585    are currently no specific modules, although there are several
586    search engine plugins. Related configuration is done with the
587    basic detection module. Aka fast pattern matcher.
588  * SO rule: a IPS rule plugin that performs custom detection that
589    can’t be done by a text rule. These rules typically do not have
590    associated modules. SO comes from shared object, meaning dynamic
591    library.
592  * spell: a type of protocol magic that the wizard uses to identify
593    ASCII protocols.
594  * text rule: a rule loaded from the configuration that has a header
595    and body. The header specifies action, protocol, source and
596    destination IP addresses and ports, and direction. The body
597    specifies detection and non-detection options.
598  * wizard: inspector that applies protocol magic to determine which
599    inspectors should be bound to traffic absent a port specific
600    binding. See hex and spell.
601
602
6032.2. Modules
604
605--------------
606
607Modules are the building blocks of Snort. They encapsulate the types
608of data that many components need including parameters, peg counts,
609profiling, builtin rules, and commands. This allows Snort to handle
610them generically and consistently. You can learn quite a lot about
611any given module from the command line. For example, to see what
612stream_tcp is all about, do this:
613
614$ snort --help-config stream_tcp
615
616Modules are configured using Lua tables with the same name. So the
617stream_tcp module is configured with defaults like this:
618
619stream_tcp = { }
620
621The earlier help output showed that the default session tracking
622timeout is 30 seconds. To change that to 60 seconds, you can
623configure it this way:
624
625stream_tcp = { session_timeout = 60 }
626
627Or this way:
628
629stream_tcp = { }
630stream_tcp.session_timeout = 60
631
632More on parameters is given in the next section.
633
634Other things to note about modules:
635
636  * Shutdown output will show the non-zero peg counts for all
637    modules. For example, if stream_tcp did anything, you would see
638    the number of sessions processed among other things.
639  * Providing the builtin rules allows the documentation to include
640    them automatically and also allows for autogenerating the rules
641    at startup.
642  * Only a few module provide commands at this point, most notably
643    the snort module.
644
645
6462.3. Parameters
647
648--------------
649
650Parameters are given with this format:
651
652type name = default: help { range }
653
654The following types are used:
655
656  * addr: any valid IP4 or IP6 address or CIDR
657  * addr_list: a space separated list of addr values
658  * bit_list: a list of consecutive integer values from 1 to the
659    range maximum
660  * bool: true or false
661  * dynamic: a select type determined by loaded plugins
662  * enum: a string selected from the given range
663  * implied: an IPS rule option that takes no value but means true
664  * int: a whole number in the given range
665  * interval: a set of ints (see below)
666  * ip4: an IP4 address or CIDR
667  * mac: an ethernet address with the form 01:02:03:04:05:06
668  * multi: one or more space separated strings from the given range
669  * port: an int in the range 0:65535 indicating a TCP or UDP port
670    number
671  * real: a real number in the given range
672  * select: a string selected from the given range
673  * string: any string with no more than the given length, if any
674
675The parameter name may be adorned in various ways to indicate
676additional information about the type and use of the parameter:
677
678  * For Lua configuration (not IPS rules), if the name ends with []
679    it is a list item and can be repeated.
680  * For IPS rules only, names starting with ~ indicate positional
681    parameters. The names of such parameters do not appear in the
682    rule.
683  * IPS rules may also have a wild card parameter, which is indicated
684    by a *. Used for unquoted, comma-separated lists such as service
685    and metadata.
686  * The snort module has command line options starting with a -.
687  * $ denotes variable names.
688
689Some additional details to note:
690
691  * Table and variable names are case sensitive; use lower case only.
692  * String values are case sensitive too; use lower case only.
693  * Numeric ranges may be of the form low:high where low and high are
694    bounds included in the range. If either is omitted, there is no
695    hard bound. E.g. 0: means any x where x >= 0.
696  * Strings may have a numeric range indicating a length limit;
697    otherwise there is no hard limit.
698  * bit_list is typically used to store a set of byte, port, or VLAN
699    ID values.
700  * interval takes the form [operator]i, j<>k, or j<⇒k where i,j,k
701    are integers and operator is one of =, !, != (same as !), <, ⇐,
702    >, >=. j<>k means j < int < k and j<⇒k means j ⇐ int ⇐ k.
703  * Ranges may use maxXX like { 1:max32 } since max32 is easier to
704    read than 4294967295. To get the values of maxXX, use snort
705    --help-limits.
706
707Parameter limits:
708
709  * max31 = 2147483647
710  * max32 = 4294967295
711  * max53 = 9007199254740992
712  * maxSZ = 9007199254740992
713
714
7152.4. Plugins
716
717--------------
718
719Snort uses a variety of plugins to accomplish much of its processing
720objectives, including:
721
722  * Codec - to decode and encode packets
723  * Inspector - like Snort 2 preprocessors, for normalization, etc.
724  * IpsOption - for detection in Snort rules
725  * IpsAction - for custom actions
726  * Logger - for handling events
727  * Mpse - for fast pattern matching
728  * So - for dynamic rules
729
730The power of plugins is that they have a very focused purpose and can
731be created with relative ease. For example, you can extend the rule
732language by writing your own IpsOption and it will plug in and
733function just like existing options. The extra directory has examples
734of each type of plugin.
735
736Most plugins can be built statically or dynamically. By default they
737are all static. There is no difference in functionality between
738static or dynamic plugins but the dynamic build generates a slightly
739lighter weight binary. Either way you can add dynamic plugins with
740--plugin-path and newer versions will replace older versions, even
741when built statically.
742
743A single dynamic library may contain more than one plugin. For
744example, an inspector will typically be packaged together with any
745associated rule options.
746
747
7482.5. Operation
749
750--------------
751
752Snort is a signature-based IPS, which means that as it receives
753network packets it reassembles and normalizes the content so that a
754set of rules can be evaluated to detect the presence of any
755significant conditions that merit further action. A rough processing
756flow is as follows:
757
758Snort 2
759
760The steps are:
761
762 1. Decode each packet to determine the basic network characteristics
763    such as source and destination addresses and ports. A typical
764    packet might have ethernet containing IP containing TCP
765    containing HTTP (ie eth:ip:tcp:http). The various encapsulating
766    protocols are examined for sanity and anomalies as the packet is
767    decoded. This is essentially a stateless effort.
768 2. Preprocess each decoded packet using accumulated state to
769    determine the purpose and content of the innermost message. This
770    step may involve reordering and reassembling IP fragments and TCP
771    segments to produce the original application protocol data unit
772    (PDU). Such PDUs are analyzed and normalized as needed to support
773    further processing.
774 3. Detection is a two step process. For efficiency, most rules
775    contain a specific content pattern that can be searched for such
776    that if no match is found no further processing is necessary.
777    Upon start up, the rules are compiled into pattern groups such
778    that a single, parallel search can be done for all patterns in
779    the group. If any match is found, the full rule is examined
780    according to the specifics of the signature.
781 4. The logging step is where Snort saves any pertinent information
782    resulting from the earlier steps. More generally, this is where
783    other actions can be taken as well such as blocking the packet.
784
7852.5.1. Snort 2 Processing
786
787The preprocess step in Snort 2 is highly configurable. Arbitrary
788preprocessors can be loaded dynamically at startup, configured in
789snort.conf, and then executed at runtime. Basically, the
790preprocessors are put into a list which is iterated for each packet.
791Recent versions have tweaked the list handling some, but the same
792basic architecture has allowed Snort 2 to grow from a sniffer, with
793no preprocessing, to a full-fledged IPS, with lots of preprocessing.
794
795While this "list of plugins" approach has considerable flexibility,
796it hampers future development when the flow of data from one
797preprocessor to the next depends on traffic conditions, a common
798situation with advanced features like application identification. In
799this case, a preprocessor like HTTP may be extracting and normalizing
800data that ultimately is not used, or appID may be repeatedly checking
801for data that is just not available.
802
803Callbacks help break out of the preprocess straitjacket. This is
804where one preprocessor supplies another with a function to call when
805certain data is available. Snort has started to take this approach to
806pass some HTTP and SIP preprocessor data to appID. However, it
807remains a peripheral feature and still requires the production of
808data that may not be consumed.
809
8102.5.2. Snort 3 Processing
811
812One of the goals of Snort 3 is to provide a more flexible framework
813for packet processing by implementing an event-driven approach.
814Another is to produce data only when needed to minimize expensive
815normalizations. However, the basic packet processing provides very
816similar functionality.
817
818The basic processing steps Snort 3 takes are similar to Snort 2 as
819seen in the following diagram. The preprocess step employs specific
820inspector types instead of a generalized list, but the basic
821procedure includes stateless packet decoding, TCP stream reassembly,
822and service specific analysis in both cases. (Snort 3 provides hooks
823for arbitrary inspectors, but they are not central to basic flow
824processing and are not shown.)
825
826Snort 3
827
828However, Snort 3 also provides a more flexible mechanism than
829callback functions. By using inspection events, it is possible for an
830inspector to supply data that other inspectors can process. This is
831known as the observer pattern or publish-subscribe pattern.
832
833Note that the data is not actually published. Instead, access to the
834data is published, and that means that subscribers can access the raw
835or normalized version(s) as needed. Normalizations are done only on
836the first access, and subsequent accesses get the previously
837normalized data. This results in just in time (JIT) processing.
838
839A basic example of this in action is provided by the extra data_log
840plugin. It is a passive inspector, ie it does nothing until it
841receives the data it subscribed for (other in the above diagram). By
842adding the following to your snort.lua configuration, you will get a
843simple URI logger.
844
845data_log = { key = 'http_raw_uri' }
846
847Inspection events coupled with pluggable inspectors provide a very
848flexible framework for implementing new features. And JIT buffer
849stuffers allow Snort to work smarter, not harder. These capabilities
850will be leveraged more and more as Snort development continues.
851
852
8532.6. Rules
854
855--------------
856
857Rules tell Snort how to detect interesting conditions, such as an
858attack, and what to do when the condition is detected. Here is an
859example rule:
860
861alert tcp any any -> 192.168.1.1 80 ( msg:"A ha!"; content:"attack"; sid:1; )
862
863The structure is:
864
865action proto source dir dest ( body )
866
867Where:
868
869action - tells Snort what to do when a rule "fires", ie when the
870signature matches. In this case Snort will log the event. It can also
871do thing like block the flow when running inline.
872
873proto - tells Snort what protocol applies. This may be ip, icmp, tcp,
874udp, http, etc.
875
876source - specifies the sending IP address and port, either of which
877can be the keyword any, which is a wildcard.
878
879dir - must be either unidirectional as above or bidirectional
880indicated by <>.
881
882dest - similar to source but indicates the receiving end.
883
884body - detection and other information contained in parenthesis.
885
886There are many rule options available to construct as sophisticated a
887signature as needed. In this case we are simply looking for the
888"attack" in any TCP packet. A better rule might look like this:
889
890alert http
891(
892    msg:"Gotcha!";
893    flow:established, to_server;
894    http_uri:"attack";
895    sid:2;
896)
897
898Note that these examples have a sid option, which indicates the
899signature ID. In general rules are specified by gid:sid:rev notation,
900where gid is the generator ID and rev is the revision of the rule. By
901default, text rules are gid 1 and shared-object (SO) rules are gid 3.
902The various components within Snort that generate events have 1XX
903gids, for example the decoder is gid 116. You can list the internal
904gids and sids with these commands:
905
906$ snort --list-gids
907$ snort --list-builtin
908
909For details on these and other options, see the reference section.
910
911
9122.7. Pattern Matching
913
914--------------
915
916Snort evaluates rules in a two-step process which includes a fast
917pattern search and full evaluation of the signature. More details on
918this process follow.
919
9202.7.1. Rule Groups
921
922When Snort starts or reloads configuration, rules are grouped by
923protocol, port and service. For example, all TCP rules using the
924HTTP_PORTS variable will go in one group and all service HTTP rules
925will go in another group. These rule groups are compiled into
926multipattern search engines (MPSE) which are designed to search for
927all patterns with just a single pass through a given packet or
928buffer. You can select the algorithm to use for fast pattern searches
929with search_engine.search_method which defaults to ac_bnfa, which
930balances speed and memory. For a faster search at the expense of
931significantly more memory, use ac_full. For best performance and
932reasonable memory, download the hyperscan source from Intel.
933
9342.7.2. Fast Patterns
935
936Fast patterns are content strings that have the fast_pattern option
937or which have been selected by Snort automatically to be used as a
938fast pattern. Snort will by default choose the longest pattern in the
939rule since that is likely to be most unique. That is not always the
940case so add fast_pattern to the appropriate content option for best
941performance. The ideal fast pattern is one which, if found, is very
942likely to result in a rule match. Fast patterns that match frequently
943for unrelated traffic will cause Snort to work hard with little to
944show for it.
945
946Certain contents are not eligible to be used as fast patterns.
947Specifically, if a content is negated, then if it is also relative to
948another content, case sensitive, or has non-zero offset or depth,
949then it is not eligible to be used as a fast pattern.
950
9512.7.3. Rule Evaluation
952
953For each fast pattern match, the corresponding rule(s) are evaluated
954left-to-right. Rule evaluation requires checking each detection
955option in a rule and is a fairly costly process which is why fast
956patterns are so important. Rule evaluation aborts on the first
957non-matching option.
958
959When rule evaluation takes place, the fast pattern match will
960automatically be skipped if possible. Note that this differs from
961Snort 2 which provided the fast_pattern:only option to designate such
962cases. This is one less thing for the rule writer to worry about.
963
964
965---------------------------------------------------------------------
966
9673. Tutorial
968
969---------------------------------------------------------------------
970
971The section will walk you through building and running Snort. It is
972not exhaustive but, once you master this material, you should be able
973to figure out more advanced usage.
974
975
9763.1. Dependencies
977
978--------------
979
980Required:
981
982  * a compiler that supports the C++14 feature set
983  * cmake to build from source
984  * daq from https://github.com/snort3/libdaq for packet IO
985  * dnet from https://github.com/dugsong/libdnet.git for network
986    utility functions
987  * hwloc from https://www.open-mpi.org/projects/hwloc/ for CPU
988    affinity management
989  * LuaJIT from http://luajit.org for configuration and scripting
990  * OpenSSL from https://www.openssl.org/source/ for SHA and MD5 file
991    signatures, the protected_content rule option, and SSL service
992    detection
993  * pcap from http://www.tcpdump.org for tcpdump style logging
994  * pcre from http://www.pcre.org for regular expression pattern
995    matching
996  * pkgconfig from https://www.freedesktop.org/wiki/Software/
997    pkg-config/ to locate build dependencies
998  * zlib from http://www.zlib.net for decompression (>= 1.2.8
999    recommended)
1000
1001Optional:
1002
1003  * asciidoc from http://www.methods.co.nz/asciidoc/ to build the
1004    HTML manual
1005  * cpputest from http://cpputest.github.io to run additional unit
1006    tests with make check
1007  * dblatex from http://dblatex.sourceforge.net to build the pdf
1008    manual (in addition to asciidoc)
1009  * flatbuffers from https://google.github.io/flatbuffers/ for
1010    enabling the flatbuffers serialization format
1011  * hyperscan >= 4.4.0 from https://github.com/01org/hyperscan to
1012    build new the regex and sd_pattern rule options and hyperscan
1013    search engine. Hyperscan is large so it recommended to follow
1014    their instructions for building it as a shared library.
1015  * iconv from https://ftp.gnu.org/pub/gnu/libiconv/ for converting
1016    UTF16-LE filenames to UTF8 (usually included in glibc)
1017  * libunwind from https://www.nongnu.org/libunwind/ to attempt to
1018    dump a somewhat readable backtrace when a fatal signal is
1019    received
1020  * lzma >= 5.1.2 from http://tukaani.org/xz/ for decompression of
1021    SWF and PDF files
1022  * safec >= 3.5 from https://github.com/rurban/safeclib/ for runtime
1023    bounds checks on certain legacy C-library calls
1024  * source-highlight from http://www.gnu.org/software/src-highlite/
1025    to generate the dev guide
1026  * w3m from http://sourceforge.net/projects/w3m/ to build the plain
1027    text manual
1028  * uuid from uuid-dev package for unique identifiers
1029
1030
10313.2. Building
1032
1033--------------
1034
1035  * Optionally built features are listed in the reference section.
1036  * Create an install path:
1037
1038    export my_path=/path/to/snorty
1039    mkdir -p $my_path
1040
1041  * If LibDAQ was installed to a custom, non-system path:
1042
1043    export PKG_CONFIG_PATH=/libdaq/install/path/lib/pkgconfig:$PKG_CONFIG_PATH
1044
1045  * Now do one of the following:
1046
1047     a. To build with cmake and make, run configure_cmake.sh. It will
1048        automatically create and populate a new subdirectory named
1049        build.
1050
1051        ./configure_cmake.sh --prefix=$my_path
1052        cd build
1053        make -j
1054        make install
1055        ln -s $my_path/conf $my_path/etc
1056
1057     b. You can also specify a cmake project generator:
1058
1059        ./configure_cmake.sh --generator=Xcode --prefix=$my_path
1060
1061     c. Or use ccmake directly to configure and generate from an
1062        arbitrary build directory like one of these:
1063
1064        ccmake -G Xcode /path/to/Snort++/tree
1065        open snort.xcodeproj
1066
1067        ccmake -G "Eclipse CDT4 - Unix Makefiles" /path/to/Snort++/tree
1068        run eclipse and do File > Import > Existing Eclipse Project
1069
1070  * To build with g++ on OS X where clang is installed, do this
1071    first:
1072
1073    export CXX=g++
1074
1075
10763.3. Running
1077
1078--------------
1079
1080Examples:
1081
1082  * Get some help:
1083
1084    $my_path/bin/snort --help
1085    $my_path/bin/snort --help-module suppress
1086    $my_path/bin/snort --help-config | grep thread
1087
1088  * Examine and dump a pcap:
1089
1090    $my_path/bin/snort -r <pcap>
1091    $my_path/bin/snort -L dump -d -e -q -r <pcap>
1092
1093  * Verify config, with or w/o rules:
1094
1095    $my_path/bin/snort -c $my_path/etc/snort/snort.lua
1096    $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules
1097
1098  * Run IDS mode. To keep it brief, look at the first n packets in
1099    each file:
1100
1101    $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
1102        -r <pcap> -A alert_test -n 100000
1103
1104  * Let’s suppress 1:2123. We could edit the conf or just do this:
1105
1106    $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
1107        -r <pcap> -A alert_test -n 100000 --lua "suppress = { { gid = 1, sid = 2123 } }"
1108
1109  * Go whole hog on a directory with multiple packet threads:
1110
1111    $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
1112        --pcap-filter \*.pcap --pcap-dir <dir> -A alert_fast -n 1000 --max-packet-threads 8
1113
1114For more examples, see the usage section.
1115
1116
11173.4. Tips
1118
1119--------------
1120
1121One of the goals of Snort 3 is to make it easier to configure your
1122sensor. Here is a summary of tips and tricks you may find useful.
1123
1124General Use
1125
1126  * Snort tries hard not to error out too quickly. It will report
1127    multiple semantic errors.
1128  * Snort always assumes the simplest mode of operation. Eg, you can
1129    omit the -T option to validate the conf if you don’t provide a
1130    packet source.
1131  * Warnings are not emitted unless --warn-* is specified. --warn-all
1132    enables all warnings, and --pedantic makes such warnings fatal.
1133  * You can process multiple sources at one time by using the -z or
1134    --max-threads option.
1135  * To make it easy to find the important data, zero counts are not
1136    output at shutdown.
1137  * Load plugins from the command line with --plugin-path /path/to/
1138    install/lib.
1139  * You can process multiple sources at one time by using the -z or
1140    --max-threads option.
1141  * Unit tests are configured with --enable-unit-tests. They can then
1142    be run with snort --catch-test [tags]|all.
1143  * Benchmark tests are configured with --enable-benchmark-tests.
1144    They can then be run with snort --catch-test [tags]|all or built
1145    as a separate executable. It is also preferred to configure a
1146    non-debug build with optimizations enabled.
1147
1148Lua Configuration
1149
1150  * Configure the wizard and default bindings will be created based
1151    on configured inspectors. No need to explicitly bind ports in
1152    this case.
1153  * You can override or add to your Lua conf with the --lua command
1154    line option.
1155  * The Lua conf is a live script that is executed when loaded. You
1156    can add functions, grab environment variables, compute values,
1157    etc.
1158  * You can also rename symbols that you want to disable. For
1159    example, changing normalizer to Xnormalizer (an unknown symbol)
1160    will disable the normalizer. This can be easier than commenting
1161    in some cases.
1162  * By default, symbols unknown to Snort are silently ignored. You
1163    can generate warnings for them with --warn-unknown. To ignore
1164    such symbols, export them in the environment variable
1165    SNORT_IGNORE.
1166
1167Writing and Loading Rules
1168
1169Snort rules allow arbitrary whitespace. Multi-line rules make it
1170easier to structure your rule for clarity. There are multiple ways to
1171add comments to your rules:
1172
1173  * The # character starts a comment to end of line. In addition, all
1174    lines between #begin and #end are comments.
1175  * The rem option allows you to write a comment that is conveyed
1176    with the rule.
1177  * C style multi-line comments are allowed, which means you can
1178    comment out portions of a rule while testing it out by putting
1179    the options between /* and */.
1180
1181There are multiple ways to load rules too:
1182
1183  * Set ips.rules or ips.include.
1184  * include statements can be used in rules files.
1185  * Use -R to load a rules file.
1186  * Use --stdin-rules with command line redirection.
1187  * Use --lua to specify one or more rules as a command line
1188    argument.
1189
1190Ips states are similar to ips rules, except that they are parsed
1191after the rules. That way rules can be overwritten in custom
1192policies.
1193
1194States without the enable option are loaded as stub rules with
1195default gid:0, sid:0. A user should specify gid, sid, enable options
1196to avoid dummy rules.
1197
1198Output Files
1199
1200To make it simple to configure outputs when you run with multiple
1201packet threads, output files are not explicitly configured. Instead,
1202you can use the options below to format the paths:
1203
1204<logdir>/[<run_prefix>][<id#>][<X>]<name>
1205
1206  * logdir is set with -l and defaults to ./
1207  * run_prefix is set with --run-prefix else not used
1208  * id# is the packet thread number that writes the file; with one
1209    packet thread, id# (zero) is omitted without --id-zero
1210  * X is / if you use --id-subdir, else _ if id# is used
1211  * name is based on module name that writes the file
1212  * all text mode outputs default to stdout
1213
1214
12153.5. Common Errors
1216
1217--------------
1218
1219PANIC: unprotected error in call to Lua API (cannot open
1220snort_defaults.lua: No such file or directory)
1221
1222  * export SNORT_LUA_PATH to point to any dofiles
1223
1224ERROR can’t find xyz
1225
1226  * if xyz is the name of a module, make sure you are not assigning a
1227    scalar where a table is required (e.g. xyz = 2 should be xyz = {
1228    }).
1229
1230ERROR can’t find x.y
1231
1232  * module x does not have a parameter named y. check --help-module x
1233    for available parameters.
1234
1235ERROR invalid x.y = z
1236
1237  * the value z is out of range for x.y. check --help-config x.y for
1238    the range allowed.
1239
1240ERROR: x = { y = z } is in conf but is not being applied
1241
1242  * make sure that x = { } isn’t set later because it will override
1243    the earlier setting. same for x.y.
1244
1245FATAL: can’t load lua/errors.lua: lua/errors.lua:68: = expected near
1246';'
1247
1248  * this is a syntax error reported by Lua to Snort on line 68 of
1249    errors.lua.
1250
1251ERROR: rules(2) unknown rule keyword: find.
1252
1253  * this was due to not including the --script-path.
1254
1255WARNING: unknown symbol x
1256
1257  * if you any variables, you can squelch such warnings by setting
1258    them in an environment variable SNORT_IGNORE. to ignore x, y, and
1259    z:
1260
1261    export SNORT_IGNORE="x y z"
1262
1263
12643.6. Gotchas
1265
1266--------------
1267
1268  * A nil key in a table will not be caught. Neither will a nil value
1269    in a table. Neither of the following will cause errors, nor will
1270    they actually set http_inspect.request_depth:
1271
1272    http_inspect = { request_depth }
1273    http_inspect = { request_depth = undefined_symbol }
1274
1275  * It is not an error to set a value multiple times. The actual
1276    value applied may not be the last in the table either. It is best
1277    to avoid such cases.
1278
1279    http_inspect =
1280    {
1281        request_depth = 1234,
1282        request_depth = 4321
1283    }
1284
1285  * Snort can’t tell you the exact filename or line number of a
1286    semantic error but it will tell you the fully qualified name.
1287
1288
12893.7. Known Issues
1290
1291--------------
1292
1293  * The dump DAQ will not work with multiple threads unless you use
1294    --daq-var output=none. This will be fixed at some point to use
1295    the Snort log directory, etc.
1296  * If you build with hyperscan on OS X and see:
1297
1298    dyld: Library not loaded: @rpath/libhs.4.0.dylib
1299
1300    when you try to run src/snort, export DYLD_LIBRARY_PATH with the path to
1301    libhs.  You can also do:
1302
1303    install_name_tool -change @rpath/libhs.4.0.dylib \
1304        /path-to/libhs.4.0.dylib src/snort
1305
1306  * Snort built with tcmalloc support (--enable-tcmalloc) on Ubuntu
1307    17.04/18.04 crashes immediately.
1308
1309    Workaround:
1310    Uninstall gperftools 2.5 provided by the distribution and install gperftools
1311    2.7 before building Snort.
1312
13133.7.1. Reload Limitations
1314
1315The following parameters can’t be changed during reload, and require
1316a restart:
1317
1318  * active.attempts
1319  * active.device
1320  * alerts.detection_filter_memcap
1321  * alerts.event_filter_memcap
1322  * alerts.rate_filter_memcap
1323  * attribute_table.max_hosts
1324  * attribute_table.max_services_per_host
1325  * daq.snaplen
1326  * detection.asn1
1327  * file_id.max_files_cached
1328  * process.chroot
1329  * process.daemon
1330  * process.set_gid
1331  * process.set_uid
1332  * snort.--bpf
1333  * snort.-l
1334
1335In addition, the following scenarios require a restart:
1336
1337  * Enabling file capture for the first time
1338  * Changing file_id.capture_memcap if file capture was previously or
1339    currently enabled
1340  * Changing file_id.capture_block_size if file capture was
1341    previously or currently enabled
1342  * Adding/removing stream_* inspectors if stream was already
1343    configured
1344
1345In all of these cases reload will fail with the following message:
1346"reload failed - restart required". The original config will remain
1347in use.
1348
1349
1350---------------------------------------------------------------------
1351
13524. Usage
1353
1354---------------------------------------------------------------------
1355
1356For the following examples "$my_path" is assumed to be the path to
1357the Snort install directory. Additionally, it is assumed that
1358"$my_path/bin" is in your PATH.
1359
1360
13614.1. Help
1362
1363--------------
1364
1365Print the help summary:
1366
1367snort --help
1368
1369Get help on a specific module ("stream", for example):
1370
1371snort --help-module stream
1372
1373Get help on the "-A" command line option:
1374
1375snort --help-options A
1376
1377Grep for help on threads:
1378
1379snort --help-config | grep thread
1380
1381Output help on "rule" options in AsciiDoc format:
1382
1383snort --markup --help-options rule
1384
1385Note
1386
1387Snort stops reading command-line options after the "--help-" and
1388"--list-" options, so any other options should be placed before them.
1389
1390
13914.2. Sniffing and Logging
1392
1393--------------
1394
1395Read a pcap:
1396
1397snort -r /path/to/my.pcap
1398
1399Dump the packets to stdout:
1400
1401snort -r /path/to/my.pcap -L dump
1402
1403Dump packets with application data and layer 2 headers
1404
1405snort -r /path/to/my.pcap -L dump -d -e
1406
1407Note
1408
1409Command line options must be specified separately. "snort -de" won’t
1410work. You can still concatenate options and their arguments, however,
1411so "snort -Ldump" will work.
1412
1413Dump packets from all pcaps in a directory:
1414
1415snort --pcap-dir /path/to/pcap/dir --pcap-filter '*.pcap' -L dump -d -e
1416
1417Log packets to a directory:
1418
1419snort --pcap-dir /path/to/pcap/dir --pcap-filter '*.pcap' -L dump -l /path/to/log/dir
1420
1421
14224.3. Configuration
1423
1424--------------
1425
1426Validate a configuration file:
1427
1428snort -c $my_path/etc/snort/snort.lua
1429
1430Validate a configuration file and a separate rules file:
1431
1432snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules
1433
1434Read rules from stdin and validate:
1435
1436snort -c $my_path/etc/snort/snort.lua --stdin-rules < $my_path/etc/snort/sample.rules
1437
1438Enable warnings for Lua configurations and make warnings fatal:
1439
1440snort -c $my_path/etc/snort/snort.lua --warn-all --pedantic
1441
1442Tell Snort where to look for additional Lua scripts:
1443
1444snort --script-path /path/to/script/dir
1445
1446
14474.4. IDS mode
1448
1449--------------
1450
1451Run Snort in IDS mode, reading packets from a pcap:
1452
1453snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap
1454
1455Log any generated alerts to the console using the "-A" option:
1456
1457snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A alert_full
1458
1459Capture separate stdout, stderr, and stdlog files (out has startup
1460and shutdown output, err has warnings and errors, and log has
1461alerts):
1462
1463snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A csv \
1464    1>out 2>err 3>log
1465
1466Add or modify a configuration from the command line using the "--lua"
1467option:
1468
1469snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A cmg \
1470    --lua 'ips = { enable_builtin_rules = true }'
1471
1472Note
1473
1474The "--lua" option can be specified multiple times.
1475
1476Run Snort in IDS mode on an entire directory of pcaps, processing
1477each input source on a separate thread:
1478
1479snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
1480    --pcap-filter '*.pcap' --max-packet-threads 8
1481
1482Run Snort on 2 interfaces, eth0 and eth1:
1483
1484snort -c $my_path/etc/snort/snort.lua -i "eth0 eth1" -z 2 -A cmg
1485
1486Run Snort inline with the afpacket DAQ:
1487
1488snort -c $my_path/etc/snort/snort.lua --daq afpacket -i "eth0:eth1" \
1489    -A cmg
1490
1491
14924.5. Plugins
1493
1494--------------
1495
1496Load external plugins and use the "ex" alert:
1497
1498snort -c $my_path/etc/snort/snort.lua \
1499    --plugin-path $my_path/lib/snort_extra \
1500    -A alert_ex -r /path/to/my.pcap
1501
1502Test the LuaJIT rule option find loaded from stdin:
1503
1504snort -c $my_path/etc/snort/snort.lua \
1505    --script-path $my_path/lib/snort_extra \
1506    --stdin-rules -A cmg -r /path/to/my.pcap << END
1507alert tcp any any -> any 80 (
1508    sid:3; msg:"found"; content:"GET";
1509    find:"pat='HTTP/1%.%d'" ; )
1510END
1511
1512
15134.6. Output Files
1514
1515--------------
1516
1517To make it simple to configure outputs when you run with multiple
1518packet threads, output files are not explicitly configured. Instead,
1519you can use the options below to format the paths:
1520
1521<logdir>/[<run_prefix>][<id#>][<X>]<name>
1522
1523Log to unified in the current directory:
1524
1525snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A unified2
1526
1527Log to unified in the current directory with a different prefix:
1528
1529snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A unified2 \
1530    --run-prefix take2
1531
1532Log to unified in /tmp:
1533
1534snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A unified2 -l /tmp
1535
1536Run 4 packet threads and log with thread number prefix (0-3):
1537
1538snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
1539    --pcap-filter '*.pcap' -z 4 -A unified2
1540
1541Run 4 packet threads and log in thread number subdirs (0-3):
1542
1543snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
1544    --pcap-filter '*.pcap' -z 4 -A unified2 --id-subdir
1545
1546Note
1547
1548subdirectories are created automatically if required. Log filename is
1549based on module name that writes the file. All text mode outputs
1550default to stdout. These options can be combined.
1551
1552
15534.7. DAQ Alternatives
1554
1555--------------
1556
1557Process hext packets from stdin:
1558
1559snort -c $my_path/etc/snort/snort.lua \
1560    --daq-dir $my_path/lib/snort/daqs --daq hext -i tty << END
1561$packet 10.1.2.3 48620 -> 10.9.8.7 80
1562"GET / HTTP/1.1\r\n"
1563"Host: localhost\r\n"
1564"\r\n"
1565END
1566
1567Process raw ethernet from hext file:
1568
1569snort -c $my_path/etc/snort/snort.lua \
1570    --daq-dir $my_path/lib/snort/daqs --daq hext \
1571    --daq-var dlt=1 -r <hext-file>
1572
1573Process a directory of plain files (ie non-pcap) with 4 threads with
15748K buffers:
1575
1576snort -c $my_path/etc/snort/snort.lua \
1577    --daq-dir $my_path/lib/snort/daqs --daq file \
1578    --pcap-dir path/to/files -z 4 -s 8192
1579
1580Bridge two TCP connections on port 8000 and inspect the traffic:
1581
1582snort -c $my_path/etc/snort/snort.lua \
1583    --daq-dir $my_path/lib/snort/daqs --daq socket
1584
1585
15864.8. Logger Alternatives
1587
1588--------------
1589
1590Dump TCP stream payload in hext mode:
1591
1592snort -c $my_path/etc/snort/snort.lua -L hext
1593
1594Output timestamp, pkt_num, proto, pkt_gen, dgm_len, dir, src_ap,
1595dst_ap, rule, action for each alert:
1596
1597snort -c $my_path/etc/snort/snort.lua -A csv
1598
1599Output the old test format alerts:
1600
1601snort -c $my_path/etc/snort/snort.lua \
1602    --lua "alert_csv = { fields = 'pkt_num gid sid rev', separator = '\t' }"
1603
1604
16054.9. Shell
1606
1607--------------
1608
1609You must build with --enable-shell to make the command line shell
1610available.
1611
1612Enable shell mode:
1613
1614snort --shell <args>
1615
1616You will see the shell mode command prompt, which looks like this:
1617
1618o")~
1619
1620(The prompt can be changed with the SNORT_PROMPT environment
1621variable.)
1622
1623You can pause immediately after loading the configuration and again
1624before exiting with:
1625
1626snort --shell --pause <args>
1627
1628In that case you must issue the resume() command to continue. Enter
1629quit() to terminate Snort or detach() to exit the shell. You can list
1630the available commands with help().
1631
1632To enable local telnet access on port 12345:
1633
1634snort --shell -j 12345 <args>
1635
1636The command line interface is still under development. Suggestions
1637are welcome.
1638
1639
16404.10. Signals
1641
1642--------------
1643
1644Note
1645
1646The following examples assume that Snort is currently running and has
1647a process ID of <pid>.
1648
1649Modify and Reload Configuration:
1650
1651echo 'suppress = { { gid = 1, sid = 2215 } }' >> $my_path/etc/snort/snort.lua
1652kill -hup <pid>
1653
1654Dump stats to stdout:
1655
1656kill -usr1 <pid>
1657
1658Shutdown normally:
1659
1660kill -term <pid>
1661
1662Exit without flushing packets:
1663
1664kill -quit <pid>
1665
1666List available signals:
1667
1668snort --help-signals
1669
1670Note
1671
1672The available signals may vary from platform to platform.
1673
1674
1675---------------------------------------------------------------------
1676
16775. Features
1678
1679---------------------------------------------------------------------
1680
1681This section explains how to use key features of Snort.
1682
1683
16845.1. Active Response
1685
1686--------------
1687
1688Snort can take more active role in securing network by sending active
1689responses to shutdown offending sessions. When active responses is
1690enabled, snort will send TCP RST or ICMP unreachable when dropping a
1691session.
1692
16935.1.1. Changes from Snort 2.9
1694
1695  * stream5_global:max_active_responses and min_response_seconds are
1696    now active.max_responses and active.min_interval.
1697  * Response actions were removed from IPS rule body to the rule
1698    action in the header. This includes react, reject, and rewrite
1699    (split out of replace which now just does the detection part).
1700    These IPS actions are plugins.
1701  * drop and block are synonymous in Snort 2.9 but in Snort 3.0 drop
1702    means don’t forward the current packet only whereas block means
1703    don’t forward this or any following packet on the flow.
1704
17055.1.2. Configure Active
1706
1707Active response is enabled by configuring one of following IPS action
1708plugins:
1709
1710react = { }
1711reject = { }
1712
1713When these active responses are not configured the default
1714configuration is used.
1715
1716Active responses will be performed for reject, react or rewrite IPS
1717rule actions, and response packets are encoded based on the
1718triggering packet. TTL will be set to the value captured at session
1719pickup.
1720
1721Configure the number of attempts to land a TCP RST within the
1722session’s current window (so that it is accepted by the receiving
1723TCP). This sequence "strafing" is really only useful in passive mode.
1724In inline mode the reset is put straight into the stream in lieu of
1725the triggering packet so strafing is not necessary.
1726
1727Each attempt (sent in rapid succession) has a different sequence
1728number. Each active response will actually cause this number of TCP
1729resets to be sent. TCP data is multiplied similarly. At most 1 ICMP
1730unreachable is sent, iff attempts > 0.
1731
1732Device IP will perform network layer injection. It is probably a
1733better choice to specify an interface and avoid kernel routing
1734tables, etc.
1735
1736dst_mac will change response destination MAC address, if the device
1737is eth0, eth1, eth2 etc. Otherwise, response destination MAC address
1738is derived from packet.
1739
1740Example:
1741
1742active =
1743{
1744    attempts = 2,
1745    device = "eth0",
1746    dst_mac = "00:06:76:DD:5F:E3",
1747}
1748
17495.1.3. Reject
1750
1751IPS action reject perform active response to shutdown hostile network
1752session by injecting TCP resets (TCP connections) or ICMP unreachable
1753packets.
1754
1755Example:
1756
1757reject = { reset = "both", control = "all" }
1758
1759local_rules =
1760[[
1761reject tcp ( msg:"hostile connection"; flow:established, to_server;
1762content:"HACK!"; sid:1; )
1763]]
1764
1765ips =
1766{
1767    rules = local_rules,
1768}
1769
17705.1.4. React
1771
1772IPS action react enables sending an HTML page on a session and then
1773resetting it.
1774
1775The headers used are:
1776
1777"HTTP/1.1 403 Forbidden\r\n" \
1778"Connection: close\r\n" \
1779"Content-Type: text/html; charset=utf-8\r\n" \
1780"Content-Length: 438\r\n" \
1781"\r\n"
1782
1783The page to be sent can be read from a file:
1784
1785react = { page = "customized_block_page.html", }
1786
1787or else the default is used:
1788
1789"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\r\n" \
1790"    \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\r\n" \
1791"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\r\n" \
1792"<head>\r\n" \
1793"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\r\n" \
1794"<title>Access Denied</title>\r\n" \
1795"</head>\r\n" \
1796"<body>\r\n" \
1797"<h1>Access Denied</h1>\r\n" \
1798"<p>You are attempting to access a forbidden site.<br />" \
1799"Consult your system administrator for details.</p>\r\n" \
1800"</body>\r\n" \
1801"</html>\r\n"
1802
1803Note that the file contains the message body only. The headers will
1804be added with an updated value for Content-Length. For HTTP/2 traffic
1805Snort will translate the page to HTTP/2 format.
1806
1807Limitations for HTTP/2:
1808
1809  * Packet will be injected against the last received stream id.
1810  * Injection triggered while server-to-client flow of traffic is in
1811    a middle of a frame is not supported. The traffic will be
1812    blocked, but the page will not be injected/displayed.
1813
1814When using react, payload injector must be configured as well. Also
1815Snort should be in ips mode, so the rule is triggered on the client
1816packet, and not delayed until the server sends ACK. To achieve this
1817use the default normalizer. It will set normalizer.tcp.ips = true.
1818Example:
1819
1820react = { page = "my_block_page.html" }
1821payload_injector = { }
1822normalizer = { }
1823
1824local_rules =
1825[[
1826react http ( msg:"Unauthorized Access Prohibited!"; flow:established,
1827to_server; http_method; content:"GET"; sid:1; )
1828]]
1829
1830ips =
1831{
1832    rules = local_rules,
1833}
1834
1835React has debug trace functionality. It can be used to get traces in
1836case injection is not successful. To turn it on:
1837
1838trace =
1839{
1840    modules = { react = { all = 1 } }
1841}
1842
18435.1.5. Rewrite
1844
1845IPS action "rewrite" enables overwrite packet contents based on
1846"replace" option in the rules. Note that using "rewrite" action
1847without "replace" option will raise corresponding rule alert, but
1848will not overwrite the packet payload.
1849
1850For example:
1851
1852local_rules =
1853[[
1854rewrite tcp 10.1.1.87 any -> 10.1.1.0/24 80
1855(
1856    sid:1000002;
1857    msg:"test replace rule";
1858    content:"index.php", nocase;
1859    replace:"indax.php";
1860)
1861]]
1862
1863ips =
1864{
1865    rules = local_rules,
1866}
1867
1868this rule replaces the first occurrence of "index.php" with
1869"indax.php", and "rewrite" action updates that packet.
1870
1871Content and replacement are aligned to the right side of the matching
1872content and are limited not by the size of the matching content, but
1873by the boundaries of the packet.
1874
1875Example:
1876
1877rewrite http any any -> any any
1878(
1879    msg:"Small replace";
1880    content:"content";
1881    replace:"text";
1882    sid:1000002;
1883)
1884
1885this rule replaces "malicious content" to "malicious context".
1886
1887Example:
1888
1889rewrite http any any -> any any
1890(
1891    msg:"Big replace";
1892    content:"content";
1893    replace:"y favorite page!";
1894    sid:1000002;
1895)
1896
1897this rule replaces "malicious content" to "my favorite page!".
1898
1899Be aware that after the match there should be enough room left for
1900the "replace" content in the matched packet. If there is not enough
1901space for the "replace" content the rule will not match.
1902
1903"replace" works for raw packets only. So, TCP data must either fit
1904under the "pkt_data" buffer requirements or one should enable
1905detection on TCP payload before reassembly:
1906search_engine.detect_raw_tcp=true. For example:
1907
1908Rule that does not require search_engine.detect_raw_tcp=true:
1909
1910rewrite udp any any -> any any
1911(
1912    msg:"TEST 1";
1913    sid:1000002;
1914    content:"attack";
1915    replace:"abc123";
1916)
1917
1918Rule that does require search_engine.detect_raw_tcp=true:
1919
1920rewrite http any any -> any any
1921(
1922    msg:"TEST 2";
1923    content:"/content.html";
1924    replace:"/replace.html";
1925    sid:1000002;
1926)
1927
1928
19295.2. AppId
1930
1931--------------
1932
1933Network administrators need application awareness in order to fine
1934tune their management of the ever-growing number of applications
1935passing traffic over the network. Application awareness allows an
1936administrator to create rules for applications as needed by the
1937business. The rules can be used to take action based on the
1938application, such as block, allow or alert.
1939
19405.2.1. Overview
1941
1942The AppId inspector provides an application level view when managing
1943networks by providing the following features:
1944
1945  * Network control: The inspector works with Snort rules by
1946    providing a set of application identifiers (AppIds) to Snort rule
1947    writers.
1948  * Application usage awareness: The inspector outputs statistics to
1949    show how many times applications are being used on the network.
1950  * Custom applications: Administrators can create their own
1951    application detectors to detect new applications. The detectors
1952    are written in Lua and interface with Snort using a well-defined
1953    C-Lua API.
1954  * Open Detector Package (ODP): A set of pre-defined application
1955    detectors are provided by the Snort team and can be downloaded
1956    from snort.org.
1957
19585.2.2. Dependency Requirements
1959
1960For proper functioning of the AppId inspector, at a minimum stream
1961flow tracking must be enabled. In addition, to identify TCP-based or
1962UDP-based applications, the appropriate stream inspector must be
1963enabled, e.g. stream_tcp or stream_udp.
1964
1965In order to identify HTTP-based applications, the HTTP inspector must
1966be enabled. Otherwise, only non-HTTP applications will be identified.
1967
1968AppId subscribes to the inspection events published by other
1969inspectors, such as the HTTP and SSL inspectors, to gain access to
1970the data needed. It uses that data to help determine the application
1971ID.
1972
1973AppId subscribes to the events published by SIP and DCE/RPC
1974inspectors to detect applications on expected flows.
1975
19765.2.3. Configuration
1977
1978The AppId feature can be enabled via configuration. To enable it with
1979the default settings use:
1980
1981appid = { }
1982
1983To use an AppId as a matching parameter in an IPS rule, use the
1984appids keyword. For example, to block HTTP traffic that contains a
1985specific header:
1986
1987block tcp any any -> 192.168.0.1 any ( msg:"Block Malicious HTTP header";
1988  appids:"HTTP"; content:"X-Header: malicious"; sid:18000; )
1989
1990Alternatively, the HTTP application can be specified in place of tcp
1991instead of using the appids keyword. The AppId inspector will set the
1992service when it is discovered so it can be used in IPS rules like
1993this. Note that this rule also does not specify the IPs or ports
1994which default to any.
1995
1996block http ( msg:"Block Malicious HTTP header";
1997  content:"X-Header: malicious"; sid:18000; )
1998
1999It’s possible to specify multiple applications (as many as desired)
2000with the appids keyword. A rule is considered a match if any of the
2001applications on the rule match. Note that this rule does not match
2002specific content which will reduce performance.
2003
2004alert tcp any any -> 192.168.0.1 any ( msg:"Alert ";
2005  appids:"telnet,ssh,smtp,http";
2006
2007Below is a minimal Snort configuration that is sufficient to block
2008flows based on a specific HTTP header:
2009
2010stream = { }
2011
2012stream_tcp = { }
2013
2014binder =
2015{
2016    {
2017        when =
2018        {
2019            proto = 'tcp',
2020            ports = [[ 80 8080 ]],
2021        },
2022        use =
2023        {
2024            type = 'http_inspect',
2025        },
2026    },
2027}
2028
2029http_inspect = { }
2030
2031appid = { }
2032
2033local_rules =
2034[[
2035block http ( msg:"openAppId: test content match for app http";
2036content:"X-Header: malicious"; sid:18760; rev:4; )
2037]]
2038
2039ips =
2040{
2041    rules = local_rules,
2042}
2043
20445.2.4. Session Application Identifiers
2045
2046There are up to four AppIds stored in a session as defined below:
2047
2048  * serviceAppId - An appId associated with server side of a session.
2049    Example: http server.
2050  * clientAppId - An appId associated with application on client side
2051    of a session. Example: Firefox.
2052  * payloadAppId - For services like http this appId is associated
2053    with a webserver host. Example: Facebook.
2054  * miscAppId - For some encapsulated protocols, this is the highest
2055    encapsulated application.
2056
2057For packets originating from the client, a payloadAppid in a session
2058is matched with all AppIds listed on a rule. Thereafter miscAppId,
2059clientAppId and serviceAppId are matched. Since Alert Events contain
2060one AppId, only the first match is reported. If a rule without an
2061appids option matches, then the most specific appId (in order of
2062payload, misc, client, server) is reported.
2063
2064The same logic is followed for packets originating from the server
2065with one exception. The order of matching is changed to make
2066serviceAppId come before clientAppId.
2067
20685.2.5. AppId Usage Statistics
2069
2070The AppId inspector prints application network usage periodically in
2071the snort log directory in unified2 format. File name, time interval
2072for statistic and file rollover are controlled by appId inspection
2073configuration.
2074
20755.2.6. Open Detector Package (ODP) Installation
2076
2077Application detectors from Snort team will be delivered in a separate
2078package called the Open Detector Package (ODP) that can be downloaded
2079from snort.org. ODP is a package that contains the following
2080artifacts:
2081
2082  * Application detectors in the Lua language.
2083  * appMapping.data file containing application metadata. This file
2084    should not be modified. The first column contains application
2085    identifier and second column contains application name. Other
2086    columns contain internal information.
2087  * Lua library file DetectorCommon.lua.
2088
2089A user can install the ODP package in any directory and configure
2090this directory via the app_detector_dir option in the appid
2091preprocessor configuration. Installing ODP will not modify any
2092subdirectory named custom, where user-created detectors are located.
2093
2094When installed, ODP will create following sub-directories:
2095
2096  * odp/lua //Cisco Lua detectors
2097  * odp/libs //Cisco Lua modules
2098
20995.2.7. User Created Application Detectors
2100
2101Users can detect new applications by adding detectors in the Lua
2102language. A document will be posted on the Snort Website with details
2103on API. Users can also copy over Snort team provided detectors and
2104modify them. Users can also use the detector creation tool described
2105in the next section.
2106
2107Users must organize their Lua detectors and libraries by creating the
2108following directory structure, under the ODP installation directory.
2109
2110  * custom/lua //Lua detectors
2111  * custom/libs //Lua modules
2112
2113The root path is specified by the "app_detector_dir" parameter of the
2114appid section of snort.conf:
2115
2116appid  =
2117{
2118    app_detector_dir = '/usr/local/lib/openappid',
2119}
2120
2121So the path to the user-created lua files would be /usr/local/lib/
2122openappid/custom/lua/
2123
2124None of the directories below /usr/local/lib/openappid/ would be
2125added for you.
2126
21275.2.8. Application Detector Reload
2128
2129Both ODP detectors and user created detectors can be reloaded using
2130the command appid.reload_detectors(). Detectors are expected to be
2131updated in the path appid.app_detector_dir before this command is
2132issued. The command takes no parameters.
2133
21345.2.9. Application Detector Creation Tool
2135
2136For rudimentary Lua detectors, there is a tool provided called
2137appid_detector_builder.sh. This is a simple, menu-driven bash script
2138which creates .lua files in your current directory, based on your
2139choices and on patterns you supply.
2140
2141When you launch the script, it will prompt for the Application Id
2142that you are giving for your detector. This is free-form ASCII with
2143minor restrictions. The Lua detector file will be named based on your
2144Application Id. If the file name already exists you will be prompted
2145to overwrite it.
2146
2147You will also be prompted for a description of your detector to be
2148placed in the comments of the Lua source code. This is optional.
2149
2150You will then be asked a series of questions designed to construct
2151Lua code based on the kind of pattern data, protocol, port(s), etc.
2152
2153When complete, the Protocol menu will be changed to include the
2154option, "Save Detector". Instead of saving the file and exiting the
2155script, you are allowed to give additional criteria for another
2156pattern which may also be incorporated in the detection scheme. Then
2157either pattern, when matched, will be considered a valid detection.
2158
2159For example, your first choices might create an HTTP detection
2160pattern of "example.com", and the next set of choices would add the
2161HTTP detection pattern of "example.uk.co" (an equally fictional
2162British counterpart). They would then co-exist in the Lua detector,
2163and either would cause a detection with the name you give for your
2164Application Id.
2165
2166The resulting .lua file will need to be placed in the directory,
2167"custom/lua", described in the previous section of the README above
2168called "User Created Application Detectors"
2169
2170
21715.3. Binder
2172
2173--------------
2174
2175One of the fundamental differences between Snort 2 and Snort 3
2176concerns configuration related to networks and ports. Here is a brief
2177review of Snort 2 configuration for network and service related
2178components:
2179
2180  * Snort’s configuration has a default policy and optional policies
2181    selected by VLAN or network (with config binding).
2182  * Each policy contains a user defined set of preprocessor
2183    configurations.
2184  * Each preprocessor has a default configuration and some support
2185    non-default configurations selected by network.
2186  * Most preprocessors have port configurations.
2187  * The default policy may also contain a list of ports to ignore.
2188
2189In Snort 3, the above configurations are done in a single module
2190called the binder. Here is an example:
2191
2192binder =
2193{
2194    -- allow all tcp port 22:
2195    -- (similar to Snort 2 config ignore_ports)
2196    { when = { proto = 'tcp', ports = '22' }, use = { action = 'allow' } },
2197
2198-- select a config file by vlan
2199-- (similar to Snort 2 config binding by vlan)
2200{ when = { vlans = '1024' }, use = { file = 'vlan.lua' } },
2201
2202-- use a non-default HTTP inspector for port 8080:
2203-- (similar to a Snort 2 targeted preprocessor config)
2204{ when = { nets = '192.168.0.0/16', proto = 'tcp', ports = '8080' },
2205  use = { name = 'alt_http', type = 'http_inspect' } },
2206
2207-- use the default inspectors:
2208-- (similar to a Snort 2 default preprocessor config)
2209{ when = { proto = 'tcp' }, use = { type = 'stream_tcp' } },
2210{ when = { service = 'http' }, use = { type = 'http_inspect' } },
2211
2212    -- figure out which inspector to run automatically:
2213    { use = { type = 'wizard' } }
2214}
2215
2216Bindings are evaluated when a session starts and again if and when
2217service is identified on the session. Essentially, the bindings are a
2218list of when-use rules evaluated from top to bottom. The first
2219matching network and service configurations are applied. binder.when
2220can contain any combination of criteria and binder.use can specify an
2221action, config file, or inspector configuration.
2222
2223
22245.4. Byte rule options
2225
2226--------------
2227
22285.4.1. byte_test
2229
2230This rule option tests a byte field against a specific value (with
2231operator). Capable of testing binary values or converting
2232representative byte strings to their binary equivalent and testing
2233them.
2234
2235Snort uses the C operators for each of these operators. If the &
2236operator is used, then it would be the same as using
2237
2238if (data & value) { do_something(); }
2239
2240! operator negates the results from the base check. !<oper> is
2241considered as
2242
2243!(data <oper> value)
2244
2245Note: The bitmask option applies bitwise AND operator on the bytes
2246converted. The result will be right-shifted by the number of bits
2247equal to the number of trailing zeros in the mask. This applies for
2248the other rule options as well.
2249
22505.4.1.1. Examples
2251
2252alert tcp (byte_test:2, =, 568, 0, bitmask 0x3FF0;)
2253
2254This example extracts 2 bytes at offset 0, performs bitwise and with
2255bitmask 0x3FF0, shifts the result by 4 bits and compares to 568.
2256
2257alert udp (byte_test:4, =, 1234, 0, string, dec;
2258    msg:"got 1234!";)
2259
2260alert udp (byte_test:8, =, 0xdeadbeef, 0, string, hex;
2261    msg:"got DEADBEEF!";)
2262
22635.4.2. byte_jump
2264
2265The byte_jump rule option allows rules to be written for length
2266encoded protocols trivially. By having an option that reads the
2267length of a portion of data, then skips that far forward in the
2268packet, rules can be written that skip over specific portions of
2269length-encoded protocols and perform detection in very specific
2270locations.
2271
22725.4.2.1. Examples
2273
2274alert tcp (content:"Begin";
2275    byte_jump:0, 0, from_end, post_offset -6;
2276    content:"end..", distance 0, within 5;
2277    msg:"Content match from end of the payload";)
2278
2279alert tcp (content:"catalog";
2280    byte_jump:2, 1, relative, post_offset 2, bitmask 0x03f0;
2281    byte_test:2, =, 968, 0, relative;
2282    msg:"Bitmask applied on the 2 bytes extracted for byte_jump";)
2283
22845.4.3. byte_extract
2285
2286The byte_extract keyword is another useful option for writing rules
2287against length-encoded protocols. It reads in some number of bytes
2288from the packet payload and saves it to a variable. These variables
2289can be referenced later in the rule, instead of using hard-coded
2290values.
2291
22925.4.3.1. Other options which use byte_extract variables
2293
2294A byte_extract rule option detects nothing by itself. Its use is in
2295extracting packet data for use in other rule options.
2296
2297Here is a list of places where byte_extract variables can be used:
2298
2299  * content/uricontent: offset, depth, distance, within
2300  * byte_test: offset, value
2301  * byte_jump: offset, post_offset
2302  * isdataat: offset
2303
23045.4.3.2. Examples
2305
2306alert tcp (byte_extract:1, 0, str_offset;
2307    byte_extract:1, 1, str_depth;
2308    content:"bad stuff", offset str_offset, depth str_depth;
2309    msg:"Bad Stuff detected within field";)
2310
2311alert tcp (content:"START"; byte_extract:1, 0, myvar, relative;
2312    byte_jump:1, 3, relative, post_offset myvar;
2313    content:"END", distance 6, within 3;
2314    msg: "byte_jump - pass variable to post_offset";)
2315
2316This example uses two variables.
2317
2318The first variable keeps the offset of a string, read from a byte at
2319offset 0. The second variable keeps the depth of a string, read from
2320a byte at offset 1. These values are used to constrain a pattern
2321match to a smaller area.
2322
2323alert tcp (content:"|04 63 34 35|", offset 4, depth 4;
2324    byte_extract: 2, 0, var_match, relative, bitmask 0x03ff;
2325    byte_test: 2, =, var_match, 2, relative;
2326    msg:"Test value match, after applying bitmask on bytes extracted";)
2327
23285.4.4. byte_math
2329
2330Perform a mathematical operation on an extracted value and a
2331specified value or existing variable, and store the outcome in a new
2332resulting variable. These resulting variables can be referenced later
2333in the rule, at the same places as byte_extract variables.
2334
2335The syntax for this rule option is different. The order of the
2336options is critical for the other rule options and can’t be changed.
2337For example, the first option is the number of bytes to extract. Here
2338the name of the option is explicitly written, for example : bytes 2.
2339The order is not important.
2340
2341Note
2342
2343Byte_math operations are performed on unsigned 32-bit values. When
2344writing a rule it should be taken into consideration to avoid wrap
2345around.
2346
23475.4.4.1. Examples
2348
2349alert tcp ( byte_math: bytes 2, offset 0, oper *, rvalue 10, result area;
2350   byte_test:2,>,area,16;)
2351
2352At the zero offset of the payload, extract 2 bytes and apply
2353multiplication operation with value 10. Store result in variable
2354area. The area variable is given as input to byte_test value option.
2355
2356Let’s consider 2 bytes of extracted data is 5. The rvalue is 10.
2357Result variable area is 50 ( 5 * 10 ). Area variable can be used in
2358either byte_test offset/value options.
2359
23605.4.5. Testing Numerical Values
2361
2362The rule options byte_test and byte_jump were written to support
2363writing rules for protocols that have length encoded data. RPC was
2364the protocol that spawned the requirement for these two rule options,
2365as RPC uses simple length based encoding for passing data.
2366
2367In order to understand why byte test and byte jump are useful, let’s
2368go through an exploit attempt against the sadmind service.
2369
2370This is the payload of the exploit:
2371
237289 09 9c e2 00 00 00 00 00 00 00 02 00 01 87 88  ................
237300 00 00 0a 00 00 00 01 00 00 00 01 00 00 00 20  ...............
237440 28 3a 10 00 00 00 0a 4d 45 54 41 53 50 4c 4f  @(:.....metasplo
237549 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00  it..............
237600 00 00 00 00 00 00 00 40 28 3a 14 00 07 45 df  ........@(:...e.
237700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
237800 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00  ................
237900 00 00 00 00 00 00 04 00 00 00 00 00 00 00 04  ................
23807f 00 00 01 00 01 87 88 00 00 00 0a 00 00 00 04  ................
23817f 00 00 01 00 01 87 88 00 00 00 0a 00 00 00 11  ................
238200 00 00 1e 00 00 00 00 00 00 00 00 00 00 00 00  ................
238300 00 00 00 00 00 00 3b 4d 45 54 41 53 50 4c 4f  .......;metasplo
238449 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00  it..............
238500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
238600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
238700 00 00 00 00 00 00 06 73 79 73 74 65 6d 00 00  ........system..
238800 00 00 15 2e 2e 2f 2e 2e 2f 2e 2e 2f 2e 2e 2f  ....../../../../
23892e 2e 2f 62 69 6e 2f 73 68 00 00 00 00 00 04 1e  ../bin/sh.......
2390
2391Let’s break this up, describe each of the fields, and figure out how
2392to write a rule to catch this exploit.
2393
2394There are a few things to note with RPC:
2395
2396Numbers are written as uint32s, taking four bytes. The number 26
2397would show up as 0x0000001a.
2398
2399Strings are written as a uint32 specifying the length of the string,
2400the string, and then null bytes to pad the length of the string to
2401end on a 4-byte boundary. The string bob would show up as
24020x00000003626f6200.
2403
240489 09 9c e2     - the request id, a random uint32, unique to each request
240500 00 00 00     - rpc type (call = 0, response = 1)
240600 00 00 02     - rpc version (2)
240700 01 87 88     - rpc program (0x00018788 = 100232 = sadmind)
240800 00 00 0a     - rpc program version (0x0000000a = 10)
240900 00 00 01     - rpc procedure (0x00000001 = 1)
241000 00 00 01     - credential flavor (1 = auth_unix)
241100 00 00 20     - length of auth_unix data (0x20 = 32)
2412
2413## the next 32 bytes are the auth_unix data
241440 28 3a 10 - unix timestamp (0x40283a10 = 1076378128 = feb 10 01:55:28 2004 gmt)
241500 00 00 0a - length of the client machine name (0x0a = 10)
24164d 45 54 41 53 50 4c 4f 49 54 00 00  - metasploit
2417
241800 00 00 00 - uid of requesting user (0)
241900 00 00 00 - gid of requesting user (0)
242000 00 00 00 - extra group ids (0)
2421
242200 00 00 00 - verifier flavor (0 = auth_null, aka none)
242300 00 00 00 - length of verifier (0, aka none)
2424
2425The rest of the packet is the request that gets passed to procedure 1
2426of sadmind.
2427
2428However, we know the vulnerability is that sadmind trusts the uid
2429coming from the client. sadmind runs any request where the client’s
2430uid is 0 as root. As such, we have decoded enough of the request to
2431write our rule.
2432
2433First, we need to make sure that our packet is an RPC call.
2434
2435content:"|00 00 00 00|", offset 4, depth 4;
2436
2437Then, we need to make sure that our packet is a call to sadmind.
2438
2439content:"|00 01 87 88|", offset 12, depth 4;
2440
2441Then, we need to make sure that our packet is a call to the procedure
24421, the vulnerable procedure.
2443
2444content:"|00 00 00 01|", offset 20, depth 4;
2445
2446Then, we need to make sure that our packet has auth_unix credentials.
2447
2448content:"|00 00 00 01|", offset 24, depth 4;
2449
2450We don’t care about the hostname, but we want to skip over it and
2451check a number value after the hostname. This is where byte_test is
2452useful. Starting at the length of the hostname, the data we have is:
2453
245400 00 00 0a 4d 45 54 41 53 50 4c 4f 49 54 00 00
245500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
245600 00 00 00
2457
2458We want to read 4 bytes, turn it into a number, and jump that many
2459bytes forward, making sure to account for the padding that RPC
2460requires on strings. If we do that, we are now at:
2461
246200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
246300 00 00 00
2464
2465which happens to be the exact location of the uid, the value we want
2466to check.
2467
2468In English, we want to read 4 bytes, 36 bytes from the beginning of
2469the packet, and turn those 4 bytes into an integer and jump that many
2470bytes forward, aligning on the 4-byte boundary. To do that in a Snort
2471rule, we use:
2472
2473byte_jump:4,36,align;
2474
2475then we want to look for the uid of 0.
2476
2477content:"|00 00 00 00|", within 4;
2478
2479Now that we have all the detection capabilities for our rule, let’s
2480put them all together.
2481
2482content:"|00 00 00 00|", offset 4, depth 4;
2483content:"|00 01 87 88|", offset 12, depth 4;
2484content:"|00 00 00 01|", offset 20, depth 4;
2485content:"|00 00 00 01|", offset 24, depth 4;
2486byte_jump:4,36,align;
2487content:"|00 00 00 00|", within 4;
2488
2489The 3rd and fourth string match are right next to each other, so we
2490should combine those patterns. We end up with:
2491
2492content:"|00 00 00 00|", offset 4, depth 4;
2493content:"|00 01 87 88|", offset 12, depth 4;
2494content:"|00 00 00 01 00 00 00 01|", offset 20, depth 8;
2495byte_jump:4,36,align;
2496content:"|00 00 00 00|", within 4;
2497
2498If the sadmind service was vulnerable to a buffer overflow when
2499reading the client’s hostname, instead of reading the length of the
2500hostname and jumping that many bytes forward, we would check the
2501length of the hostname to make sure it is not too large.
2502
2503To do that, we would read 4 bytes, starting 36 bytes into the packet,
2504turn it into a number, and then make sure it is not too large (let’s
2505say bigger than 200 bytes). In Snort, we do:
2506
2507byte_test:4,>,200,36;
2508
2509Our full rule would be:
2510
2511content:"|00 00 00 00|", offset 4, depth 4;
2512content:"|00 01 87 88|", offset 12, depth 4;
2513content:"|00 00 00 01 00 00 00 01|", offset 20, depth 8;
2514byte_test:4,>,200,36;
2515
2516
25175.5. Consolidated Config
2518
2519--------------
2520
2521Config dump mode generates a consolidated dump of the config passed
2522to Snort. This output consists of the configured values as well as
2523the module defaults for the values that aren’t configured.
2524
2525In the dump mode Snort validates the config (similar to option -T)
2526and suppresses unrelated messages going to stdout (configuration
2527warnings and errors are still printed to stderr).
2528
2529The dump mode is activated by the following options:
2530--dump-config-text, --dump-config=all, --dump-config=top. They are
2531described in detail below.
2532
2533The simple configuration is used in examples. The output contains
2534applied configurations (defaults and configured). To simplify the
2535output we show a brief list of default options.
2536
2537snort.lua
2538
2539stream =
2540{
2541    max_flows = 2
2542}
2543
2544stream_tcp =
2545{
2546    show_rebuilt_packets = true
2547}
2548
2549binder =
2550{
2551    { when = { nets = '10.1.2.0/24' }, use = { inspection_policy = 'http.lua' } },
2552    { when = { nets = '192.168.2.0/24' }, use = { inspection_policy = 'sip.lua' } },
2553}
2554
2555http.lua
2556
2557wizard =
2558{
2559    spells =
2560    {
2561        { service = 'http', proto = 'tcp', client_first = true, to_server = { 'GET' }, to_client = { 'HTTP/' } },
2562    }
2563}
2564
2565sip.lua
2566
2567wizard =
2568{
2569    spells =
2570    {
2571        { service = 'sip', to_server = { 'INVITE' } },
2572    }
2573}
2574
25755.5.1. Text Format
2576
2577The --dump-config-text option verifies the configuration and dumps it
2578to stdout in text format. The output contains a config of the main
2579policy and all other included sub-policies.
2580
2581Example: snort -c snort.lua --dump-config-text
2582
2583consolidated config for snort.lua
2584alerts.order="pass reset block drop alert log"
2585alerts.rate_filter_memcap=1048576
2586binder[0].when.ips_policy_id=0
2587binder[0].when.role="any"
2588binder[0].when.nets="10.1.2.0/24"
2589binder[0].use.action="inspect"
2590binder[0].use.inspection_policy="http.lua"
2591binder[1].when.ips_policy_id=0
2592binder[1].when.role="any"
2593binder[1].when.nets="192.168.2.0/24"
2594binder[1].use.action="inspect"
2595binder[1].use.inspection_policy="sip.lua"
2596output.obfuscate=false
2597output.wide_hex_dump=true
2598packets.address_space_agnostic=false
2599packets.limit=0
2600search_engine.split_any_any=true
2601search_engine.queue_limit=128
2602stream.file_cache.idle_timeout=180
2603stream.file_cache.cap_weight=32
2604stream.max_flows=2
2605stream_tcp.small_segments.maximum_size=0
2606stream_tcp.session_timeout=30
2607stream_tcp.track_only=false
2608stream_tcp.show_rebuilt_packets=true
2609consolidated config for http.lua
2610wizard.spells[0].proto="tcp"
2611wizard.spells[0].client_first=true
2612wizard.spells[0].service="http"
2613wizard.spells[0].to_client[0].spell="HTTP/"
2614wizard.spells[0].to_server[0].spell="GET"
2615consolidated config for sip.lua
2616wizard.spells[0].proto="tcp"
2617wizard.spells[0].client_first=true
2618wizard.spells[0].service="sip"
2619wizard.spells[0].to_server[0].spell="INVITE"
2620
2621For lists, the index next to the option name designates an element
2622parsing order.
2623
26245.5.2. JSON Format
2625
2626The --dump-config=all command-line option verifies the configuration
2627and dumps it to stdout in JSON format. The output contains a config
2628of the main policy and all other included sub-policies. Snort dumps
2629output in a one-line format.
2630
2631There is 3rd party tool jq for converting to a pretty printed format.
2632
2633Example: snort -c snort.lua --dump-config=all | jq .
2634
2635[
2636    {
2637        "filename": "snort.lua",
2638        "config": {
2639        "alerts": {
2640            "order": "pass reset block drop alert log",
2641            "rate_filter_memcap": 1048576
2642        },
2643        "binder": [
2644            {
2645            "when": {
2646                "ips_policy_id": 0,
2647                "role": "any",
2648                "nets": "10.1.2.0/24"
2649            },
2650            "use": {
2651                "action": "inspect",
2652                "inspection_policy": "http.lua"
2653            }
2654            },
2655            {
2656            "when": {
2657                "ips_policy_id": 0,
2658                "role": "any",
2659                "nets": "192.168.2.0/24"
2660            },
2661            "use": {
2662                "action": "inspect",
2663                "inspection_policy": "sip.lua"
2664            }
2665            }
2666        ],
2667        "output": {
2668            "obfuscate": false,
2669            "wide_hex_dump": true
2670        },
2671        "packets": {
2672            "address_space_agnostic": false,
2673            "limit": 0
2674        },
2675        "process": {
2676            "daemon": false,
2677            "dirty_pig": false,
2678            "utc": false
2679        },
2680        "search_engine": {
2681            "split_any_any": true,
2682            "queue_limit": 128
2683        },
2684        "stream": {
2685            "file_cache": {
2686            "idle_timeout": 180,
2687            "cap_weight": 32
2688            },
2689            "max_flows": 2
2690        },
2691        "stream_tcp": {
2692            "small_segments": {
2693                "maximum_size": 0
2694            },
2695            "session_timeout": 30,
2696            "track_only": false,
2697            "show_rebuilt_packets": true
2698        }
2699        }
2700    },
2701    {
2702        "filename": "http.lua",
2703        "config": {
2704        "wizard": {
2705            "spells": [
2706            {
2707                "proto": "tcp",
2708                "client_first": true,
2709                "service": "http",
2710                "to_client": [
2711                {
2712                    "spell": "HTTP/"
2713                }
2714                ],
2715                "to_server": [
2716                {
2717                    "spell": "GET"
2718                }
2719                ]
2720            }
2721            ]
2722        }
2723        }
2724    },
2725    {
2726        "filename": "sip.lua",
2727        "config": {
2728        "wizard": {
2729            "spells": [
2730            {
2731                "proto": "tcp",
2732                "client_first": true,
2733                "service": "sip",
2734                "to_server": [
2735                {
2736                    "spell": "INVITE"
2737                }
2738                ]
2739            }
2740            ]
2741        }
2742        }
2743    }
2744]
2745
2746The --dump-config=top command-line option is similar to --dump-config
2747=all, except it produces dump for the main policy only. It verifies
2748the configuration and dumps the main policy configuration to stdout
2749in JSON format.
2750
2751Example: snort -c snort.lua --dump-config=top | jq .
2752
2753{
2754    "alerts": {
2755        "order": "pass reset block drop alert log",
2756        "rate_filter_memcap": 1048576,
2757    },
2758    "binder": [
2759        {
2760            "when": {
2761                "ips_policy_id": 0,
2762                "role": "any",
2763                "nets": "10.1.2.0/24"
2764            },
2765            "use": {
2766                "action": "inspect",
2767                "inspection_policy": "http.lua"
2768            }
2769        },
2770        {
2771            "when": {
2772                "ips_policy_id": 0,
2773                "role": "any",
2774                "nets": "192.168.2.0/24"
2775            },
2776            "use": {
2777                "action": "inspect",
2778                "inspection_policy": "sip.lua"
2779            }
2780        }
2781    ],
2782    "output": {
2783        "obfuscate": false,
2784        "wide_hex_dump": true
2785    },
2786    "packets": {
2787        "address_space_agnostic": false,
2788        "limit": 0,
2789    },
2790    "process": {
2791        "daemon": false,
2792        "dirty_pig": false,
2793        "utc": false
2794    },
2795    "search_engine": {
2796        "split_any_any": true,
2797        "queue_limit": 128
2798    },
2799    "stream": {
2800        "file_cache": {
2801            "idle_timeout": 180,
2802            "cap_weight": 32
2803        }
2804        "max_flows": 2
2805    },
2806    "stream_tcp": {
2807        "small_segments": {
2808            "count": 0,
2809            "maximum_size": 0
2810        },
2811        "session_timeout": 30,
2812        "track_only": false,
2813        "show_rebuilt_packets": true
2814    },
2815}
2816
2817
28185.6. DCE Inspectors
2819
2820--------------
2821
2822The main purpose of these inspector are to perform SMB desegmentation
2823and DCE/RPC defragmentation to avoid rule evasion using these
2824techniques.
2825
28265.6.1. Overview
2827
2828The following transports are supported for DCE/RPC: SMB, TCP, and
2829UDP. New rule options have been implemented to improve performance,
2830reduce false positives and reduce the count and complexity of DCE/RPC
2831based rules.
2832
2833Different from Snort 2, the DCE-RPC preprocessor is split into three
2834inspectors - one for each transport: dce_smb, dce_tcp, dce_udp. This
2835includes the configuration as well as the inspector modules. The
2836Snort 2 server configuration is now split between the inspectors.
2837Options that are meaningful to all inspectors, such as policy and
2838defragmentation, are copied into each inspector configuration. The
2839address/port mapping is handled by the binder. Autodetect
2840functionality is replaced by wizard curses.
2841
28425.6.2. Quick Guide
2843
2844A typical dcerpce configuration looks like this:
2845
2846binder =
2847{
2848   {
2849       when =
2850       {
2851           proto = 'tcp',
2852           ports = '139 445 1025',
2853        },
2854       use =
2855       {
2856           type = 'dce_smb',
2857       },
2858    },
2859    {
2860       when =
2861       {
2862           proto = 'tcp',
2863           ports = '135 2103',
2864       },
2865       use =
2866       {
2867           type = 'dce_tcp',
2868       },
2869    },
2870    {
2871       when =
2872       {
2873           proto = 'udp',
2874           ports = '1030',
2875       },
2876       use =
2877       {
2878           type = 'dce_udp',
2879       },
2880    }
2881 }
2882
2883dce_smb = { }
2884
2885dce_tcp = { }
2886
2887dce_udp = { }
2888
2889In this example, it defines smb, tcp and udp inspectors based on
2890port. All the configurations are default.
2891
28925.6.3. Target Based
2893
2894There are enough important differences between Windows and Samba
2895versions that a target based approach has been implemented. Some
2896important differences:
2897
2898  * Named pipe instance tracking
2899  * Accepted SMB commands
2900  * AndX command chaining
2901  * Transaction tracking
2902  * Multiple Bind requests
2903  * DCE/RPC Fragmented requests - Context ID
2904  * DCE/RPC Fragmented requests - Operation number
2905  * DCE/RPC Stub data byte order
2906
2907Because of those differences, each inspector can be configured to
2908different policy. Here are the list of policies supported:
2909
2910  * WinXP (default)
2911  * Win2000
2912  * WinVista
2913  * Win2003
2914  * Win2008
2915  * Win7
2916  * Samba
2917  * Samba-3.0.37
2918  * Samba-3.0.22
2919  * Samba-3.0.20
2920
29215.6.4. Reassembling
2922
2923Both SMB inspector and TCP inspector support reassemble. Reassemble
2924threshold specifies a minimum number of bytes in the DCE/RPC
2925desegmentation and defragmentation buffers before creating a
2926reassembly packet to send to the detection engine. This option is
2927useful in inline mode so as to potentially catch an exploit early
2928before full defragmentation is done. A value of 0 s supplied as an
2929argument to this option will, in effect, disable this option. Default
2930is disabled.
2931
29325.6.5. SMB
2933
2934SMB inspector is one of the most complex inspectors. In addition to
2935supporting rule options and lots of inspector rule events, it also
2936supports file processing for both SMB version 1, 2, and 3.
2937
29385.6.5.1. Finger Print Policy
2939
2940In the initial phase of an SMB session, the client needs to
2941authenticate with a SessionSetupAndX. Both the request and response
2942to this command contain OS and version information that can allow the
2943inspector to dynamically set the policy for a session which allows
2944for better protection against Windows and Samba specific evasions.
2945
29465.6.5.2. File Inspection
2947
2948SMB inspector supports file inspection. A typical configuration looks
2949like this:
2950
2951binder =
2952{
2953   {
2954       when =
2955       {
2956           proto = 'tcp',
2957           ports = '139 445',
2958       },
2959       use =
2960       {
2961           type = 'dce_smb',
2962       },
2963   },
2964}
2965
2966dce_smb =
2967{
2968    smb_file_inspection = 'on',
2969    smb_file_depth = 0,
2970 }
2971
2972file_id =
2973{
2974    enable_type = true,
2975    enable_signature = true,
2976    enable_capture = true,
2977    file_rules = magics,
2978}
2979
2980First, define a binder to map tcp port 139 and 445 to smb. Then,
2981enable file inspection in smb inspection and set the file depth as
2982unlimited. Lastly, enable file inspector to inspect file type,
2983calculate file signature, and capture file. The details of file
2984inspector are explained in file processing section.
2985
2986SMB inspector does inspection of normal SMB file transfers. This
2987includes doing file type and signature through the file processing as
2988well as setting a pointer for the "file_data" rule option. Note that
2989the "file_depth" option only applies to the maximum amount of file
2990data for which it will set the pointer for the "file_data" rule
2991option. For file type and signature it will use the value configured
2992for the file API. If "only" is specified, the inspector will only do
2993SMB file inspection, i.e. it will not do any DCE/RPC tracking or
2994inspection. If "on" is specified with no arguments, the default file
2995depth is 16384 bytes. An argument of -1 to "file-depth" disables
2996setting the pointer for "file_data", effectively disabling SMB file
2997inspection in rules. An argument of 0 to "file_depth" means
2998unlimited. Default is "off", i.e. no SMB file inspection is done in
2999the inspector.
3000
30015.6.6. TCP
3002
3003dce_tcp inspector supports defragmentation, reassembling, and policy
3004that is similar to SMB.
3005
30065.6.7. UDP
3007
3008dce_udp is a very simple inspector that only supports defragmentation
3009
30105.6.8. Rule Options
3011
3012New rule options are supported by enabling the dcerpc2 inspectors:
3013
3014  * dce_iface
3015  * dce_opnum
3016  * dce_stub_data
3017
3018New modifiers to existing byte_test and byte_jump rule options:
3019
3020  * byte_test: dce
3021  * byte_jump: dce
3022
30235.6.8.1. dce_iface
3024
3025For DCE/RPC based rules it has been necessary to set flow-bits based
3026on a client bind to a service to avoid false positives. It is
3027necessary for a client to bind to a service before being able to make
3028a call to it. When a client sends a bind request to the server, it
3029can, however, specify one or more service interfaces to bind to. Each
3030interface is represented by a UUID. Each interface UUID is paired
3031with a unique index (or context id) that future requests can use to
3032reference the service that the client is making a call to. The server
3033will respond with the interface UUIDs it accepts as valid and will
3034allow the client to make requests to those services. When a client
3035makes a request, it will specify the context id so the server knows
3036what service the client is making a request to. Instead of using
3037flow-bits, a rule can simply ask the inspector, using this rule
3038option, whether or not the client has bound to a specific interface
3039UUID and whether or not this client request is making a request to
3040it. This can eliminate false positives where more than one service is
3041bound to successfully since the inspector can correlate the bind UUID
3042to the context id used in the request. A DCE/RPC request can specify
3043whether numbers are represented as big endian or little endian. The
3044representation of the interface UUID is different depending on the
3045endianness specified in the DCE/RPC previously requiring two rules -
3046one for big endian and one for little endian. The inspector
3047eliminates the need for two rules by normalizing the UUID. An
3048interface contains a version. Some versions of an interface may not
3049be vulnerable to a certain exploit. Also, a DCE/RPC request can be
3050broken up into 1 or more fragments. Flags (and a field in the
3051connectionless header) are set in the DCE/RPC header to indicate
3052whether the fragment is the first, a middle or the last fragment.
3053Many checks for data in the DCE/RPC request are only relevant if the
3054DCE/RPC request is a first fragment (or full request), since
3055subsequent fragments will contain data deeper into the DCE/RPC
3056request. A rule which is looking for data, say 5 bytes into the
3057request (maybe it’s a length field), will be looking at the wrong
3058data on a fragment other than the first, since the beginning of
3059subsequent fragments are already offset some length from the
3060beginning of the request. This can be a source of false positives in
3061fragmented DCE/RPC traffic. By default it is reasonable to only
3062evaluate if the request is a first fragment (or full request).
3063However, if the "any_frag" option is used to specify evaluating on
3064all fragments.
3065
3066Examples:
3067
3068dce_iface: 4b324fc8-1670-01d3-1278-5a47bf6ee188;
3069dce_iface: 4b324fc8-1670-01d3-1278-5a47bf6ee188,<2;
3070dce_iface: 4b324fc8-1670-01d3-1278-5a47bf6ee188,any_frag;
3071dce_iface: 4b324fc8-1670-01d3-1278-5a47bf6ee188,=1,any_frag;
3072
3073This option is used to specify an interface UUID. Optional arguments
3074are an interface version and operator to specify that the version be
3075less than (<), greater than (>), equal to (=) or not equal to (!) the
3076version specified. Also, by default the rule will only be evaluated
3077for a first fragment (or full request, i.e. not a fragment) since
3078most rules are written to start at the beginning of a request. The
3079"any_frag" argument says to evaluate for middle and last fragments as
3080well. This option requires tracking client Bind and Alter Context
3081requests as well as server Bind Ack and Alter Context responses for
3082connection-oriented DCE/RPC in the inspector. For each Bind and Alter
3083Context request, the client specifies a list of interface UUIDs along
3084with a handle (or context id) for each interface UUID that will be
3085used during the DCE/RPC session to reference the interface. The
3086server response indicates which interfaces it will allow the client
3087to make requests to - it either accepts or rejects the client’s wish
3088to bind to a certain interface. This tracking is required so that
3089when a request is processed, the context id used in the request can
3090be correlated with the interface UUID it is a handle for.
3091
3092hexlong and hexshort will be specified and interpreted to be in big
3093endian order (this is usually the default way an interface UUID will
3094be seen and represented). As an example, the following Messenger
3095interface UUID as taken off the wire from a little endian Bind
3096request:
3097
3098|f8 91 7b 5a 00 ff d0 11 a9 b2 00 c0 4f b6 e6 fc|
3099
3100must be written as:
3101
31025a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc
3103
3104The same UUID taken off the wire from a big endian Bind request:
3105
3106|5a 7b 91 f8 ff 00 11 d0 a9 b2 00 c0 4f b6 e6 fc|
3107
3108must be written the same way:
3109
31105a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc
3111
3112This option matches if the specified interface UUID matches the
3113interface UUID (as referred to by the context id) of the DCE/RPC
3114request and if supplied, the version operation is true. This option
3115will not match if the fragment is not a first fragment (or full
3116request) unless the "any_frag" option is supplied in which case only
3117the interface UUID and version need match. Note that a defragmented
3118DCE/RPC request will be considered a full request.
3119
3120Using this rule option will automatically insert fast pattern
3121contents into the fast pattern matcher. For UDP rules, the interface
3122UUID, in both big and little endian format will be inserted into the
3123fast pattern matcher. For TCP rules, (1) if the rule option
3124"flow:to_server|from_client" is used, |05 00 00| will be inserted
3125into the fast pattern matcher, (2) if the rule option
3126"flow:from_server|to_client" is used, |05 00 02| will be inserted
3127into the fast pattern matcher and (3) if the flow isn’t known, |05 00
3128| will be inserted into the fast pattern matcher. Note that if the
3129rule already has content rule options in it, the best (meaning
3130longest) pattern will be used. If a content in the rule uses the
3131fast_pattern rule option, it will unequivocally be used over the
3132above mentioned patterns.
3133
31345.6.8.2. dce_opnum
3135
3136The opnum represents a specific function call to an interface. After
3137is has been determined that a client has bound to a specific
3138interface and is making a request to it (see above - dce_iface)
3139usually we want to know what function call it is making to that
3140service. It is likely that an exploit lies in the particular DCE/RPC
3141function call.
3142
3143Examples:
3144
3145dce_opnum: 15;
3146dce_opnum: 15-18;
3147dce_opnum: 15,18-20;
3148dce_opnum: 15,17,20-22;
3149
3150This option is used to specify an opnum (or operation number), opnum
3151range or list containing either or both opnum and/or opnum-range. The
3152opnum of a DCE/RPC request will be matched against the opnums
3153specified with this option. This option matches if any one of the
3154opnums specified match the opnum of the DCE/RPC request.
3155
31565.6.8.3. dce_stub_data
3157
3158Since most DCE/RPC based rules had to do protocol decoding only to
3159get to the DCE/RPC stub data, i.e. the remote procedure call or
3160function call data, this option will alleviate this need and place
3161the cursor at the beginning of the DCE/RPC stub data. This reduces
3162the number of rule option checks and the complexity of the rule.
3163
3164This option takes no arguments.
3165
3166Example:
3167
3168dce_stub_data;
3169
3170This option is used to place the cursor (used to walk the packet
3171payload in rules processing) at the beginning of the DCE/RPC stub
3172data, regardless of preceding rule options. There are no arguments to
3173this option. This option matches if there is DCE/RPC stub data.
3174
3175The cursor is moved to the beginning of the stub data. All ensuing
3176rule options will be considered "sticky" to this buffer. The first
3177rule option following dce_stub_data should use absolute location
3178modifiers if it is position-dependent. Subsequent rule options should
3179use a relative modifier if they are meant to be relative to a
3180previous rule option match in the stub data buffer. Any rule option
3181that does not specify a relative modifier will be evaluated from the
3182start of the stub data buffer. To leave the stub data buffer and
3183return to the main payload buffer, use the "pkt_data" rule option.
3184
31855.6.8.4. byte_test and byte_jump
3186
3187A DCE/RPC request can specify whether numbers are represented in big
3188or little endian. These rule options will take as a new argument
3189"dce" and will work basically the same as the normal byte_test/
3190byte_jump, but since the DCE/RPC inspector will know the endianness
3191of the request, it will be able to do the correct conversion.
3192
3193Examples:
3194
3195byte_test: 4,>,35000,0,relative,dce;
3196byte_test: 2,!=,2280,-10,relative,dce;
3197
3198When using the "dce" argument to a byte_test, the following normal
3199byte_test arguments will not be allowed: "big", "little", "string",
3200"hex", "dec" and "oct".
3201
3202Examples:
3203
3204byte_jump:4,-4,relative,align,multiplier 2,post_offset -4,dce;
3205
3206When using the dce argument to a byte_jump, the following normal
3207byte_jump arguments will not be allowed: "big", "little", "string",
3208"hex", "dec", "oct" and "from_beginning"
3209
3210
32115.7. File Processing
3212
3213--------------
3214
3215With the volume of malware transferred through network increasing,
3216network file inspection becomes more and more important. This feature
3217will provide file type identification, file signature creation, and
3218file capture capabilities to help users deal with those challenges.
3219
32205.7.1. Overview
3221
3222There are two parts of file services: file APIs and file policy. File
3223APIs provides all the file inspection functionalities, such as file
3224type identification, file signature calculation, and file capture.
3225File policy provides users ability to control file services, such as
3226enable/disable/configure file type identification, file signature, or
3227file capture.
3228
3229In addition to all capabilities from Snort 2, we support customized
3230file policy along with file event log.
3231
3232  * Supported protocols: HTTP, SMTP, IMAP, POP3, FTP, and SMB.
3233  * Supported file signature calculation: SHA256
3234
32355.7.2. Quick Guide
3236
3237A very simple configuration has been included in lua/snort.lua file.
3238A typical file configuration looks like this:
3239
3240dofile('magic.lua')
3241
3242my_file_policy =
3243{
3244    {  when = { file_type_id = 0 }, use = { verdict = 'log', enable_file_signature = true, enable_file_capture = true } }
3245    {  when = { file_type_id = 22 }, use = { verdict = 'log', enable_file_signature = true } },
3246    {  when = { sha256 = "F74DC976BC8387E7D4FC0716A069017A0C7ED13F309A523CC41A8739CCB7D4B6" }, use = { verdict = 'block'} },
3247}
3248
3249file_id =
3250{
3251    enable_type = true,
3252    enable_signature = true,
3253    enable_capture = true,
3254    file_rules = magics,
3255    trace_type = true,
3256    trace_signature = true,
3257    trace_stream = true,
3258    file_policy = my_file_policy,
3259 }
3260
3261file_log =
3262{
3263    log_pkt_time = true,
3264    log_sys_time = false,
3265}
3266
3267There are 3 steps to enable file processing:
3268
3269  * First, you need to include the file magic rules.
3270  * Then, define the file policy and configure the inspector
3271  * At last, enable file_log to get detailed information about file
3272    event
3273
32745.7.3. Pre-packaged File Magic Rules
3275
3276A set of file magic rules is packaged with Snort. They can be located
3277at "lua/file_magic.lua". To use this feature, it is recommended that
3278these pre-packaged rules are used; doing so requires that you include
3279the file in your Snort configuration as such (already in snort.lua):
3280
3281dofile('magic.lua')
3282
3283Example:
3284
3285{ type = "GIF", id = 62, category = "Graphics", rev = 1,
3286  magic = { { content = "| 47 49 46 38 37 61 |",offset = 0 } } },
3287
3288{ type = "GIF", id = 63, category = "Graphics", rev = 1,
3289  magic = { { content = "| 47 49 46 38 39 61 |",offset = 0 } } },
3290
3291The previous two rules define GIF format, because two file magics are
3292different. File magics are specified by content and offset, which
3293look at content at particular file offset to identify the file type.
3294In this case, two magics look at the beginning of the file. You can
3295use character if it is printable or hex value in between "|".
3296
32975.7.4. File Policy
3298
3299You can enabled file type, file signature, or file capture by
3300configuring file_id. In addition, you can enable trace to see file
3301stream data, file type, and file signature information.
3302
3303Most importantly, you can configure a file policy that can block/
3304alert some file type or an individual file based on SHA. This allows
3305you build a file blacklist or whitelist.
3306
3307Example:
3308
3309file_policy =
3310{
3311    {  when = { file_type_id = 22 }, use = { verdict = 'log', enable_file_signature = true } },
3312    {  when = { sha256 = "F74DC976BC8387E7D4FC0716A069017A0C7ED13F309A523CC41A8739CCB7D4B6" }, use = { verdict = 'block'} },
3313    {  when = { file_type_id = 0 }, use = { verdict = 'log', enable_file_signature = true, enable_file_capture = true } }
3314}
3315
3316In this example, it enables this policy:
3317
3318  * For PDF files, they will be logged with signatures.
3319  * For the file matching this SHA, it will be blocked
3320  * For all file types identified, they will be logged with
3321    signature, and also captured onto log folder.
3322
33235.7.5. File Capture
3324
3325File can be captured and stored to log folder. We use SHA as file
3326name instead of actual file name to avoid conflicts. You can capture
3327either all files, some file type, or a particular file based on SHA.
3328
3329You can enable file capture through this config:
3330
3331enable_capture = true,
3332
3333or enable it for some file or file type in your file policy:
3334
3335{  when = { file_type_id = 22 }, use = { verdict = 'log', enable_file_capture = true } },
3336
3337The above rule will enable PDF file capture.
3338
33395.7.6. File Events
3340
3341File inspect preprocessor also works as a dynamic output plugin for
3342file events. It logs basic information about file. The log file is in
3343the same folder as other log files with name starting with
3344"file.log".
3345
3346Example:
3347
3348file_log = { log_pkt_time = true, log_sys_time = false }
3349
3350All file events will be logged in packet time, system time is not
3351logged.
3352
3353File event example:
3354
335508/14-19:14:19.100891  10.22.75.72:33734 -> 10.22.75.36:80,
3356[Name: "malware.exe"] [Verdict: Block] [Type: MSEXE]
3357[SHA: 6F26E721FDB1AAFD29B41BCF90196DEE3A5412550615A856DAE8E3634BCE9F7A]
3358[Size: 1039328]
3359
3360
33615.8. High Availability
3362
3363--------------
3364
3365High Availability includes the HA flow synchronization and the
3366SideChannel messaging subsystems.
3367
33685.8.1. HA
3369
3370HighAvailability (or HA) is a Snort module that provides state
3371coherency between two partner snort instances. It uses SideChannel
3372for messaging.
3373
3374There can be multiple types of HA within Snort and Snort plugins. HA
3375implements an extensible architecture to enable plugins to subscribe
3376to the base flow HA messaging. These plugins can then include their
3377own messages along with the flow cache HA messages.
3378
3379HA produces and consumes two type of messages:
3380
3381  * Update - Update flow status. Plugins may add their own data to
3382    the messages
3383  * Delete - A flow has been removed from the cache
3384
3385The HA module is configured with these items:
3386
3387high_availability =
3388{
3389    ports = "1",
3390    enable = true,
3391    min_age = 0,
3392    min_sync = 0
3393}
3394
3395The ports item maps to the SideChannel port to use for the HA
3396messaging.
3397
3398The enabled item controls the overall HA operation.
3399
3400The items min_age and min_sync are used in the stream HA logic.
3401min_age is the number of milliseconds that a flow must exist in the
3402flow cache before sending HA messages to the partner. min_sync is the
3403minimum time between HA status updates. HA messages for a particular
3404flow will not be sent faster than min_sync. Both are expressed as a
3405number of milliseconds.
3406
3407HA messages are composed of the base stream information plus any
3408content from additional modules. Modules subscribe HA in order to add
3409message content. The stream HA content is always present in the
3410messages while the ancillary module content is only present when
3411requested via a status change request.
3412
34135.8.2. Connector
3414
3415Connectors are a set of modules that are used to exchange
3416message-oriented data among Snort threads and the external world. A
3417typical use-case is HA (High Availability) message exchange.
3418Connectors serve to decouple the message transport from the message
3419creation/consumption. Connectors expose a common API for several
3420forms of message transport.
3421
3422Connectors are a Snort plugin type.
3423
34245.8.2.1. Connector (parent plugin class)
3425
3426Connectors may either be a simplex channel and perform unidirectional
3427communications. Or may be duplex and perform bidirectional
3428communications. The TcpConnector is duplex while the FileConnector is
3429simplex.
3430
3431All subtypes of Connector have a direction configuration element and
3432a connector element. The connector string is the key used to identify
3433the element for sidechannel configuration. The direction element may
3434have a default value, for instance TcpConnector’s are duplex.
3435
3436There are currently two implementations of Connectors:
3437
3438  * TcpConnector - Exchange messages over a tcp channel.
3439  * FileConnector - Write messages to files and read messages from
3440    files.
3441
34425.8.2.2. TcpConnector
3443
3444TcpConnector is a subclass of Connector and implements a DUPLEX type
3445Connector, able to send and receive messages over a tcp session.
3446
3447TcpConnector adds a few session setup configuration elements:
3448
3449  * setup = call or answer - call is used to have TcpConnector
3450    initiate the connection. answer is used to have TcpConnector
3451    accept incoming connections.
3452  * address = <addr> - used for call setup to specify the partner
3453  * base_port = port - used to contruct the actual port number for
3454    call and answer modes. Actual port used is (base_port +
3455    instance_id).
3456
3457An example segment of TcpConnector configuration:
3458
3459tcp_connector =
3460{
3461    {
3462        connector = 'tcp_1',
3463        address = '127.0.0.1',
3464        setup = 'call',
3465        base_port = 11000
3466    },
3467}
3468
34695.8.2.3. FileConnector
3470
3471FileConnector implements a Connector that can either read from files
3472or write to files. FileConnector’s are simplex and must be configured
3473to be CONN_TRANSMIT or CONN_RECEIVE.
3474
3475FileConnector configuration adds two additional element:
3476
3477  * name = string - used as part of the message file name
3478  * format = text or binary - FileConnector supports two file types
3479
3480The configured name string is used to construct the actual names as
3481in:
3482
3483  * file_connector_NAME_transmit and file_connector_NAME_receive
3484
3485All messages for one Snort invocation are read and written to one
3486file.
3487
3488In the case of a receive FileConnector, all messages are read from
3489the file prior to the start of packet processing. This allows the
3490messages to establish state information for all processed packets.
3491
3492Connectors are used solely by SideChannel
3493
3494An example segment of FileConnector configuration:
3495
3496file_connector =
3497{
3498    {
3499        connector = 'file_tx_1',
3500        direction = 'transmit',
3501        format = 'text',
3502        name = 'HA'
3503    },
3504    {
3505        connector = 'file_rx_1',
3506        direction = 'receive',
3507        format = 'text',
3508        name = 'HA'
3509    },
3510}
3511
35125.8.3. Side Channel
3513
3514SideChannel is a Snort module that uses Connectors to implement a
3515messaging infrastructure that is used to communicate between Snort
3516threads and the outside world.
3517
3518SideChannel adds functionality onto the Connector as:
3519
3520  * message multiplexing/demultiplexing - An additional protocol
3521    layer is added to the messages. This port number is used to
3522    direct message to/from various SideClass instancs.
3523  * application receive processing - handler for received messages on
3524    a specific port.
3525
3526SideChannel’s are always implement a duplex (bidirectional) messaging
3527model and can map to separate transmit and receive Connectors.
3528
3529The message handling model leverages the underlying Connector
3530handling. So please refer to the Connector documentation.
3531
3532SideChannel’s are instantiated by various applications. The
3533SideChannel port numbers are the configuration element used to map
3534SideChannel’s to applications.
3535
3536The SideChannel configuration mostly serves to map a port number to a
3537Connector or set of connectors. Each port mapping can have at most
3538one transmit plus one receive connector or one duplex connector.
3539Multiple SideChannel’s may be configured and instantiated to support
3540multiple applications.
3541
3542An example SideChannel configuration along with the corresponding
3543Connector configuration:
3544
3545side_channel =
3546{
3547    {
3548        ports = '1',
3549        connectors =
3550        {
3551            {
3552                connector = 'file_rx_1',
3553            },
3554            {
3555                connector = 'file_tx_1',
3556            }
3557        },
3558    },
3559}
3560
3561file_connector =
3562{
3563    {
3564        connector = 'file_tx_1',
3565        direction = 'transmit',
3566        format = 'text',
3567        name = 'HA'
3568    },
3569    {
3570        connector = 'file_rx_1',
3571        direction = 'receive',
3572        format = 'text',
3573        name = 'HA'
3574    },
3575}
3576
3577
35785.9. FTP
3579
3580--------------
3581
3582Given an FTP command channel buffer, FTP will interpret the data,
3583identifying FTP commands and parameters, as well as FTP response
3584codes and messages. It will enforce correctness of the parameters,
3585determine when an FTP command connection is encrypted, and determine
3586when an FTP data channel is opened.
3587
35885.9.1. Configuring the inspector to block exploits and attacks
3589
35905.9.1.1. ftp_server configuration
3591
3592  * ftp_cmds
3593
3594This specifies additional FTP commands outside of those checked by
3595default within the inspector. The inspector may be configured to
3596generate an alert when it sees a command it does not recognize.
3597
3598Aside from the default commands recognized, it may be necessary to
3599allow the use of the "X" commands, specified in RFC 775. To do so,
3600use the following ftp_cmds option. Since these are rarely used by FTP
3601client implementations, they are not included in the defaults.
3602
3603ftp_cmds = [[ XPWD XCWD XCUP XMKD XRMD ]]
3604
3605  * def_max_param_len
3606
3607This specifies the default maximum parameter length for all commands
3608in bytes. If the parameter for an FTP command exceeds that length,
3609and the inspector is configured to do so, an alert will be generated.
3610This is used to check for buffer overflow exploits within FTP
3611servers.
3612
3613  * cmd_validity
3614
3615This specifies the valid format and length for parameters of a given
3616command.
3617
3618  * cmd_validity[].len
3619
3620This specifies the maximum parameter length for the specified command
3621in bytes, overriding the default. If the parameter for that FTP
3622command exceeds that length, and the inspector is configured to do
3623so, an alert will be generated. It can be used to restrict specific
3624commands to small parameter values. For example the USER
3625command — usernames may be no longer than 16 bytes, so the
3626appropriate configuration would be:
3627
3628cmd_validity =
3629{
3630    {
3631        command = 'USER',
3632        length = 16,
3633    }
3634}
3635
3636  * cmd_validity[].format
3637
3638format is as follows:
3639
3640int                 Param must be an integer
3641number              Param must be an integer between 1 and 255
3642char <chars>        Param must be a single char, and one of <chars>
3643date <datefmt>      Param follows format specified where
3644                    # = Number, C=Char, []=optional, |=OR, {}=choice,
3645                    anything else=literal (i.e., .+- )
3646string              Param is string (effectively unrestricted)
3647host_port           Param must a host port specifier, per RFC 959.
3648long_host_port      Parameter must be a long host port specified, per RFC 1639
3649extended_host_port  Parameter must be an extended host port specified, per RFC 2428
3650
3651Examples of the cmd_validity option are shown below. These examples
3652are the default checks (per RFC 959 and others) performed by the
3653inspector.
3654
3655cmd_validity =
3656{
3657    {
3658        command = 'CWD',
3659        length = 200,
3660    },
3661    {
3662        command = 'MODE',
3663        format = '< char SBC >',
3664    },
3665    {
3666        command = 'STRU',
3667        format = '< char FRP >',
3668    },
3669    {
3670        command = 'ALLO',
3671        format = '< int [ char R int ] >',
3672    },
3673    {
3674        command = 'TYPE',
3675        format = [[ < { char AE [ char NTC ] | char I | char L [ number ]
3676            } > ]],
3677    },
3678    {
3679        command = 'PORT',
3680        format = '< host_port >',
3681    },
3682}
3683
3684A cmd_validity entry in the configuration can be used to override
3685these defaults and/or add a check for other commands. A few examples
3686follow.
3687
3688This allows additional modes, including mode Z which allows for
3689zip-style compression:
3690
3691cmd_validity =
3692{
3693    {
3694        command = 'MODE',
3695        format = '< char ASBCZ >',
3696    },
3697}
3698
3699Allow for a date in the MDTM command:
3700
3701cmd_validity =
3702{
3703    {
3704        command = 'MDTM',
3705        format = '< [ date nnnnnnnnnnnnnn[.n[n[n]]] ] string >',
3706    },
3707}
3708
3709MDTM is an odd case that is worth discussing…
3710
3711While not part of an established standard, certain FTP servers accept
3712MDTM commands that set the modification time on a file. The most
3713common among servers that do, accept a format using YYYYMMDDHHmmss
3714[.uuu]. Some others accept a format using YYYYMMDDHHmmss[+|-]TZ
3715format. The example above is for the first case.
3716
3717To check validity for a server that uses the TZ format, use the
3718following:
3719
3720cmd_validity =
3721{
3722    {
3723        command = 'MDTM',
3724        format = '< [ date nnnnnnnnnnnnnn[{+|-}n[n]] ] string >',
3725    },
3726}
3727
3728  * chk_str_fmt
3729
3730This causes the inspector to check for string format attacks on the
3731specified commands.
3732
3733  * telnet_cmds
3734
3735Detect and alert when telnet cmds are seen on the FTP command
3736channel.
3737
3738  * ignore_telnet_erase_cmds
3739
3740This option allows Snort to ignore telnet escape sequences for erase
3741character (TNC EAC) and erase line (TNC EAL) when normalizing FTP
3742command channel. Some FTP servers do not process those telnet escape
3743sequences.
3744
3745  * ignore_data_chan
3746
3747When set to true, causes the FTP inspector to force the rest of snort
3748to ignore the FTP data channel connections. NO INSPECTION other than
3749state (inspector AND rules) will be performed on that data channel.
3750It can be turned on to improve performance — especially with respect
3751to large file transfers from a trusted source — by ignoring traffic.
3752If your rule set includes virus-type rules, it is recommended that
3753this option not be used.
3754
37555.9.1.2. ftp_client configuration
3756
3757  * max_resp_len
3758
3759This specifies the maximum length for all response messages in bytes.
3760If the message for an FTP response (everything after the 3 digit
3761code) exceeds that length, and the inspector is configured to do so,
3762an alert will be generated. This is used to check for buffer overflow
3763exploits within FTP clients.
3764
3765  * telnet_cmds
3766
3767Detect and alert when telnet cmds are seen on the FTP command
3768channel.
3769
3770  * ignore_telnet_erase_cmds
3771
3772This option allows Snort to ignore telnet escape sequences for erase
3773character (TNC EAC) and erase line (TNC EAL) when normalizing FTP
3774command channel. Some FTP clients do not process those telnet escape
3775sequences.
3776
37775.9.1.3. ftp_data
3778
3779In order to enable file inspection for ftp, the following should be
3780added to the configuration:
3781
3782ftp_data = {}
3783
3784
37855.10. HTTP Inspector
3786
3787--------------
3788
3789One of the major undertakings for Snort 3 is developing a completely
3790new HTTP inspector.
3791
37925.10.1. Overview
3793
3794You can configure it by adding:
3795
3796http_inspect = {}
3797
3798to your snort.lua configuration file. Or you can read about it in the
3799source code under src/service_inspectors/http_inspect.
3800
3801So why a new HTTP inspector?
3802
3803For starters it is object-oriented. That’s good for us because we
3804maintain this software. But it should also be really nice for
3805open-source developers. You can make meaningful changes and additions
3806to HTTP processing without having to understand the whole thing. In
3807fact much of the new HTTP inspector’s knowledge of HTTP is
3808centralized in a series of tables where it can be easily reviewed and
3809modified. Many significant changes can be made just by updating these
3810tables.
3811
3812http_inspect is the first inspector written specifically for the new
3813Snort 3 architecture. This provides access to one of the very best
3814features of Snort 3: purely PDU-based inspection. The classic
3815preprocessor processes HTTP messages, but even while doing so it is
3816constantly aware of IP packets and how they divide up the TCP data
3817stream. The same HTTP message might be processed differently
3818depending on how the sender (bad guy) divided it up into IP packets.
3819
3820http_inspect is free of this burden and can focus exclusively on
3821HTTP. This makes it much simpler, easier to test, and less prone to
3822false positives. It also greatly reduces the opportunity for
3823adversaries to probe the inspector for weak spots by adjusting packet
3824boundaries to disguise bad behavior.
3825
3826Dealing solely with HTTP messages also opens the door for developing
3827major new features. The http_inspect design supports true stateful
3828processing. Want to ask questions that involve both the client
3829request and the server response? Or different requests in the same
3830session? These things are possible.
3831
3832http_inspect is taking a very different approach to HTTP header
3833fields. The classic preprocessor divides all the HTTP headers
3834following the start line into cookies and everything else. It
3835normalizes the two pieces using a generic process and puts them in
3836buffers that one can write rules against. There is some limited
3837support for examining individual headers within the inspector but it
3838is very specific.
3839
3840The new concept is that every header should be normalized in an
3841appropriate and specific way and individually made available for the
3842user to write rules against it. If for example a header is supposed
3843to be a date then normalization means put that date in a standard
3844format.
3845
38465.10.2. Legacy and Enhanced Normalizers
3847
3848Currently, there are Legacy and Enhanced Normalizers for JavaScript
3849normalization. Both normalizers are independent and can be configured
3850separately. The Legacy normalizer should be considered deprecated.
3851The Enhanced Normalizer is encouraged to use for JavaScript
3852normalization in the first place as we continue improving
3853functionality and quality.
3854
38555.10.2.1. Legacy Normalizer
3856
3857The Legacy Normalizer can normalize obfuscated data within the
3858JavaScript functions such as unescape, String.fromCharCode,
3859decodeURI, and decodeURIComponent. It also replaces consecutive
3860whitespaces with a single space and normalizes the plus by
3861concatenating the strings. For more information on how to enable
3862Legacy Normalizer, check the http_inspect.normalize_javascript
3863option. Legacy Normalizer is deprecated preferably to use Enhanced
3864Normalizer. After supporting backward compatibility in the Enhanced
3865Normalizer, Legacy Normalizer will be removed.
3866
38675.10.2.2. Enhanced Normalizer
3868
3869Having ips option js_data in the rules automatically enables Enhanced
3870Normalizer. The Enhanced Normalizer can normalize inline/external
3871scripts. It supports scripts over multiple PDUs. It is a stateful
3872JavaScript whitespace and identifiers normalizer. All JavaScript
3873identifier names, except those from the ignore list, will be
3874substituted with unified names in the following format: var_0000 →
3875var_ffff. Moreover, Normalizer validates the syntax concerning
3876ECMA-262 Standard, including scope tracking and restrictions for
3877script elements. For more information on how additionally configure
3878Enhanced Normalizer check with the following configuration options:
3879js_norm_bytes_depth, js_norm_identifier_depth, js_norm_max_tmpl_nest,
3880js_norm_max_bracket_depth, js_norm_max_scope_depth,
3881js_norm_ident_ignore. Eventually Enhanced Normalizer will completely
3882replace Legacy Normalizer.
3883
38845.10.3. Configuration
3885
3886Configuration can be as simple as adding:
3887
3888http_inspect = {}
3889
3890to your snort.lua file. The default configuration provides a thorough
3891inspection and may be all that you need. But there are some options
3892that provide extra features, tweak how things are done, or conserve
3893resources by doing less.
3894
38955.10.3.1. request_depth and response_depth
3896
3897These replace the flow depth parameters used by the old HTTP
3898inspector but they work differently.
3899
3900The default is to inspect the entire HTTP message body. That’s a very
3901sound approach but if your HTTP traffic includes many very large
3902files such as videos the load on Snort can become burdensome. Setting
3903the request_depth and response_depth parameters will limit the amount
3904of body data that is sent to the rule engine. For example:
3905
3906request_depth = 10000,
3907response_depth = 80000,
3908
3909would examine only the first 10000 bytes of POST, PUT, and other
3910message bodies sent by the client. Responses from the server would be
3911limited to 80000 bytes.
3912
3913These limits apply only to the message bodies. HTTP headers are
3914always completely inspected.
3915
3916If you want to only inspect headers and no body, set the depth to 0.
3917If you want to inspect the entire body set the depth to -1 or simply
3918omit the depth parameter entirely because that is the default.
3919
3920These limits have no effect on how much data is forwarded to file
3921processing.
3922
39235.10.3.2. script_detection
3924
3925Script detection is a feature that enables Snort to more quickly
3926detect and block response messages containing malicious JavaScript.
3927When http_inspect detects the end of a script it immediately forwards
3928the available part of the message body for early detection. This
3929enables malicious Javascripts to be detected more quickly but
3930consumes somewhat more of the sensor’s resources.
3931
3932This feature is off by default. script_detection = true will activate
3933it.
3934
39355.10.3.3. gzip
3936
3937http_inspect by default decompresses deflate and gzip message bodies
3938before inspecting them. This feature can be turned off by unzip =
3939false. Turning off decompression provides a substantial performance
3940improvement but at a very high price. It is unlikely that any
3941meaningful inspection of message bodies will be possible. Effectively
3942HTTP processing would be limited to the headers.
3943
39445.10.3.4. normalize_utf
3945
3946http_inspect will decode utf-8, utf-7, utf-16le, utf-16be, utf-32le,
3947and utf-32be in response message bodies based on the Content-Type
3948header. This feature is on by default: normalize_utf = false will
3949deactivate it.
3950
39515.10.3.5. decompress_pdf
3952
3953decompress_pdf = true will enable decompression of compressed
3954portions of PDF files encountered in a response body. http_inspect
3955will examine the response body for PDF files that are then parsed to
3956locate PDF streams with a single /FlateDecode filter. The compressed
3957content is decompressed and made available through the file data rule
3958option.
3959
39605.10.3.6. decompress_swf
3961
3962decompress_swf = true will enable decompression of compressed SWF
3963(Adobe Flash content) files encountered in a response body. The
3964available decompression modes are ’deflate’ and ’lzma’. http_inspect
3965will search for the file signatures CWS for Deflate/ZLIB and ZWS for
3966LZMA. The compressed content is decompressed and made available
3967through the file data rule option. The compressed SWF file signature
3968is converted to FWS to indicate an uncompressed file.
3969
39705.10.3.7. decompress_vba
3971
3972decompress_vba = true will enable decompression of RLE (Run Length
3973Encoding) compressed vba (Visual Basic for Applications) macro data
3974of MS Office files. The MS office files are PKZIP compressed which
3975are parsed to locate the OLE (Object Linking and Embedding) file
3976embedded with the files containing RLE compressed vba macro data. The
3977decompressed vba macro data is then made available through the
3978vba_data ips rule option.
3979
39805.10.3.8. normalize_javascript
3981
3982normalize_javascript = true will enable legacy normalizer of
3983JavaScript within the HTTP response body. http_inspect looks for
3984JavaScript by searching for the <script> tag without a type.
3985Obfuscated data within the JavaScript functions such as unescape,
3986String.fromCharCode, decodeURI, and decodeURIComponent are
3987normalized. The different encodings handled within the unescape,
3988decodeURI, or decodeURIComponent are %XX, %uXXXX, XX and uXXXXi.
3989http_inspect also replaces consecutive whitespaces with a single
3990space and normalizes the plus by concatenating the strings. Such
3991normalizations refer to basic JavaScript normalization.
3992
39935.10.3.9. js_norm_bytes_depth
3994
3995js_norm_bytes_depth = N {-1 : max53} will set a number of input
3996JavaScript bytes to normalize. When the depth is reached,
3997normalization will be stopped. It’s implemented per-script. By
3998default js_norm_bytes_depth = -1, will set unlimited depth. The
3999enhanced normalizer provides more precise whitespace normalization of
4000JavaScript, that removes all redundant whitespaces and line
4001terminators from the JavaScript syntax point of view (between
4002identifier and punctuator, between identifier and operator, etc.)
4003according to ECMAScript 5.1 standard. Additionally, it performs
4004normalization of JavaScript identifiers making a substitution of
4005unique names with unified names representation: var_0000:var_ffff.
4006The identifiers are variables and function names. The normalized data
4007is available through the js_data rule option.
4008
40095.10.3.10. js_norm_identifier_depth
4010
4011js_norm_identifier_depth = N {0 : 65536} will set a number of unique
4012JavaScript identifiers to normalize. When the depth is reached, a
4013built-in alert is generated. Every HTTP Response has its own
4014identifier substitution context. Thus, all scripts from the same
4015response will be normalized as if they are a single script.. By
4016default, the value is set to 65536, which is the max allowed number
4017of unique identifiers. The generated names are in the range from
4018var_0000 to var_ffff.
4019
40205.10.3.11. js_norm_max_tmpl_nest
4021
4022js_norm_max_tmpl_nest = N {0 : 255} (default 32) is an option of the
4023enhanced JavaScript normalizer that determines the deepest level of
4024nested template literals to be processed. Introduced in ES6, template
4025literals provide syntax to define a literal multiline string, which
4026can have arbitrary JavaScript substitutions, that will be evaluated
4027and inserted into the string. Such substitutions can be nested, and
4028require keeping track of every layer for proper normalization. This
4029option is present to limit the amount of memory dedicated to this
4030tracking.
4031
40325.10.3.12. js_norm_max_bracket_depth
4033
4034js_norm_max_bracket_depth = N {1 : 65535} (default 256) is an option
4035of the enhanced JavaScript normalizer that determines the deepest
4036level of nested bracket scope. The scope term includes code sections
4037("{}"), parentheses("()") and brackets("[]"). This option is present
4038to limit the amount of memory dedicated to this tracking.
4039
40405.10.3.13. js_norm_max_scope_depth
4041
4042js_norm_max_scope_depth = N {1 : 65535} (default 256) is an option of
4043the enhanced JavaScript normalizer that determines the deepest level
4044of nested scope. The scope term includes any type of JavaScript
4045program scope such as the global one, function scope, if block,
4046loops, code block, object scope, etc. This option is present to limit
4047the amount of memory dedicated to this tracking.
4048
40495.10.3.14. js_norm_ident_ignore
4050
4051js_norm_ident_ignore = {<a list of ignored identifiers>}. The default
4052list is present in "snort_defaults.lua".
4053
4054The Normalizer does not substitute ignored identifiers, keeping their
4055name unchanged. Additionally, the Normalizer tracks expressions with
4056ignored identifiers, so the subsequent identifiers are not
4057substituted in the chain of dots, bracket accessors and function
4058calls. For example:
4059
4060console.log("bar")
4061document.getElementById("id").text
4062eval("script")
4063foo["bar"]
4064
4065The list must contain object and function names only. For example:
4066
4067http_inspect.js_norm_ident_ignore = { 'console', 'document', 'eval', 'foo' }
4068
40695.10.3.15. xff_headers
4070
4071This configuration supports defining custom x-forwarded-for type
4072headers. In a multi-vendor world, it is quite possible that the
4073header name carrying the original client IP could be vendor-specific.
4074This is due to the absence of standardization which would otherwise
4075standardize the header name. In such a scenario, this configuration
4076provides a way with which such headers can be introduced to HI. The
4077default value of this configuration is "x-forwarded-for
4078true-client-ip". The default definition introduces the two commonly
4079known headers and is preferred in the same order by the inspector as
4080they are defined, e.g "x-forwarded-for" will be preferred than
4081"true-client-ip" if both headers are present in the stream. The
4082header names should be delimited by a space.
4083
40845.10.3.16. maximum_host_length
4085
4086Setting maximum_host_length causes http_inspect to generate 119:25 if
4087the Host header value including optional white space exceeds the
4088specified length. In the abnormal case of multiple Host headers, the
4089total length of the combined values is used. The default value is -1,
4090meaning do not perform this check.
4091
40925.10.3.17. maximum_chunk_length
4093
4094http_inspect strictly limits individual chunks within a chunked
4095message body to be less than four gigabytes.
4096
4097A lower limit may be configured by setting maximum_chunk_length. Any
4098chunk longer than maximum chunk length will generate a 119:16 alert.
4099
41005.10.3.18. URI processing
4101
4102Normalization and inspection of the URI in the HTTP request message
4103is a key aspect of what http_inspect does. The best way to normalize
4104a URI is very dependent on the idiosyncrasies of the HTTP server
4105being accessed. The goal is to interpret the URI the same way as the
4106server will so that nothing the server will see can be hidden from
4107the rule engine.
4108
4109The default URI inspection parameters are oriented toward following
4110the HTTP RFCs—reading the URI the way the standards say it should be
4111read. Most servers deviate from this ideal in various ways that can
4112be exploited by an attacker. The options provide tools for the user
4113to cope with that.
4114
4115utf8 = true
4116plus_to_space = true
4117percent_u = false
4118utf8_bare_byte = false
4119iis_unicode = false
4120iis_double_decode = true
4121
4122The HTTP inspector normalizes percent encodings found in URIs. For
4123instance it will convert "%48%69%64%64%65%6e" to "Hidden". All the
4124options listed above control how this is done. The options listed as
4125true are fairly standard features that are decoded by default. You
4126don’t need to list them in snort.lua unless you want to turn them off
4127by setting them to false. But that is not recommended unless you know
4128what you are doing and have a definite reason.
4129
4130The other options are primarily for the protection of servers that
4131support irregular forms of decoding. These features are off by
4132default but you can activate them if you need to by setting them to
4133true in snort.lua.
4134
4135bad_characters = "0x25 0x7e 0x6b 0x80 0x81 0x82 0x83 0x84"
4136
4137That’s a list of 8-bit Ascii characters that you don’t want present
4138in any normalized URI after the percent decoding is done. For example
41390x25 is a hexadecimal number (37 in decimal) which stands for the %
4140character. The % character is legitimately used for encoding special
4141characters in a URI. But if there is still a percent after
4142normalization one might conclude that something is wrong. If you
4143choose to configure 0x25 as a bad character there will be an alert
4144whenever this happens.
4145
4146Another example is 0x00 which signifies the null character zero. Null
4147characters in a URI are generally wrong and very suspicious.
4148
4149The default is not to alert on any of the 256 8-bit Ascii characters.
4150Add this option to your configuration if you want to define some bad
4151characters.
4152
4153ignore_unreserved = "abc123"
4154
4155Percent encoding common characters such as letters and numbers that
4156have no special meaning in HTTP is suspicious. It’s legal but why
4157would you do it unless you have something to hide? http_inspect will
4158alert whenever an upper-case or lower-case letter, a digit, period,
4159underscore, tilde, or minus is percent-encoded. But if a legitimate
4160application in your environment encodes some of these characters for
4161some reason this allows you to create exemptions for those
4162characters.
4163
4164In the example, the lower-case letters a, b, and c and the digits 1,
41652, and 3 are exempted. These may be percent-encoded without
4166generating an alert.
4167
4168simplify_path = true
4169backslash_to_slash = true
4170
4171HTTP inspector simplifies directory paths in URIs by eliminating
4172extra traversals using ., .., and /.
4173
4174For example I can take a simple URI such as
4175
4176/very/easy/example
4177
4178and complicate it like this:
4179
4180/very/../very/././././easy//////detour/to/nowhere/../.././../example
4181
4182which may be very difficult to match with a detection rule.
4183simplify_path is on by default and you should not turn it off unless
4184you have no interest in URI paths.
4185
4186backslash_to_slash is a tweak to path simplification for servers that
4187allow directories to be separated by backslashes:
4188
4189/this/is/the/normal/way/to/write/a/path
4190
4191\this\is\the\other\way\to\write\a\path
4192
4193backslash_to_slash is turned on by default. It replaces all the
4194backslashes with slashes during normalization.
4195
41965.10.4. CONNECT processing
4197
4198The HTTP CONNECT method is used by a client to establish a tunnel to
4199a destination via an HTTP proxy server. If the connection is
4200successful the server will send a 2XX success response to the client,
4201then proceed to blindly forward traffic between the client and
4202destination. That traffic belongs to a new session between the client
4203and destination and may be of any protocol, so clearly the HTTP
4204inspector will be unable to continue processing traffic following the
4205CONNECT message as if it were just a continuation of the original
4206HTTP/1.1 session.
4207
4208Therefore upon receiving a success response to a CONNECT request, the
4209HTTP inspector will stop inspecting the session. The next packet will
4210return to the wizard, which will determine the appropriate inspector
4211to continue processing the flow. If the tunneled protocol happens to
4212be HTTP/1.1, the HTTP inspector will again start inspecting the flow,
4213but as an entirely new session.
4214
4215There is one scenario where the cutover to the wizard will not occur
4216despite a 2XX success response to a CONNECT request. HTTP allows for
4217pipelining, or sending multiple requests without waiting for a
4218response. If the HTTP inspector sees any further traffic from the
4219client after a CONNECT request before it has seen the CONNECT
4220response, it is unclear whether this traffic should be interpreted as
4221a pipelined HTTP request or tunnel traffic sent in anticipation of a
4222success response from the server. Due to this potential evasion
4223tactic, the HTTP inspector will not cut over to the wizard if it sees
4224any early client-to-server traffic, but will continue normal HTTP
4225processing of the flow regardless of the eventual server response.
4226
42275.10.5. Trace messages
4228
4229When a user needs help to sort out things going on inside HTTP
4230inspector, Trace module becomes handy.
4231
4232$ snort --help-module trace | grep http_inspect
4233
4234Messages for the enhanced JavaScript Normalizer follow (more
4235verbosity available in debug build):
4236
42375.10.5.1. trace.module.http_inspect.js_proc
4238
4239Messages from script processing flow and their verbosity levels:
4240
4241 1. Script opening tag location.
4242 2. Attributes of the detected script.
4243 3. Return codes from Normalizer.
4244
42455.10.5.2. trace.module.http_inspect.js_dump
4246
4247JavaScript data dump and verbosity levels:
4248
4249 1. js_data buffer as it is passed to detection.
4250 2. (no messages available currently)
4251 3. Current script as it is passed to Normalizer.
4252
42535.10.6. Detection rules
4254
4255http_inspect parses HTTP messages into their components and makes
4256them available to the detection engine through rule options. Let’s
4257start with an example:
4258
4259alert tcp any any -> any any ( msg:"URI example"; flow:established,
4260to_server; http_uri; content:"chocolate"; sid:1; rev:1; )
4261
4262This rule looks for chocolate in the URI portion of the request
4263message. Specifically, the http_uri rule option is the normalized URI
4264with all the percent encodings removed. It will find chocolate in
4265both:
4266
4267GET /chocolate/cake HTTP/1.1
4268
4269and
4270
4271GET /%63%68$6F%63%6F%6C%61%74%65/%63%61%6B%65 HTTP/1.1
4272
4273It is also possible to search the unnormalized URI
4274
4275alert tcp any any -> any any ( msg:"Raw URI example"; flow:established,
4276to_server; http_raw_uri; content:"chocolate"; sid:2; rev:1; )
4277
4278will match the first message but not the second. If you want to
4279detect someone who is trying to hide his request for chocolate then
4280
4281alert tcp any any -> any any ( msg:"Raw URI example"; flow:established,
4282to_server; http_raw_uri; content:"%63%68$6F%63%6F%6C%61%74%65";
4283sid:3; rev:1; )
4284
4285will do the trick.
4286
4287Let’s look at possible ways of writing a rule to match HTTP response
4288messages with the Content-Language header set to "da" (Danish). You
4289could write:
4290
4291alert tcp any any -> any any ( msg:"whole header search";
4292flow:established, to_client; http_header; content:
4293"Content-Language: da", nocase; sid:4; rev:1; )
4294
4295This rule leaves much to be desired. Modern headers are often
4296thousands of bytes and seem to get longer every year. Searching all
4297of the headers consumes a lot of resources. Furthermore this rule is
4298easily evaded:
4299
4300HTTP/1.1 ... Content-Language:  da ...
4301
4302the extra space before the "da" throws the rule off. Or how about:
4303
4304HTTP/1.1 ... Content-Language: xx,da ...
4305
4306By adding a made up second language the attacker has once again
4307thwarted the match.
4308
4309A better way to write this rule is:
4310
4311alert tcp any any -> any any ( msg:"individual header search";
4312flow:established, to_client; http_header: field content-language;
4313content:"da", nocase; sid:4; rev:2; )
4314
4315The field option improves performance by narrowing the search to the
4316Content-Language field of the header. Because it uses the header
4317parsing abilities of http_inspect to find the field of interest it
4318will not be thrown off by extra spaces or other languages in the
4319list.
4320
4321In addition to the headers there are rule options for virtually every
4322part of the HTTP message.
4323
43245.10.6.1. http_uri and http_raw_uri
4325
4326These provide the URI of the request message. The raw form is exactly
4327as it appeared in the message and the normalized form is determined
4328by the URI normalization options you selected. In addition to
4329searching the entire URI there are six components that can be
4330searched individually:
4331
4332alert tcp any any -> any any ( msg:"URI path"; flow:established,
4333to_server; http_uri: path; content:"chocolate"; sid:1; rev:2; )
4334
4335By specifying "path" the search is limited to the path portion of the
4336URI. Informally this is the part consisting of the directory path and
4337file name. Thus it will match:
4338
4339GET /chocolate/cake HTTP/1.1
4340
4341but not:
4342
4343GET /book/recipes?chocolate+cake HTTP/1.1
4344
4345The question mark ends the path and begins the query portion of the
4346URI. Informally the query is where parameter values are set and often
4347contains a search to be performed.
4348
4349The six components are:
4350
4351 1. path: directory and file
4352 2. query: user parameters
4353 3. fragment: part of the file requested, normally found only inside
4354    a browser and not transmitted over the network
4355 4. host: domain name of the server being addressed
4356 5. port: TCP port number being addressed
4357 6. scheme: normally "http" or "https" but others are possible such
4358    as "ftp"
4359
4360Here is an example with all six:
4361
4362GET https://www.samplehost.com:287/basic/example/of/path?with-query
4363#and-fragment HTTP/1.1\r\n
4364
4365The URI is everything between the first space and the last space.
4366"https" is the scheme, "www.samplehost.com" is the host, "287" is the
4367port, "/basic/example/of/path" is the path, "with-query" is the
4368query, and "and-fragment" is the fragment.
4369
4370http_uri represents the normalized uri, normalization of components
4371depends on uri type. If the uri is of type absolute (contains all six
4372components) or absolute path (contains path, query and fragment) then
4373the path and query components are normalized. In these cases,
4374http_uri represents the normalized path, query, and fragment (/path?
4375query#fragment). If the uri is of type authority (host and port), the
4376host is normalized and http_uri represents the normalized host with
4377the port number. In all other cases http_uri is the same as
4378http_raw_uri.
4379
4380Note: this section uses informal language to explain some things.
4381Nothing here is intended to conflict with the technical language of
4382the HTTP RFCs and the implementation follows the RFCs.
4383
43845.10.6.2. http_header and http_raw_header
4385
4386These cover all the header lines except the first one. You may
4387specify an individual header by name using the field option as shown
4388in this earlier example:
4389
4390alert tcp any any -> any any ( msg:"individual header search";
4391flow:established, to_client; http_header: field content-language;
4392content:"da", nocase; sid:4; rev:2; )
4393
4394This rule searches the value of the Content-Language header. Header
4395names are not case sensitive and may be written in the rule in any
4396mixture of upper and lower case.
4397
4398With http_header the individual header value is normalized in a way
4399that is appropriate for that header.
4400
4401If you don’t specify a header you get all of the headers.
4402http_raw_header includes the unmodified header names and values as
4403they appeared in the original message. http_header is the same except
4404percent encodings and cookies are removed and paths are simplified
4405exactly as if the headers were a URI.
4406
4407In most cases specifying individual headers creates a more efficient
4408and accurate rule. It is recommended that new rules be written using
4409individual headers whenever possible.
4410
44115.10.6.3. http_trailer and http_raw_trailer
4412
4413HTTP permits header lines to appear after a chunked body ends.
4414Typically they contain information about the message content that was
4415not available when the headers were created. For convenience we call
4416them trailers.
4417
4418http_trailer and http_raw_trailer are identical to their header
4419counterparts except they apply to these end headers. If you want a
4420rule to inspect both kinds of headers you need to write two rules,
4421one using header and one using trailer.
4422
44235.10.6.4. http_cookie and http_raw_cookie
4424
4425These provide the value of the Cookie header for a request message
4426and the Set-Cookie for a response message. If multiple cookies are
4427present they will be concatenated into a comma-separated list.
4428
4429Normalization for http_cookie is the same URI-style normalization
4430applied to http_header when no specific header is specified.
4431
44325.10.6.5. http_true_ip
4433
4434This provides the original IP address of the client sending the
4435request as it was stored by a proxy in the request message headers.
4436Specifically it is the last IP address listed in the X-Forwarded-For,
4437True-Client-IP or any other custom x-forwarded-for type header. If
4438multiple headers are present the preference defined in xff_headers
4439configuration is considered.
4440
44415.10.6.6. http_client_body
4442
4443This is the body of a request message such as POST or PUT.
4444Normalization for http_client_body is the same URI-like normalization
4445applied to http_header when no specific header is specified.
4446
44475.10.6.7. http_raw_body
4448
4449This is the body of a request or response message. It will be
4450dechunked and unzipped if applicable but will not be normalized in
4451any other way.
4452
44535.10.6.8. http_method
4454
4455The method field of a request message. Common values are "GET",
4456"POST", "OPTIONS", "HEAD", "DELETE", "PUT", "TRACE", and "CONNECT".
4457
44585.10.6.9. http_stat_code
4459
4460The status code field of a response message. This is normally a
44613-digit number between 100 and 599. In this example it is 200.
4462
4463HTTP/1.1 200 OK
4464
44655.10.6.10. http_stat_msg
4466
4467The reason phrase field of a response message. This is the
4468human-readable text following the status code. "OK" in the previous
4469example.
4470
44715.10.6.11. http_version
4472
4473The protocol version information that appears on the first line of an
4474HTTP message. This is usually "HTTP/1.0" or "HTTP/1.1".
4475
44765.10.6.12. http_raw_request and http_raw_status
4477
4478These are the unmodified first header line of the HTTP request and
4479response messages respectively. These rule options are a safety valve
4480in case you need to do something you cannot otherwise do. In most
4481cases it is better to use a rule option for a specific part of the
4482first header line. For a request message those are http_method,
4483http_raw_uri, and http_version. For a response message those are
4484http_version, http_stat_code, and http_stat_msg.
4485
44865.10.6.13. file_data
4487
4488The file_data contains the normalized message body. This is the
4489normalization described above under gzip, normalize_utf,
4490decompress_pdf, decompress_swf, and normalize_javascript.
4491
44925.10.6.14. js_data
4493
4494The js_data contains normalized JavaScript text collected from the
4495whole PDU (inline or external scripts). It requires the Enhanced
4496Normalizer enabled: http_inspect = { js_norm_bytes_depth = N },
4497js_norm_bytes_depth option is described above. Despite what js_data
4498has, file_data still contains the whole HTTP body with an original
4499JavaScript in it.
4500
45015.10.6.15. vba_data
4502
4503The vba_data will contain the decompressed Visual Basic for
4504Applications (vba) macro data embedded in MS office files. It
4505requires decompress_zip and decompress_vba options enabled.
4506
45075.10.6.16. num_headers and num_trailers
4508
4509These rule options are used to check the number of headers and
4510trailers, respectively. Checks available: equal to "=" or just value,
4511not "!" or "!=", less than "<", greater than ">", less or equal to
4512"⇐", less or greater than ">=", in range "<>", in range or equal to "
4513<⇒".
4514
45155.10.7. Timing issues and combining rule options
4516
4517HTTP inspector is stateful. That means it is aware of a bigger
4518picture than the packet in front of it. It knows what all the pieces
4519of a message are, the dividing lines between one message and the
4520next, which request message triggered which response message,
4521pipelines, and how many messages have been sent over the current
4522connection.
4523
4524Some rules use a single rule option:
4525
4526alert tcp any any -> any any ( msg:"URI example"; flow:established,
4527to_server; http_uri; content:"chocolate"; sid:1; rev:1; )
4528
4529Whenever a new URI is available this rule will be evaluated. Nothing
4530complicated about that, but suppose we use more than one rule option:
4531
4532alert tcp any any -> any any ( msg:"combined example"; flow:established,
4533to_server; http_uri: with_body; content:"chocolate"; file_data;
4534content:"sinister POST data"; sid:5; rev:1; )
4535
4536The with_body option to http_uri causes the URI to be made available
4537with the message body. Use with_body for header-related rule options
4538in rules that also examine the message body.
4539
4540The with_trailer option is analogous and causes an earlier message
4541element to be made available at the end of the message when the
4542trailers following a chunked body arrive.
4543
4544alert tcp any any -> any any ( msg:"double content-language";
4545flow:established, to_client; http_header: with_trailer, field
4546content-language; content:"da", nocase; http_trailer: field
4547content-language; content:"en", nocase; sid:6; rev:1; )
4548
4549This rule will alert if the Content-Language changes from Danish in
4550the headers to English in the trailers. The with_trailer option is
4551essential to make this rule work.
4552
4553It is also possible to write rules that examine both the client
4554request and the server response to it.
4555
4556alert tcp any any -> any any ( msg:"request and response example";
4557flow:established, to_client; http_uri: with_body; content:"chocolate";
4558file_data; content:"white chocolate"; sid:7; rev:1; )
4559
4560This rule looks for white chocolate in a response message body where
4561the URI of the request contained chocolate. Note that this is a
4562"to_client" rule that will alert on and potentially block a server
4563response containing white chocolate, but only if the client URI
4564requested chocolate. If the rule were rewritten "to_server" it would
4565be nonsense and not work. Snort cannot block a client request based
4566on what the server response will be because that has not happened
4567yet.
4568
4569Another point is "with_body" for http_uri. This ensures the rule
4570works on the entire response body. If we were looking for white
4571chocolate in the response headers this would not be necessary.
4572
4573Response messages do not have a URI so there was only one thing
4574http_uri could have meant in the previous rule. It had to be
4575referring to the request message. Sometimes that is not so clear.
4576
4577alert tcp any any -> any any ( msg:"header ambiguity example 1";
4578flow:established, to_client; http_header: with_body; content:
4579"chocolate"; file_data; content:"white chocolate"; sid:8; rev:1; )
4580
4581alert tcp any any -> any any ( msg:"header ambiguity example 2";
4582flow:established, to_client; http_header: with_body, request; content:
4583"chocolate"; file_data; content:"white chocolate"; sid:8; rev:2; )
4584
4585Our search for chocolate has moved from the URI to the message
4586headers. Both the request and response messages have headers—which
4587one are we asking about? Ambiguity is always resolved in favor of
4588looking in the current message which is the response. The first rule
4589is looking for a server response containing chocolate in the headers
4590and white chocolate in the body.
4591
4592The second rule uses the "request" option to explicitly say that the
4593http_header to be searched is the request header.
4594
4595Let’s put all of this together. There are six opportunities to do
4596detection:
4597
4598 1. When the the request headers arrive. The request line and all of
4599    the headers go through detection at the same time.
4600 2. When sections of the request message body arrive. If you want to
4601    combine this with something from the request line or headers you
4602    must use the with_body option.
4603 3. When the request trailers arrive. If you want to combine this
4604    with something from the request line or headers you must use the
4605    with_trailer option.
4606 4. When the response headers arrive. The status line and all of the
4607    headers go through detection at the same time. These may be
4608    combined with elements from the request line, request headers, or
4609    request trailers. Where ambiguity arises use the request option.
4610 5. When sections of the response message body arrive. These may be
4611    combined with the status line, response headers, request line,
4612    request headers, or request trailers as described above.
4613 6. When the response trailers arrive. Again these may be combined as
4614    described above.
4615
4616Message body sections can only go through detection at the time they
4617are received. Headers may be combined with later items but the body
4618cannot.
4619
4620
46215.11. HTTP/2 Inspector
4622
4623--------------
4624
4625New in Snort 3, the HTTP/2 inspector enables Snort to process HTTP/2
4626traffic.
4627
46285.11.1. Overview
4629
4630Despite the name, it is better to think of HTTP/2 not as a newer
4631version of HTTP/1.1, but rather a separate protocol layer that runs
4632under HTTP/1.1 and on top of TLS or TCP. It supports several new
4633features with the goal of improving the performance of HTTP requests,
4634notably the ability to multiplex many requests over a single TCP
4635connection, HTTP header compression, and server push.
4636
4637HTTP/2 is a perfect fit for the new Snort 3 PDU-based inspection
4638architecture. The HTTP/2 inspector parses and strips the HTTP/2
4639protocol framing and outputs HTTP/1.1 messages, exactly what
4640http_inspect wants to input. The HTTP/2 traffic then undergoes the
4641same processing as regular HTTP/1.1 traffic discussed above. So if
4642you haven’t already, take a look at the HTTP Inspector section; those
4643features also apply to HTTP/2 traffic.
4644
46455.11.2. Configuration
4646
4647You can configure the HTTP/2 inspector with the default configuration
4648by adding:
4649
4650http2_inspect = {}
4651
4652to your snort.lua configuration file. Since processing HTTP/2 traffic
4653relies on the HTTP inspector, http_inspect must also be configured.
4654Keep in mind that the http_inspect configuration will also impact
4655HTTP/2 traffic.
4656
46575.11.2.1. concurrent_streams_limit
4658
4659This limits the maximum number of HTTP/2 streams Snort will process
4660concurrently in a single HTTP/2 flow. The default and minimum
4661configurable value is 100. It can be configured up to a maximum of
46621000.
4663
46645.11.3. Detection rules
4665
4666Since HTTP/2 traffic is processed through the HTTP inspector, all of
4667the rule options discussed above are also available for HTTP/2
4668traffic. To smooth the transition to inspecting HTTP/2, rules that
4669specify service:http will be treated as if they also specify
4670service:http2. Thus:
4671
4672alert tcp any any -> any any (flow:established, to_server;
4673http_uri; content:"/foo";
4674service: http; sid:10; rev:1;)
4675
4676is understood to mean:
4677
4678alert tcp any any -> any any (flow:established, to_server;
4679http_uri; content:"/foo";
4680service: http,http2; sid:10; rev:1;)
4681
4682Thus it will alert on "/foo" in the URI for both HTTP/1 and HTTP/2
4683traffic.
4684
4685The reverse is not true. "service: http2" without http will match on
4686HTTP/2 flows but not HTTP/1 flows.
4687
4688This feature makes it easy to add HTTP/2 inspection without modifying
4689large numbers of existing rules. New rules should explicitly specify
4690"service http,http2;" if that is the desired behavior. Eventually
4691support for http implies http2 may be deprecated and removed.
4692
4693
46945.12. IEC104 Inspector
4695
4696--------------
4697
4698iec104 inspector is a service inspector for the IEC 60870-5-104
4699protocol.
4700
47015.12.1. Overview
4702
4703IEC 60870-5-104 (iec104) is a protocol distributed by the
4704International Electrotechnical Commission (IEC) that provides a
4705standardized method of sending telecontrol messages between central
4706stations and outstations, typically running on TCP port 2404.
4707
4708It is used in combination with the companion specifications in the
4709IEC 60870-5 family, most notably IEC 60870-5-101, to provide reliable
4710transport via TCP/IP.
4711
4712An iec104 Application Protocol Data Unit (APDU) consists of one of
4713three Application Protocol Control Information (APCI) structures,
4714each beginning with the start byte 0x68. In the case of an
4715Information Transfer APCI, an Application Service Data Unit (ASDU)
4716follows the APCI.
4717
4718The iec104 inspector decodes the iec104 protocol and provides rule
4719options to access certain protocol fields and data content. This
4720allows the user to write rules for iec104 packets without decoding
4721the protocol.
4722
47235.12.2. Configuration
4724
4725iec104 messages can be normalized to either combine a message spread
4726across multiple frames, or to split apart multiple messages within
4727one frame. No manual configuration is necessary to leverage this
4728functionality.
4729
47305.12.3. Quick Guide
4731
4732A typical iec104 configuration looks like this:
4733
4734binder =
4735{
4736    {
4737        when =
4738        {
4739            proto = 'tcp',
4740            ports = '2404'
4741        },
4742        use =
4743        {
4744            type = 'iec104'
4745        },
4746    },
4747}
4748
4749iec104 = { }
4750
4751In this example, the tcp inspector is defined based on port. All
4752configurations are default.
4753
4754Debug logging can be enabled with the following additional
4755configuration:
4756
4757trace =
4758{
4759    modules =
4760    {
4761        iec104 =
4762        {
4763            all = 1
4764        }
4765    }
4766}
4767
47685.12.4. Rule Options
4769
4770New rule options are supported by enabling the iec104 inspector:
4771
4772  * iec104_apci_type
4773  * iec104_asdu_func
4774
47755.12.4.1. iec104_apci_type
4776
4777Determining the APCI type of an iec104 message involves checking the
4778state of one to two bits in the message’s first control field octet.
4779This can be completed with a byte_test in a plaintext rule, however
4780it adds unnecessary complexity to the rule. Since most rules
4781inspecting iec104 traffic will target APCI Type I messages, this
4782option was created to alleviate the need to manually check the type
4783and subsequently reduce the complexity of the rule.
4784
4785This option takes one argument with three acceptable configurations.
4786
4787Examples:
4788
4789iec104_apci_type:unnumbered_control_function;
4790iec104_apci_type:S;
4791iec104_apci_type:i;
4792
4793This option is used to verify that the message being processed is of
4794the specified type. The argument passed to this rule option can be
4795specified in one of three ways: the full type name, the lowercase
4796type abbreviation, or the uppercase type abbreviation.
4797
47985.12.4.2. iec104_asdu_func
4799
4800Determining the ASDU function of an iec104 message can be completed
4801with a plaintext rule that checks a single byte in the message,
4802however it also requires verifying that the message’s APCI is of Type
4803I. Since a rule writer may not necessarily know that this additional
4804check must be made, this option was created to simplify the process
4805of verifying the function type and subsequently reduce the complexity
4806of the rule.
4807
4808This option takes one argument with two acceptable configurations.
4809
4810Examples:
4811
4812iec104_asdu_func:M_SP_NA_1;
4813iec104_asdu_func:m_ps_na_1;
4814
4815This option is used to verify that the message being processed is
4816using the specified ASDU function. The argument passed to this rule
4817option can be specified in one of two ways: the uppercase function
4818name, or the lowercase function name.
4819
4820
48215.13. Performance Monitor
4822
4823--------------
4824
4825The new and improved performance monitor! Is your sensor being bogged
4826down by too many flows? perf_monitor! Why are certain TCP segments
4827being dropped without hitting a rule? perf_monitor! Why is a sensor
4828leaking water? Not perf_monitor, check with stream…
4829
48305.13.1. Overview
4831
4832The Snort performance monitor is the built-in utility for monitoring
4833system and traffic statistics. All statistics are separated by
4834processing thread. perf_monitor supports several trackers for
4835monitoring such data:
4836
48375.13.2. Base Tracker
4838
4839The base tracker is used to gather running statistics about Snort and
4840its running modules. All Snort modules gather, at the very least,
4841counters for the number of packets reaching it. Most supplement these
4842counts with those for domain specific functions, such as
4843http_inspect’s number of GET requests seen.
4844
4845Statistics are gathered live and can be reported at regular
4846intervals. The stats reported correspond only to the interval in
4847question and are reset at the beginning of each interval.
4848
4849These are the same counts displayed when Snort shuts down, only
4850sorted amongst the discrete intervals in which they occurred.
4851
4852Base differs from prior implementations in Snort in that all stats
4853gathered are only raw counts, allowing the data to be evaluated as
4854needed. Additionally, base is entirely pluggable. Data from new Snort
4855plugins can be added to the existing stats either automatically or,
4856if specified, by name and function.
4857
4858All plugins and counters can be enabled or disabled individually,
4859allowing for only the data that is actually desired instead of overly
4860verbose performance logs.
4861
4862To enable everything:
4863
4864perf_monitor = { modules = {} }
4865
4866To enable everything within a module:
4867
4868perf_monitor =
4869{
4870    modules =
4871    {
4872        {
4873            name = 'stream_tcp',
4874            pegs = [[ ]]
4875        },
4876    }
4877}
4878
4879To enable specific counts within modules:
4880
4881perf_monitor =
4882{
4883    modules =
4884    {
4885        {
4886            name = 'stream_tcp',
4887            pegs = [[ overlaps gaps ]]
4888        },
4889    }
4890
4891Note: Event stats from prior Snorts are now located within base
4892statistics.
4893
48945.13.3. Flow Tracker
4895
4896Flow tracks statistics regarding traffic and L3/L4 protocol
4897distributions. This data can be used to build a profile of traffic
4898for inspector tuning and for identifying where Snort may be stressed.
4899
4900To enable:
4901
4902perf_monitor = { flow = true }
4903
49045.13.4. FlowIP Tracker
4905
4906FlowIP provides statistics for individual hosts within a network.
4907This data can be used for identifying communication habits, such as
4908generating large or small amounts of data, opening a small or large
4909number of sessions, and tendency to send smaller or larger IP
4910packets.
4911
4912To enable:
4913
4914perf_monitor = { flow_ip = true }
4915
49165.13.5. CPU Tracker
4917
4918This tracker monitors the CPU and wall time spent by a given
4919processing thread.
4920
4921To enable:
4922
4923perf_monitor = { cpu = true }
4924
49255.13.6. Formatters
4926
4927Performance monitor allows statistics to be output in a few formats.
4928Along with human readable text (as seen at shutdown) and csv formats,
4929a Flatbuffers binary format is also available if Flatbuffers is
4930present at build. A utility for accessing the statistics generated in
4931this format has been included for convenience (see fbstreamer in
4932tools). This tool generates a YAML array of records found, allowing
4933the data to be read by humans or passed into other analysis tools.
4934For information on working directly with the Flatbuffers file format
4935used by Performance monitor, see the developer notes for Performance
4936monitor or the code provided for fbstreamer.
4937
4938
49395.14. POP and IMAP
4940
4941--------------
4942
4943POP inspector is a service inspector for POP3 protocol and IMAP
4944inspector is for IMAP4 protocol.
4945
49465.14.1. Overview
4947
4948POP and IMAP inspectors examine data traffic and find POP and IMAP
4949commands and responses. The inspectors also identify the command,
4950header, body sections and extract the MIME attachments and decode it
4951appropriately. The pop and imap also identify and whitelist the pop
4952and imap traffic.
4953
49545.14.2. Configuration
4955
4956POP inspector and IMAP inspector offer same set of configuration
4957options for MIME decoding depth. These depths range from 0 to 65535
4958bytes. Setting the value to 0 ("do none") turns the feature off.
4959Alternatively the value -1 means an unlimited amount of data should
4960be decoded. If you do not specify the default value is 1460 bytes.
4961
4962The depth limits apply per attachment. They are:
4963
49645.14.2.1. b64_decode_depth
4965
4966Set the base64 decoding depth used to decode the base64-encoded MIME
4967attachments.
4968
49695.14.2.2. qp_decode_depth
4970
4971Set the Quoted-Printable (QP) decoding depth used to decode
4972QP-encoded MIME attachments.
4973
49745.14.2.3. bitenc_decode_depth
4975
4976Set the non-encoded MIME extraction depth used for non-encoded MIME
4977attachments.
4978
49795.14.2.4. uu_decode_depth
4980
4981Set the Unix-to-Unix (UU) decoding depth used to decode UU-encoded
4982attachments.
4983
49845.14.2.5. Examples
4985
4986stream = { }
4987
4988stream_tcp = { }
4989
4990stream_ip = { }
4991
4992binder =
4993{
4994    {
4995        {
4996            when = { proto = 'tcp', ports = '110', },
4997            use = { type = 'pop', },
4998        },
4999        {
5000            when = { proto = 'tcp', ports = '143', },
5001            use =  { type = 'imap', },
5002        },
5003    },
5004}
5005
5006imap =
5007{
5008    qp_decode_depth = 500,
5009}
5010
5011pop =
5012{
5013    qp_decode_depth = -1,
5014    b64_decode_depth = 3000,
5015}
5016
5017
50185.15. Port Scan
5019
5020--------------
5021
5022A module to detect port scanning
5023
50245.15.1. Overview
5025
5026This module is designed to detect the first phase in a network
5027attack: Reconnaissance. In the Reconnaissance phase, an attacker
5028determines what types of network protocols or services a host
5029supports. This is the traditional place where a portscan takes place.
5030This phase assumes the attacking host has no prior knowledge of what
5031protocols or services are supported by the target, otherwise this
5032phase would not be necessary.
5033
5034As the attacker has no beforehand knowledge of its intended target,
5035most queries sent by the attacker will be negative (meaning that the
5036services are closed). In the nature of legitimate network
5037communications, negative responses from hosts are rare, and rarer
5038still are multiple negative responses within a given amount of time.
5039Our primary objective in detecting portscans is to detect and track
5040these negative responses.
5041
5042One of the most common portscanning tools in use today is Nmap. Nmap
5043encompasses many, if not all, of the current portscanning techniques.
5044Portscan was designed to be able to detect the different types of
5045scans Nmap can produce.
5046
5047The following are a list of the types of Nmap scans Portscan will
5048currently alert for.
5049
5050  * TCP Portscan
5051  * UDP Portscan
5052  * IP Portscan
5053
5054These alerts are for one to one portscans, which are the traditional
5055types of scans; one host scans multiple ports on another host. Most
5056of the port queries will be negative, since most hosts have
5057relatively few services available.
5058
5059  * TCP Decoy Portscan
5060  * UDP Decoy Portscan
5061  * IP Decoy Portscan
5062
5063Decoy portscans are much like regular, only the attacker has spoofed
5064source address inter-mixed with the real scanning address. This
5065tactic helps hide the true identity of the attacker.
5066
5067  * TCP Distributed Portscan
5068  * UDP Distributed Portscan
5069  * IP Distributed Portscan
5070
5071These are many to one portscans. Distributed portscans occur when
5072multiple hosts query one host for open services. This is used to
5073evade an IDS and obfuscate command and control hosts.
5074
5075Note
5076
5077Negative queries will be distributed among scanning hosts, so we
5078track this type of scan through the scanned host.
5079
5080  * TCP Portsweep
5081  * UDP Portsweep
5082  * IP Portsweep
5083  * ICMP Portsweep
5084
5085These alerts are for one to many portsweeps. One host scans a single
5086port on multiple hosts. This usually occurs when a new exploit comes
5087out and the attacker is looking for a specific service.
5088
5089Note
5090
5091The characteristics of a portsweep scan may not result in many
5092negative responses. For example, if an attacker portsweeps a web farm
5093for port 80, we will most likely not see many negative responses.
5094
5095  * TCP Filtered Portscan
5096  * UDP Filtered Portscan
5097  * IP Filtered Portscan
5098  * TCP Filtered Decoy Portscan
5099  * UDP Filtered Decoy Portscan
5100  * IP Filtered Decoy Portscan
5101  * TCP Filtered Portsweep
5102  * UDP Filtered Portsweep
5103  * IP Filtered Portsweep
5104  * ICMP Filtered Portsweep
5105  * TCP Filtered Distributed Portscan
5106  * UDP Filtered Distributed Portscan
5107  * IP Filtered Distributed Portscan
5108
5109"Filtered" alerts indicate that there were no network errors (ICMP
5110unreachables or TCP RSTs) or responses on closed ports have been
5111suppressed. It’s also a good indicator on whether the alert is just a
5112very active legitimate host. Active hosts, such as NATs, can trigger
5113these alerts because they can send out many connection attempts
5114within a very small amount of time. A filtered alert may go off
5115before responses from the remote hosts are received.
5116
5117Portscan only generates one alert for each host pair in question
5118during the time window. On TCP scan alerts, Portscan will also
5119display any open ports that were scanned. On TCP sweep alerts
5120however, Portscan will only track open ports after the alert has been
5121triggered. Open port events are not individual alerts, but tags based
5122off the original scan alert.
5123
51245.15.2. Scan levels
5125
5126There are 3 default scan levels that can be set.
5127
51281) default_hi_port_scan
51292) default_med_port_scan
51303) default_low_port_scan
5131
5132Each of these default levels have separate options that can be edited
5133to alter the scan sensitivity levels (scans, rejects, nets or ports)
5134
5135Example:
5136
5137port_scan = default_low_port_scan
5138
5139port_scan.tcp_decoy.ports = 1
5140port_scan.tcp_decoy.scans = 1
5141port_scan.tcp_decoy.rejects = 1
5142port_scan.tcp_ports.nets = 1
5143
5144The example above would change each of the individual settings to 1.
5145
5146NOTE:The default levels for scans, rejects, nets and ports can be
5147seen in the snort_defaults.lua file.
5148
5149The counts can be seen in the alert outputs (-Acmg shown below):
5150
515150 72 69 6F 72 69 74 79  20 43 6F 75 6E 74 3A 20  Priority  Count:
515230 0A 43 6F 6E 6E 65 63  74 69 6F 6E 20 43 6F 75  0.Connec tion Cou
51536E 74 3A 20 34 35 0A 49  50 20 43 6F 75 6E 74 3A  nt: 45.I P Count:
515420 31 0A 53 63 61 6E 6E  65 72 20 49 50 20 52 61  1.Scann er IP Ra
51556E 67 65 3A 20 31 2E 32  2E 33 2E 34 3A 31 2E 32  nge: 1.2 .3.4:1.2
51562E 33 2E 34 0A 50 6F 72  74 2F 50 72 6F 74 6F 20  .3.4.Por t/Proto
515743 6F 75 6E 74 3A 20 33  37 0A 50 6F 72 74 2F 50  Count: 3 7.Port/P
515872 6F 74 6F 20 52 61 6E  67 65 3A 20 31 3A 39 0A  roto Ran ge: 1:9.
5159
5160"Low" alerts are only generated on error packets sent from the target
5161host, and because of the nature of error responses, this setting
5162should see very few false positives. However, this setting will never
5163trigger a Filtered Scan alert because of a lack of error responses.
5164This setting is based on a static time window of 60 seconds, after
5165which this window is reset.
5166
5167"Medium" alerts track Connection Counts, and so will generate
5168Filtered Scan alerts. This setting may false positive on active hosts
5169(NATs, proxies, DNS caches, etc), so the user may need to deploy the
5170use of Ignore directives to properly tune this directive.
5171
5172"High" alerts continuously track hosts on a network using a time
5173window to evaluate portscan statistics for that host. A "High"
5174setting will catch some slow scans because of the continuous
5175monitoring, but is very sensitive to active hosts. This most
5176definitely will require the user to tune Portscan.
5177
51785.15.3. Tuning Portscan
5179
5180The most important aspect in detecting portscans is tuning the
5181detection engine for your network(s). Here are some tuning tips:
5182
5183Use the watch_ip, ignore_scanners, and ignore_scanned options. It’s
5184important to correctly set these options. The watch_ip option is easy
5185to understand. The analyst should set this option to the list of CIDR
5186blocks and IPs that they want to watch. If no watch_ip is defined,
5187Portscan will watch all network traffic. The ignore_scanners and
5188ignore_scanned options come into play in weeding out legitimate hosts
5189that are very active on your network. Some of the most common
5190examples are NAT IPs, DNS cache servers, syslog servers, and nfs
5191servers. Portscan may not generate false positives for these types of
5192hosts, but be aware when first tuning Portscan for these IPs.
5193Depending on the type of alert that the host generates, the analyst
5194will know which to ignore it as. If the host is generating portsweep
5195events, then add it to the ignore_scanners option. If the host is
5196generating portscan alerts (and is the host that is being scanned),
5197add it to the ignore_scanned option.
5198
5199Filtered scan alerts are much more prone to false positives. When
5200determining false positives, the alert type is very important. Most
5201of the false positives that Portscan may generate are of the filtered
5202scan alert type. So be much more suspicious of filtered portscans.
5203Many times this just indicates that a host was very active during the
5204time period in question. If the host continually generates these
5205types of alerts, add it to the ignore_scanners list or use a lower
5206sensitivity level.
5207
5208Make use of the Priority Count, Connection Count, IP Count, Port
5209Count, IP range, and Port range to determine false positives. The
5210portscan alert details are vital in determining the scope of a
5211portscan and also the confidence of the portscan. In the future, we
5212hope to automate much of this analysis in assigning a scope level and
5213confidence level, but for now the user must manually do this. The
5214easiest way to determine false positives is through simple ratio
5215estimations. The following is a list of ratios to estimate and the
5216associated values that indicate a legitimate scan and not a false
5217positive.
5218
5219Connection Count / IP Count: This ratio indicates an estimated
5220average of connections per IP. For portscans, this ratio should be
5221high, the higher the better. For portsweeps, this ratio should be
5222low.
5223
5224Port Count / IP Count: This ratio indicates an estimated average of
5225ports connected to per IP. For portscans, this ratio should be high
5226and indicates that the scanned host’s ports were connected to by
5227fewer IPs. For portsweeps, this ratio should be low, indicating that
5228the scanning host connected to few ports but on many hosts.
5229
5230Connection Count / Port Count: This ratio indicates an estimated
5231average of connections per port. For portscans, this ratio should be
5232low. This indicates that each connection was to a different port. For
5233portsweeps, this ratio should be high. This indicates that there were
5234many connections to the same port.
5235
5236The reason that Priority Count is not included, is because the
5237priority count is included in the connection count and the above
5238comparisons take that into consideration. The Priority Count play an
5239important role in tuning because the higher the priority count the
5240more likely it is a real portscan or portsweep (unless the host is
5241firewalled).
5242
5243If all else fails, lower the sensitivity level. If none of these
5244other tuning techniques work or the analyst doesn’t have the time for
5245tuning, lower the sensitivity level. You get the best protection the
5246higher the sensitivity level, but it’s also important that the
5247portscan detection engine generates alerts that the analyst will find
5248informative. The low sensitivity level only generates alerts based on
5249error responses. These responses indicate a portscan and the alerts
5250generated by the low sensitivity level are highly accurate and
5251require the least tuning. The low sensitivity level does not catch
5252filtered scans, since these are more prone to false positives.
5253
5254
52555.16. Sensitive Data Filtering
5256
5257--------------
5258
5259The sd_pattern IPS option provides detection and filtering of
5260Personally Identifiable Information (PII). This information includes
5261credit card numbers, U.S. Social Security numbers, and email
5262addresses. A rich regular expression syntax is available for defining
5263your own PII.
5264
52655.16.1. Hyperscan
5266
5267The sd_pattern rule option is powered by the open source Hyperscan
5268library from Intel. It provides a regex grammar which is mostly PCRE
5269compatible. To learn more about Hyperscan see https://intel.github.io
5270/hyperscan/dev-reference/
5271
52725.16.2. Syntax
5273
5274Snort provides sd_pattern as IPS rule option with no additional
5275inspector overhead. The Rule option takes the following syntax.
5276
5277sd_pattern: "<pattern>"[, threshold <count>];
5278
52795.16.2.1. Pattern
5280
5281Pattern is the most important and is the only required parameter to
5282sd_pattern. It supports 3 built in patterns which are configured by
5283name: "credit_card", "us_social" and "us_social_nodashes", as well as
5284user defined regular expressions of the Hyperscan dialect (see https:
5285//intel.github.io/hyperscan/dev-reference/compilation.html#
5286pattern-support).
5287
5288sd_pattern:"credit_card";
5289
5290When configured, Snort will replace the pattern credit_card with the
5291built in pattern. In addition to pattern matching, Snort will
5292validate that the matched digits will pass the Luhn-check algorithm.
5293Currently the only pattern that performs extra verification.
5294
5295sd_pattern:"us_social";
5296sd_pattern:"us_social_nodashes";
5297
5298These special patterns will also be replaced with a built in pattern.
5299Naturally, "us_social" is a pattern of 9 digits separated by -'s in
5300the canonical form.
5301
5302sd_pattern:"\b\w+@ourdomain\.com\b"
5303
5304This is a user defined pattern which matches what is most likely
5305email addresses for the site "ourdomain.com". The pattern is a PCRE
5306compatible regex, \b matches a word boundary (whitespace, end of
5307line, non-word characters) and \w+ matches one or more word
5308characters. \. matches a literal ..
5309
5310The above pattern would match "a@ourdomain.com", "aa@ourdomain.com"
5311but would not match 1@ourdomain.com ab12@ourdomain.com or
5312@ourdomain.com.
5313
5314Note: This is just an example, this pattern is not suitable to detect
5315many correctly formatted emails.
5316
53175.16.2.2. Threshold
5318
5319Threshold is an optional parameter allowing you to change built in
5320default value (default value is 1). The following two instances are
5321identical. The first will assume the default value of 1 the second
5322declaration explicitly sets the threshold to 1.
5323
5324sd_pattern:"This rule requires 1 match";
5325sd_pattern:"This rule requires 1 match", threshold 1;
5326
5327That’s pretty easy, but here is one more example anyway.
5328
5329sd_pattern:"This is a string literal", threshold 300;
5330
5331This example requires 300 matches of the pattern "This is a string
5332literal" to qualify as a positive match. That is, if the string only
5333occurred 299 times in a packet, you will not see an event.
5334
53355.16.2.3. Obfuscating Credit Cards and Social Security Numbers
5336
5337Snort provides discreet logging for the built in patterns
5338"credit_card", "us_social" and "us_social_nodashes". Enabling
5339output.obfuscate_pii makes Snort obfuscate the suspect packet payload
5340which was matched by the patterns. This configuration is disabled by
5341default.
5342
5343output =
5344{
5345    obfuscate_pii = true
5346}
5347
53485.16.3. Example
5349
5350A complete Snort IPS rule
5351
5352alert tcp ( sid:1; msg:"Credit Card"; sd_pattern:"credit_card"; )
5353
5354Logged output when running Snort in "cmg" alert format.
5355
535602/25-21:19:05.125553 [**] [1:1:0] "Credit Card" [**] [Priority: 0] {TCP} 10.1.2.3:48620 -> 10.9.8.7:8
535702:01:02:03:04:05 -> 02:09:08:07:06:05 type:0x800 len:0x46
535810.1.2.3:48620 -> 10.9.8.7:8 TCP TTL:64 TOS:0x0 ID:14 IpLen:20 DgmLen:56
5359***A**** Seq: 0xB2  Ack: 0x2  Win: 0x2000  TcpLen: 20
5360- - - raw[16] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
536158 58 58 58 58 58 58 58 58 58 58 58 39 32 39 34              XXXXXXXXXXXX9294
5362- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5363
53645.16.4. Caveats
5365
5366 1. Snort currently requires setting the fast pattern engine to use
5367    "hyperscan" in order for sd_pattern ips option to function
5368    correctly.
5369
5370    search_engine = { search_method = 'hyperscan' }
5371
5372 2. Log obfuscation is only applicable to CMG and Unified2 logging
5373    formats.
5374 3. Log obfuscation doesn’t support user defined PII patterns. It is
5375    currently only supported for the built in patterns for Credit
5376    Cards and US Social Security numbers.
5377 4. Log obfuscation doesn’t work with stream rebuilt packet payloads.
5378    (This is a known bug).
5379
5380
53815.17. SMTP
5382
5383--------------
5384
5385SMTP inspector is a service inspector for SMTP protocol.
5386
53875.17.1. Overview
5388
5389The SMTP inspector examines SMTP connections looking for commands and
5390responses. It also identifies the command, header and body sections,
5391TLS data and extracts the MIME attachments. This inspector also
5392identifies and whitelists the SMTP traffic.
5393
5394SMTP inspector logs the filename, email addresses, attachment names
5395when configured.
5396
53975.17.2. Configuration
5398
5399SMTP command lines can be normalized to remove extraneous spaces.
5400TLS-encrypted traffic can be ignored, which improves performance. In
5401addition, plain-text mail data can be ignored for an additional
5402performance boost.
5403
5404The configuration options are described below:
5405
54065.17.2.1. normalize and normalize_cmds
5407
5408Normalization checks for more than one space character after a
5409command. Space characters are defined as space (ASCII 0x20) or tab
5410(ASCII 0x09). "normalize" provides options all|none|cmds, all checks
5411all commands, none turns off normalization for all commands. cmds
5412just checks commands listed with the "normalize_cmds" parameter. For
5413example:
5414
5415smtp = { normalize = 'cmds', normalize_cmds = 'RCPT VRFY EXPN' }
5416
54175.17.2.2. ignore_data
5418
5419Set it to true to ignore data section of mail (except for mail
5420headers) when processing rules.
5421
54225.17.2.3. ignore_tls_data
5423
5424Set it to true to ignore TLS-encrypted data when processing rules.
5425
54265.17.2.4. max_command_line_len
5427
5428Alert if an SMTP command line is longer than this value. Absence of
5429this option or a "0" means never alert on command line length. RFC
54302821 recommends 512 as a maximum command line length.
5431
54325.17.2.5. max_header_line_len
5433
5434Alert if an SMTP DATA header line is longer than this value. Absence
5435of this option or a "0" means never alert on data header line length.
5436RFC 2821 recommends 1024 as a maximum data header line length.
5437
54385.17.2.6. max_response_line_len
5439
5440Alert if an SMTP response line is longer than this value. Absence of
5441this option or a "0" means never alert on response line length. RFC
54422821 recommends 512 as a maximum response line length.
5443
54445.17.2.7. alt_max_command_line_len
5445
5446Overrides max_command_line_len for specific commands For example:
5447
5448alt_max_command_line_len =
5449{
5450    {
5451        command = 'MAIL',
5452        length = 260,
5453    },
5454    {
5455        command = 'RCPT',
5456        length = 300,
5457    },
5458}
5459
54605.17.2.8. invalid_cmds
5461
5462Alert if this command is sent from client side.
5463
54645.17.2.9. valid_cmds
5465
5466List of valid commands. We do not alert on commands in this list.
5467
5468DEFAULT empty list, but SMTP inspector has this list hard-coded: [[
5469ATRN AUTH BDAT DATA DEBUG EHLO EMAL ESAM ESND ESOM ETRN EVFY EXPN
5470HELO HELP IDENT MAIL NOOP ONEX QUEU QUIT RCPT RSET SAML SEND SIZE
5471STARTTLS SOML TICK TIME TURN TURNME VERB VRFY X-EXPS X-LINK2STATE
5472XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUE XSTA XTRN XUSR ]]
5473
54745.17.2.10. data_cmds
5475
5476List of commands that initiate sending of data with an end of data
5477delimiter the same as that of the DATA command per RFC 5321 - "
5478<CRLF>.<CRLF>".
5479
54805.17.2.11. binary_data_cmds
5481
5482List of commands that initiate sending of data and use a length value
5483after the command to indicate the amount of data to be sent, similar
5484to that of the BDAT command per RFC 3030.
5485
54865.17.2.12. auth_cmds
5487
5488List of commands that initiate an authentication exchange between
5489client and server.
5490
54915.17.2.13. xlink2state
5492
5493Enable/disable xlink2state alert, options are {disable | alert |
5494drop}. See CVE-2005-0560 for a description of the vulnerability.
5495
54965.17.2.14. MIME processing depth parameters
5497
5498These four MIME processing depth parameters are identical to their
5499POP and IMAP counterparts. See that section for further details.
5500
5501b64_decode_depth qp_decode_depth bitenc_decode_depth uu_decode_depth
5502
55035.17.2.15. Log Options
5504
5505Following log options allow SMTP inspector to log email addresses and
5506filenames. Please note, this is logged only with the unified2 output
5507and is not logged with the console output (-A cmg). u2spewfoo can be
5508used to read this data from the unified2.
5509
5510log_mailfrom
5511
5512This option enables SMTP inspector to parse and log the sender’s
5513email address extracted from the "MAIL FROM" command along with all
5514the generated events for that session. The maximum number of bytes
5515logged for this option is 1024.
5516
5517log_rcptto
5518
5519This option enables SMTP inspector to parse and log the recipient
5520email addresses extracted from the "RCPT TO" command along with all
5521the generated events for that session. Multiple recipients are
5522appended with commas. The maximum number of bytes logged for this
5523option is 1024.
5524
5525log_filename
5526
5527This option enables SMTP inspector to parse and log the MIME
5528attachment filenames extracted from the Content-Disposition header
5529within the MIME body along with all the generated events for that
5530session. Multiple filenames are appended with commas. The maximum
5531number of bytes logged for this option is 1024.
5532
5533log_email_hdrs
5534
5535This option enables SMTP inspector to parse and log the SMTP email
5536headers extracted from SMTP data along with all generated events for
5537that session. The number of bytes extracted and logged depends upon
5538the email_hdrs_log_depth.
5539
5540email_hdrs_log_depth
5541
5542This option specifies the depth for logging email headers. The
5543allowed range for this option is 0 - 20480. A value of 0 will disable
5544email headers logging. The default value for this option is 1464.
5545
55465.17.3. Example
5547
5548smtp =
5549{
5550    normalize = 'cmds',
5551    normalize_cmds = 'EXPN VRFY RCPT',
5552    b64_decode_depth = 0,
5553    qp_decode_depth = 0,
5554    bitenc_decode_depth = 0,
5555    uu_decode_depth = 0,
5556    log_mailfrom = true,
5557    log_rcptto = true,
5558    log_filename = true,
5559    log_email_hdrs = true,
5560    max_command_line_len = 512,
5561    max_header_line_len = 1000,
5562    max_response_line_len = 512,
5563    max_auth_command_line_len = 50,
5564    xlink2state = 'alert',
5565    alt_max_command_line_len =
5566    {
5567        {
5568            command = 'MAIL',
5569            length = 260,
5570        },
5571        {
5572            command = 'RCPT',
5573            length = 300,
5574        },
5575        {
5576            command = 'HELP',
5577            length = 500,
5578        },
5579        {
5580            command = 'HELO',
5581            length = 500,
5582        },
5583        {
5584            command = 'ETRN',
5585            length = 500,
5586        },
5587        {
5588            command = 'EXPN',
5589            length = 255,
5590        },
5591        {
5592            command = 'VRFY',
5593            length = 255,
5594        },
5595    },
5596}
5597
5598
55995.18. Telnet
5600
5601--------------
5602
5603Given a telnet data buffer, Telnet will normalize the buffer with
5604respect to telnet commands and option negotiation, eliminating telnet
5605command sequences per RFC 854. It will also determine when a telnet
5606connection is encrypted, per the use of the telnet encryption option
5607per RFC 2946.
5608
56095.18.1. Configuring the inspector to block exploits and attacks
5610
5611ayt_attack_thresh number
5612
5613Detect and alert on consecutive are you there [AYT] commands beyond
5614the threshold number specified. This addresses a few specific
5615vulnerabilities relating to bsd-based implementations of telnet.
5616
5617
56185.19. Trace
5619
5620--------------
5621
5622Snort 3 retired the different flavors of debug macros that used to be
5623set through the SNORT_DEBUG environment variable. It was replaced by
5624per-module trace functionality. Trace is turned on by setting the
5625specific trace module configuration in snort.lua. As before, to
5626enable debug tracing, Snort must be configured at build time with
5627--enable-debug-msgs. However, a growing number of modules (such as
5628wizard and snort.inspector_manager) are providing non-debug trace
5629messages in normal production builds.
5630
56315.19.1. Trace module
5632
5633The trace module is responsible for configuring traces and supports
5634the following parameters:
5635
5636output - configure the output method for trace messages
5637modules - trace configuration for specific modules
5638constraints - filter traces by the packet constraints
5639ntuple - on/off packet n-tuple info logging
5640timestamp - on/off message timestamps logging
5641
5642The following lines, added in snort.lua, will enable trace messages
5643for detection and codec modules. The messages will be printed to
5644syslog if the packet filtering constraints match. Messages will be in
5645extended format, including timestamp and n-tuple packet info at the
5646beginning of each trace message.
5647
5648trace =
5649{
5650    output = "syslog",
5651    modules =
5652    {
5653        detection = { detect_engine = 1 },
5654        decode = { all = 1 }
5655    },
5656    constraints =
5657    {
5658        ip_proto = 17,
5659        dst_ip = "10.1.1.2",
5660        src_port = 100,
5661        dst_port = 200
5662    },
5663    ntuple = true,
5664    timestamp = true
5665}
5666
5667The trace module supports config reloading. Also, it’s possible to
5668set or clear modules traces and packet filter constraints via the
5669control channel command.
5670
56715.19.2. Trace module - configuring traces
5672
5673The trace module has the modules option - a table with trace
5674configuration for specific modules. The following lines placed in
5675snort.lua will enable trace messages for detection, codec and wizard
5676modules:
5677
5678trace =
5679{
5680    modules =
5681    {
5682        detection = { all = 1 },
5683        decode = { all = 1 },
5684        wizard = { all = 1 }
5685    }
5686}
5687
5688The detection and snort modules are currently the only modules to
5689support multiple trace options. Others have only the default all
5690option, which will enable or disable all traces in a given module.
5691It’s available for multi-option modules also and works as a global
5692switcher:
5693
5694trace =
5695{
5696    modules =
5697    {
5698        detection = { all = 1 }  -- set each detection option to level 1
5699    }
5700}
5701
5702trace =
5703{
5704    modules =
5705    {
5706        detection = { all = 1, tag = 2 }  -- set each detection option to level 1 but the 'tag' to level 2
5707    }
5708}
5709
5710Also, it’s possible to enable or disable traces for all modules with
5711a top-level all option.
5712
5713The following configuration states that:
5714
5715  * all traces are enabled with verbosity level 5
5716  * traces for the decode module are enabled with level 3
5717  * rule_eval traces for the detection module are enabled with level
5718    1
5719
5720    trace =
5721    {
5722        modules =
5723        {
5724            all = 5,
5725            decode = { all = 3 },
5726            detection = { rule_eval = 1 }
5727        }
5728    }
5729
5730The full list of available trace parameters is placed into the "Basic
5731Modules.trace" chapter.
5732
5733Each option must be assigned an integer value between 0 and 255 to
5734specify a level of verbosity for that option:
5735
57360 - turn off trace messages printing for the option
57371 - print most significant trace messages for the option
5738255 - print all available trace messages for the option
5739
5740Tracing is disabled by default (verbosity level equals 0). The
5741verbosity level is treated as a threshold, so specifying a higher
5742value will result in all messages with a lower level being printed as
5743well. For example:
5744
5745trace =
5746{
5747    modules =
5748    {
5749        decode = { all = 3 }  -- messages with levels 1, 2, and 3 will be printed
5750    }
5751}
5752
57535.19.3. Trace module - configuring packet filter constraints for
5754packet related trace messages
5755
5756There is a capability to filter traces by the packet constraints. The
5757trace module has the constraints option - a table with filtering
5758configuration that will be applied to all trace messages that include
5759a packet. Filtering is done on a flow that packet is related. By
5760default filtering is disabled.
5761
5762Available constraints options:
5763
5764ip_proto - numerical IP protocol ID
5765src_ip - match all packets with a flow that has this client IP address (passed as a string)
5766src_port - match all packets with a flow that has this source port
5767dst_ip - match all packets with a flow that has this server IP address (passed as a string)
5768dst_port - match all packets with a flow that has this destination port
5769match - boolean flag to enable/disable whether constraints will ever match (enabled by default)
5770
5771The following lines placed in snort.lua will enable all trace
5772messages for detection filtered by ip_proto, dst_ip, src_port and
5773dst_port:
5774
5775trace =
5776{
5777    modules =
5778    {
5779        detection = { all = 1 }
5780    },
5781    constraints =
5782    {
5783        ip_proto = 6, -- tcp
5784        dst_ip = "10.1.1.10",
5785        src_port = 150,
5786        dst_port = 250
5787    }
5788}
5789
5790To create constraints that will never successfully match, set the
5791match parameter to false. This is useful for situations where one is
5792relying on external packet filtering from the DAQ module, or for
5793preventing all trace messages in the context of a packet. The
5794following is an example of such configuration:
5795
5796trace =
5797{
5798    modules =
5799    {
5800        snort = { all = 1 }
5801    },
5802    constraints =
5803    {
5804        match = false
5805    }
5806}
5807
58085.19.4. Trace module - configuring trace output method
5809
5810There is a capability to configure the output method for trace
5811messages. The trace module has the output option with two acceptable
5812values:
5813
5814"stdout" - printing to stdout
5815"syslog" - printing to syslog
5816
5817By default, the output method will be set based on the Snort run
5818mode. Normally it will use stdout, but if -D (daemon mode) and/or -M
5819(alert-syslog mode) are set, it will instead use syslog.
5820
5821Example - set output method as syslog:
5822
5823In snort.lua, the following lines were added:
5824
5825trace =
5826{
5827    output = "syslog",
5828    modules =
5829    {
5830        detection = { all = 1 }
5831    }
5832}
5833
5834As a result, each trace message will be printed into syslog (the
5835Snort run-mode will be ignored).
5836
58375.19.5. Configuring traces via control channel command
5838
5839There is a capability to configure module trace options and packet
5840constraints via the control channel command by using a Snort shell.
5841In order to enable shell, Snort has to be configured and built with
5842--enable-shell.
5843
5844The trace control channel command is a way how to configure module
5845trace options and/or packet filter constraints directly during Snort
5846run and without reloading the entire config.
5847
5848Control channel also allow adjusting trace output format by setting
5849ntuple and timestamp switchers.
5850
5851After entering the Snort shell, there are two commands available for
5852the trace module:
5853
5854trace.set({ modules = {...}, constraints = {...} }) - set modules traces and constraints (should pass a valid Lua-entry)
5855
5856trace.set({ modules = { all = N } }) - enable traces for all modules with verbosity level N
5857
5858trace.set({ ntuple = true/false }) - on/off packet n-tuple info logging
5859
5860trace.set({ timestamp = true/false }) - on/off timestamp logging
5861
5862trace.clear() - clear modules traces and constraints
5863
5864Also, it’s possible to omit tables in the trace.set() command:
5865
5866trace.set({constraints = {...}}) - set only filtering configuration keeping old modules traces
5867
5868trace.set({modules = {...}}) - set only module trace options keeping old filtering constraints
5869
5870trace.set({}) - disable traces and constraints (set to empty)
5871
58725.19.6. Trace messages format
5873
5874Each tracing message has a standard format:
5875
5876<module_name>:<option_name>:<message_log_level>: <particular_message>
5877
5878The stdout logger also prints thread type and thread instance ID at
5879the beginning of each trace message in a colon-separated manner.
5880
5881The capital letter at the beginning of the trace message indicates
5882the thread type.
5883
5884Possible thread types: C – main (control) thread P – packet thread O
5885– other thread
5886
5887Setting the option - ntuple allows you to change the trace message
5888format, expanding it with information about the processed packet.
5889
5890It will be added at the beginning, right after the thread type and
5891instance ID, in the following format:
5892
5893src_ip src_port -> dst_ip dst_port ip_proto AS=address_space
5894
5895Where:
5896
5897src_ip - source IP address
5898src_port - source port
5899dst_ip - destination IP address
5900dst_port - destination port
5901ip_proto - IP protocol ID
5902address_space - unique ID of the address space
5903
5904Those info can be displayed only for IP packets. Port defaults to
5905zero if a packet doesn’t have it.
5906
5907The timestamp option extends output format by logging the message
5908time in the next format:
5909
5910MM/DD-hh:mm:ss.SSSSSS
5911
5912Where:
5913
5914M – month
5915D – day
5916h – hours
5917m – minutes
5918s – seconds
5919S – milliseconds
5920
59215.19.7. Example - Debugging rules using detection trace
5922
5923The detection engine is responsible for rule evaluation. Turning on
5924the trace for it can help with debugging new rules.
5925
5926The relevant options for detection are as follow:
5927
5928rule_eval - follow rule evaluation
5929buffer - print evaluated buffer if it changed (level 1) or at every step (level 5)
5930rule_vars - print value of ips rule options vars
5931fp_search - print information on fast pattern search
5932
5933Buffer print is useful, but in case the buffer is very big can be too
5934verbose. Choose between verbosity levels 1, 5, or no buffer trace
5935accordingly.
5936
5937rule_vars is useful when the rule is using ips rule options vars.
5938
5939In snort.lua, the following lines were added:
5940
5941trace =
5942{
5943    modules =
5944    {
5945        detection =
5946        {
5947            rule_eval = 1,
5948            buffer = 1,
5949            rule_vars = 1,
5950            fp_search = 1
5951        }
5952    }
5953}
5954
5955The pcap has a single packet with payload:
5956
595710.AAAAAAAfoobar
5958
5959Evaluated on rules:
5960
5961# byte_math + oper with byte extract and content
5962# VAL = 1, byte_math = 0 + 10
5963alert tcp ( byte_extract: 1, 0, VAL, string, dec;
5964byte_math:bytes 1,offset VAL,oper +, rvalue 10, result var1, string dec;
5965content:"foo", offset var1; sid:3)
5966
5967#This rule should not trigger
5968alert tcp (content:"AAAAA"; byte_jump:2,0,relative;
5969content:"foo", within 3; sid:2)
5970
5971The output:
5972
5973detection:rule_eval:1: packet 1 C2S 127.0.0.1:1234 127.0.0.1:5678 (fast-patterns)
5974detection:rule_eval:1: Fast pattern search
5975detection:fp_search:1: 1 fp packet[16]
5976
5977snort.raw[16]:
5978- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
597931 30 00 41 41 41 41 41 41 41  66 6F 6F 62 61 72              10.AAAAAAAfoobar
5980- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
5981detection:rule_eval:1: Processing pattern match #1
5982detection:rule_eval:1: Fast pattern packet[5] = 'AAAAA' |41 41 41 41 41 | ( )
5983detection:rule_eval:1: Starting tree eval
5984detection:rule_eval:1: Evaluating option content, cursor name pkt_data, cursor position 0
5985
5986snort.raw[16]:
5987- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
598831 30 00 41 41 41 41 41 41 41  66 6F 6F 62 61 72              10.AAAAAAAfoobar
5989- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
5990detection:rule_vars:1: Rule options variables: var[0]=0 var[1]=0 var[2]=0
5991detection:rule_eval:1: Evaluating option byte_jump, cursor name pkt_data, cursor position 8
5992
5993snort.raw[8]:
5994- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
599541 41 66 6F 6F 62 61 72                                       AAfoobar
5996- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
5997detection:rule_eval:1: no match
5998detection:rule_vars:1: Rule options variables: var[0]=0 var[1]=0 var[2]=0
5999detection:rule_eval:1: Evaluating option byte_jump, cursor name pkt_data, cursor position 9
6000
6001snort.raw[7]:
6002- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
600341 66 6F 6F 62 61 72                                          Afoobar
6004- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6005detection:rule_eval:1: no match
6006detection:rule_vars:1: Rule options variables: var[0]=0 var[1]=0 var[2]=0
6007detection:rule_eval:1: Evaluating option byte_jump, cursor name pkt_data, cursor position 10
6008
6009snort.raw[6]:
6010- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
601166 6F 6F 62 61 72                                             foobar
6012- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6013detection:rule_eval:1: no match
6014detection:rule_eval:1: no match
6015detection:rule_eval:1: Processing pattern match #2
6016detection:rule_eval:1: Fast pattern packet[3] = 'foo' |66 6F 6F | ( )
6017detection:rule_eval:1: Starting tree eval
6018detection:rule_eval:1: Evaluating option byte_extract, cursor name pkt_data, cursor position 0
6019
6020snort.raw[16]:
6021- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
602231 30 00 41 41 41 41 41 41 41  66 6F 6F 62 61 72              10.AAAAAAAfoobar
6023- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6024detection:rule_vars:1: Rule options variables: var[0]=1 var[1]=0 var[2]=0
6025detection:rule_eval:1: Evaluating option byte_math, cursor name pkt_data, cursor position 1
6026
6027snort.raw[15]:
6028- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
602930 00 41 41 41 41 41 41 41 66  6F 6F 62 61 72                 0.AAAAAAAfoobar
6030- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6031detection:rule_vars:1: Rule options variables: var[0]=1 var[1]=10 var[2]=0
6032detection:rule_eval:1: Evaluating option content, cursor name pkt_data, cursor position 2
6033
6034snort.raw[14]:
6035- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
603600 41 41 41 41 41 41 41 66 6F  6F 62 61 72                    .AAAAAAAfoobar
6037- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6038detection:rule_vars:1: Rule options variables: var[0]=1 var[1]=10 var[2]=0
6039detection:rule_eval:1: Reached leaf, cursor name pkt_data, cursor position 13
6040
6041snort.raw[3]:
6042- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
604362 61 72                                                      bar
6044- - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -
6045detection:rule_eval:1: Matched rule gid:sid:rev 1:3:0
6046detection:rule_vars:1: Rule options variables: var[0]=1 var[1]=10 var[2]=0
604704/22-20:21:40.905630, 1, TCP, raw, 56, C2S, 127.0.0.1:1234, 127.0.0.1:5678, 1:3:0, allow
6048
60495.19.8. Example - Protocols decoding trace
6050
6051Turning on decode trace will print out information about the packets
6052decoded protocols. Can be useful in case of tunneling.
6053
6054Example for a icmpv4-in-ipv6 packet:
6055
6056In snort.lua, the following line was added:
6057
6058trace =
6059{
6060    modules =
6061    {
6062        decode = { all = 1 }
6063    }
6064}
6065
6066The output:
6067
6068decode:all:1: Codec eth (protocol_id: 34525) ip header starts at: 0x7f70800110f0, length is 14
6069decode:all:1: Codec ipv6 (protocol_id: 1) ip header starts at: 0x7f70800110f0, length is 40
6070decode:all:1: Codec icmp4 (protocol_id: 256) ip header starts at: 0x7f70800110f0, length is 8
6071decode:all:1: Codec unknown (protocol_id: 256) ip header starts at: 0x7f70800110f0, length is 0
6072
60735.19.9. Example - Track the time packet spends in each inspector
6074
6075There is a capability to track which inspectors evaluate a packet,
6076and how much time the inspector consumes doing so. These trace
6077messages could be enabled by the Snort module trace options:
6078
6079main - command execution traces (main trace logging)
6080inspector_manager - inspectors execution and time tracking traces
6081
6082Example for a single packet with payload:
6083
608410.AAAAAAAfoobar
6085
6086In snort.lua, the following lines were added:
6087
6088trace =
6089{
6090    modules =
6091    {
6092        snort =
6093        {
6094            -- could be replaced by 'all = 1'
6095            main = 1,
6096            inspector_manager = 1
6097        }
6098    }
6099}
6100
6101The output:
6102
6103snort:main:1: [0] Queuing command START for execution (refcount 1)
6104snort:main:1: [0] Queuing command RUN for execution (refcount 1)
6105snort:main:1: [0] Destroying completed command START
6106snort:inspector_manager:1: start inspection, raw, packet 1, context 1
6107snort:inspector_manager:1: enter stream
6108snort:inspector_manager:1: exit stream, elapsed time: 2 usec
6109snort:inspector_manager:1: stop inspection, raw, packet 1, context 1, total time: 14 usec
6110snort:inspector_manager:1: post detection inspection, raw, packet 1, context 1
6111snort:inspector_manager:1: end inspection, raw, packet 1, context 1, total time: 0 usec
6112snort:main:1: [0] Destroying completed command RUN
6113
61145.19.10. Example - trace filtering by packet constraints:
6115
6116In snort.lua, the following lines were added:
6117
6118ips =
6119{
6120    rules =
6121    [[
6122        alert tcp any any -> any any ( msg: "ALERT_TCP"; gid: 1001; sid: 1001 )
6123        alert udp any any -> any any ( msg: "ALERT_UDP"; gid: 1002; sid: 1002 )
6124    ]]
6125}
6126
6127trace =
6128{
6129    modules =
6130    {
6131        detection = { rule_eval = 1 }
6132    },
6133    constraints =
6134    {
6135        ip_proto = 17, -- udp
6136        dst_ip = "10.1.1.2",
6137        src_port = 100,
6138        dst_port = 200
6139    }
6140}
6141
6142The processed traffic was next:
6143
6144d ( stack="eth:ip4:udp" )
6145
6146c ( ip4:a="10.1.1.1", ip4:b="10.1.1.2", udp:a=100, udp:b=200 )
6147a ( pay="pass" )
6148b ( pay="pass" )
6149
6150c ( ip4:a="10.2.1.1" )
6151a ( pay="pass" )
6152b ( pay="pass" )
6153
6154c ( udp:a=101 )
6155a ( pay="block" )
6156b ( pay="block" )
6157
6158The output:
6159
6160detection:rule_eval:1: packet 1 UNK 10.1.1.1:100 10.1.1.2:200 (fast-patterns)
6161detection:rule_eval:1: Fast pattern processing - no matches found
6162detection:rule_eval:1: packet 1 UNK 10.1.1.1:100 10.1.1.2:200 (non-fast-patterns)
6163detection:rule_eval:1: packet 2 UNK 10.1.1.2:200 10.1.1.1:100 (fast-patterns)
6164detection:rule_eval:1: Fast pattern processing - no matches found
6165detection:rule_eval:1: packet 2 UNK 10.1.1.2:200 10.1.1.1:100 (non-fast-patterns)
6166detection:rule_eval:1: packet 3 UNK 10.2.1.1:100 10.1.1.2:200 (fast-patterns)
6167detection:rule_eval:1: Fast pattern processing - no matches found
6168detection:rule_eval:1: packet 3 UNK 10.2.1.1:100 10.1.1.2:200 (non-fast-patterns)
6169detection:rule_eval:1: packet 4 UNK 10.1.1.2:200 10.2.1.1:100 (fast-patterns)
6170detection:rule_eval:1: Fast pattern processing - no matches found
6171detection:rule_eval:1: packet 4 UNK 10.1.1.2:200 10.2.1.1:100 (non-fast-patterns)
6172
6173The trace messages for two last packets (numbers 5 and 6) weren’t
6174printed.
6175
61765.19.11. Example - configuring traces via trace.set() command
6177
6178In snort.lua, the following lines were added:
6179
6180ips =
6181{
6182    rules =
6183    [[
6184        alert tcp any any -> any any ( msg: "ALERT_TCP"; gid: 1001; sid: 1001 )
6185        alert udp any any -> any any ( msg: "ALERT_UDP"; gid: 1002; sid: 1002 )
6186    ]]
6187}
6188
6189trace =
6190{
6191    constraints =
6192    {
6193        ip_proto = 17, -- udp
6194        dst_ip = "10.1.1.2",
6195        src_port = 100,
6196        dst_port = 200
6197    },
6198    modules =
6199    {
6200        detection = { rule_eval = 1 }
6201    }
6202}
6203
6204The processed traffic was next:
6205
6206# Flow 1
6207d ( stack="eth:ip4:udp" )
6208c ( ip4:a="10.1.1.1", ip4:b="10.1.1.2", udp:a=100, udp:b=200 )
6209a ( data="udp packet 1" )
6210a ( data="udp packet 2" )
6211
6212# Flow 2
6213d ( stack="eth:ip4:tcp" )
6214c ( ip4:a="10.1.1.3", ip4:b="10.1.1.4", tcp:a=5000, tcp:b=6000 )
6215a ( syn )
6216b ( syn, ack )
6217a ( ack )
6218a ( ack, data="tcp packet 1" )
6219a ( ack, data="tcp packet 2" )
6220a ( fin, ack )
6221b ( fin, ack )
6222
6223After 1 packet, entering shell and pass the trace.set() command as
6224follows:
6225
6226trace.set({ constraints = { ip_proto = 6, dst_ip = "10.1.1.4", src_port = 5000, dst_port = 6000 }, modules = { decode = { all = 1 }, detection = { rule_eval = 1 } } })
6227
6228The output (not full, only descriptive lines):
6229
6230detection:rule_eval:1: packet 1 UNK 10.1.1.1:100 10.1.1.2:200 (fast-patterns)
6231detection:rule_eval:1: packet 1 UNK 10.1.1.1:100 10.1.1.2:200 (non-fast-patterns)
6232decode:all:1: Codec udp (protocol_id: 256) ip header starts length is 8
6233decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6234detection:rule_eval:1: packet 3 UNK 10.1.1.3:5000 10.1.1.4:6000 (fast-patterns)
6235detection:rule_eval:1: packet 3 UNK 10.1.1.3:5000 10.1.1.4:6000 (non-fast-patterns)
6236decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6237detection:rule_eval:1: packet 4 UNK 10.1.1.4:6000 10.1.1.3:5000 (fast-patterns)
6238detection:rule_eval:1: packet 4 UNK 10.1.1.4:6000 10.1.1.3:5000 (non-fast-patterns)
6239decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6240detection:rule_eval:1: packet 5 UNK 10.1.1.3:5000 10.1.1.4:6000 (fast-patterns)
6241detection:rule_eval:1: packet 5 UNK 10.1.1.3:5000 10.1.1.4:6000 (non-fast-patterns)
6242decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6243detection:rule_eval:1: packet 6 UNK 10.1.1.3:5000 10.1.1.4:6000 (fast-patterns)
6244detection:rule_eval:1: packet 6 UNK 10.1.1.3:5000 10.1.1.4:6000 (non-fast-patterns)
6245decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6246detection:rule_eval:1: packet 7 UNK 10.1.1.3:5000 10.1.1.4:6000 (fast-patterns)
6247detection:rule_eval:1: packet 7 UNK 10.1.1.3:5000 10.1.1.4:6000 (non-fast-patterns)
6248decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6249detection:rule_eval:1: packet 8 UNK 10.1.1.3:5000 10.1.1.4:6000 (fast-patterns)
6250detection:rule_eval:1: packet 8 UNK 10.1.1.3:5000 10.1.1.4:6000 (non-fast-patterns)
6251decode:all:1: Codec tcp (protocol_id: 256) ip header starts length is 20
6252detection:rule_eval:1: packet 9 UNK 10.1.1.4:6000 10.1.1.3:5000 (fast-patterns)
6253detection:rule_eval:1: packet 9 UNK 10.1.1.4:6000 10.1.1.3:5000 (non-fast-patterns)
6254
6255The new configuration was applied. decode:all:1 messages aren’t
6256filtered because they don’t include a packet (a packet isn’t
6257well-formed at the point when the message is printing).
6258
62595.19.12. Other available traces
6260
6261There are more trace options supported by detection:
6262
6263detect_engine - prints statistics about the engine
6264pkt_detect - prints a message when disabling content detect for packet
6265opt_tree - prints option tree data structure
6266tag - prints a message when a new tag is added
6267
6268The rest support only 1 option, and can be turned on by adding all =
62691 to their table in trace lua config.
6270
6271  * stream module trace:
6272
6273When turned on prints a message in case inspection is stopped on a
6274flow. Example for output:
6275
6276stream:all:1: stop inspection on flow, dir BOTH
6277
6278  * stream_ip, stream_user: trace will output general processing
6279    messages
6280
6281Other modules that support trace have messages as seemed fit to the
6282developer. Some are for corner cases, others for complex data
6283structures.
6284
6285
62865.20. Wizard
6287
6288--------------
6289
6290Using the wizard enables port-independent configuration and the
6291detection of malware command and control channels. If the wizard is
6292bound to a session, it peeks at the initial payload to determine the
6293service. For example, GET would indicate HTTP and HELO would indicate
6294SMTP. Upon finding a match, the service bindings are reevaluated so
6295the session can be handed off to the appropriate inspector. The
6296wizard is still under development; if you find you need to tweak the
6297defaults please let us know.
6298
62995.20.1. Wizard patterns
6300
6301Wizard supports 3 kinds of patterns:
6302
6303 1. Hexes
6304 2. Spells
6305 3. Curses
6306
6307Each kind of pattern has its own purpose and features. It should be
6308noted that the types of patterns are evaluated exactly in the order
6309in which they are described above. Thus, if some data matches a hex,
6310it will not be processed by spells and curses.
6311
6312The depth of search for a pattern in the data can be configured using
6313the max_search_depth option
6314
6315TCP packets form a flow, so wizard checks all data in the flow for a
6316match. If no pattern matches and max_search_depth is reached, the
6317flow is abandoned by wizard.
6318
6319UDP packets form a "meta-flow" based on the addresses and ports of
6320the packets. However, unlike TCP processing, for UDP wizard only
6321looks at the first arriving packet from the meta-flow. If no pattern
6322matches that packet or wizard’s max_search_depth is reached, the
6323meta-flow is abandoned by wizard.
6324
63255.20.2. Wizard patterns - Spells
6326
6327Spell is a text based pattern. The best area of usage - text
6328protocols: http, smtp, sip, etc. Spells are:
6329
6330  * Case insensitive
6331  * Whitespace sensitive
6332  * Able to match by a wildcard symbol
6333
6334In order to match any sequence of characters in pattern, you should
6335use "*" (glob) symbol in pattern.
6336
6337Example:
6338  Pattern: '220-*FTP'
6339  Traffic that would match: '220- Hello world! It's a new FTP server'
6340
6341To escape "*" symbol, put "**" in the pattern.
6342
6343Spells are configured as a Lua array, each element of which can
6344contain following options:
6345
6346  * service - name of the service that would be assigned
6347  * proto - protocol to scan
6348  * client_first - indicator of which end initiates data transfer
6349  * to_server - list of text patterns to search in the data sent to
6350    the client
6351  * to_client - list of text patterns to search in the data sent to
6352    the server
6353
6354    Example of a spell definition in Lua:
6355      {
6356        service = 'smtp',
6357        proto = 'tcp',
6358        client_first = true,
6359        to_server = { 'HELO', 'EHLO' },
6360        to_client = { '220*SMTP', '220*MAIL' }
6361      }
6362
63635.20.3. Wizard patterns - Hexes
6364
6365Hexes can be used to match binary protocols: dnp3, http2, ssl, etc.
6366Hexes use hexadecimal representation of the data for pattern
6367matching.
6368
6369Wildcard in hex pattern is a placeholder for exactly one occurrence
6370of any hexadecimal digit and denoted by the symbol "?".
6371
6372Example:
6373  Pattern: '|05 ?4|'
6374  Traffic that would match: '|05 84|'
6375
6376Hexes are configured in the same way as spells and have an identical
6377set of options.
6378
6379Example of a hex definition in Lua:
6380  {
6381    service = 'dnp3',
6382    proto = 'tcp',
6383    client_first = true,
6384    to_server = { '|05 64|' },
6385    to_client = { '|05 64|' }
6386  }
6387
63885.20.4. Wizard patterns - Curses
6389
6390Curses are internal algorithms of service identification. They are
6391implemented as state machines in C++ code and can have their own
6392unique state information stored on the flow.
6393
6394A list of available services can be obtained using snort
6395--help-config wizard | grep curses.
6396
6397A configuration which enables some curses:
6398  curses = {'dce_udp', 'dce_tcp', 'dce_smb', 'sslv2'}
6399
64005.20.5. Additional Details:
6401
6402  * Note that usually more specific patterns have higher precedence.
6403
6404    For example:
6405      The following spells against 'foobar' payload. The 3rd spell matches.
6406        { service = 'first',  to_server = { 'foo' } },
6407        { service = 'second',  to_server = { 'bar' } }
6408        { service = 'third',  to_server = { 'foobar' } }
6409
6410  * If the wizard and one or more service inspectors are configured w
6411    /o explicitly configuring the binder, default bindings will be
6412    generated which should work for most common cases.
6413  * Also note that while Snort 2 bindings can only be configured in
6414    the default policy, each Snort 3 policy can contain a binder
6415    leading to an arbitrary hierarchy.
6416  * The entire configuration can be reloaded and hot-swapped during
6417    run-time via signal or command in both Snort 2 and Snort 3.
6418    Ultimately, Snort 3 will support commands to update the binder on
6419    the fly, thus enabling incremental reloads of individual
6420    inspectors.
6421  * Both Snort 2 and Snort 3 support server specific configurations
6422    via a hosts table (XML in Snort 2 and Lua in Snort 3). The table
6423    allows you to map network, protocol, and port to a service and
6424    policy. This table can be reloaded and hot-swapped separately
6425    from the config file.
6426  * You can find the specifics on the binder, wizard, and hosts
6427    tables in the manual or command line like this: snort
6428    --help-module binder, etc.
6429
6430
6431---------------------------------------------------------------------
6432
64336. DAQ Configuration and Modules
6434
6435---------------------------------------------------------------------
6436
6437The Data AcQuisition library (DAQ), provides pluggable packet I/O.
6438LibDAQ replaces direct calls to libraries like libpcap with an
6439abstraction layer that facilitates operation on a variety of hardware
6440and software interfaces without requiring changes to Snort. It is
6441possible to select the DAQ module and mode when invoking Snort to
6442perform pcap readback or inline operation, etc. The DAQ library may
6443be useful for other packet processing applications and the modular
6444nature allows you to build new modules for other platforms.
6445
6446The DAQ library exists as a separate repository on the official Snort
64473 GitHub project (https://github.com/snort3/libdaq) and contains a
6448number of bundled DAQ modules including AFPacket, Divert, NFQ, PCAP,
6449and Netmap implementations. Snort 3 itself contains a few new DAQ
6450modules mostly used for testing as described below. Additionally, DAQ
6451modules developed by third parties to facilitate the usage of their
6452own hardware and software platforms exist.
6453
6454
64556.1. Building the DAQ Library and Its Bundled DAQ Modules
6456
6457--------------
6458
6459Refer to the READMEs in the LibDAQ source tarball for instructions on
6460how to build the library and modules as well as details on
6461configuring and using the bundled DAQ modules.
6462
6463
64646.2. Configuration
6465
6466--------------
6467
6468As with a number of features in Snort 3, the LibDAQ and DAQ module
6469configuration may be controlled using either the command line options
6470or by configuring the daq Snort module in the Lua configuration.
6471
6472DAQ modules may be statically built into Snort, but the more common
6473case is to use DAQ modules that have been built as dynamically
6474loadable objects. Because of this, the first thing to take care of is
6475informing Snort of any locations it should search for dynamic DAQ
6476modules. From the command line, this can be done with one or more
6477invocations of the --daq-dir option, which takes a colon-separated
6478set of paths to search as its argument. All arguments will be
6479collected into a list of locations to be searched. In the Lua
6480configuration, the daq.module_dirs[] property is a list of paths for
6481the same purpose.
6482
6483Next, one must select which DAQ modules they wish to use by name. At
6484least one base module and zero or more wrapper modules may be
6485selected. This is done using the --daq options from the command line
6486or the daq.modules[] list-type property. To get a list of the
6487available modules, run Snort with the --daq-list option making sure
6488to specify any DAQ module search directories beforehand. If no DAQ
6489module is specified, Snort will default to attempting to find and use
6490a DAQ module named pcap.
6491
6492Some DAQ modules can be further directly configured using DAQ module
6493variables. All DAQ module variables come in the form of either just a
6494key or a key and a value separated by an equals sign. For example,
6495debug or fanout_type=hash. The command line option for specifying
6496these is --daq-var and the configuration file equivalent is the
6497daq.modules[].variables[] property. The available variables for each
6498module will be shown when listing the available DAQ modules with
6499--daq-list.
6500
6501The LibDAQ concept of operational mode (passive, inline, or file
6502readback) is automatically configured based on inferring the mode
6503from other Snort configuration. The presence of -r or --pcap-*
6504options implies read-file, -i without -Q implies passive, and -i with
6505-Q implies inline. The mode can be overridden on a per-DAQ module
6506basis with the --daq-mode option on the command line or the
6507daq.modules[].mode property.
6508
6509The DAQ module receive timeout is always configured to 1 second. The
6510packet capture length (snaplen) defaults to 1518 bytes and can be
6511overridden by the -s command line option or daq.snaplen property.
6512
6513Finally, and most importantly, is the input specification for the DAQ
6514module. In readback mode, this is simply the file to be read back and
6515analyzed. For live traffic processing, this is the name of the
6516interface or other necessary input specification as required by the
6517DAQ module to understand what to operate upon. From the command line,
6518the -r option is used to specify a file to be read back and the -i
6519option is used to indicate a live interface input specification. Both
6520are covered by the daq.inputs[] property.
6521
6522For advanced use cases, one additional LibDAQ configuration exists:
6523the number of DAQ messages to request per receive call. In Snort,
6524this is referred to as the DAQ "batch size" and defaults to 64. The
6525default can be overridden with the --daq-batch-size command line
6526option or daq.batch_size property. The message pool size requested
6527from the DAQ module will be four times this batch size.
6528
65296.2.1. Command Line Example
6530
6531    snort --daq-dir /usr/local/lib/daq --daq-dir /opt/lib/daq --daq afpacket
6532--daq-var debug --daq-var fanout_type=hash -i eth1:eth2 -Q
6533
65346.2.2. Configuration File Example
6535
6536The following is the equivalent of the above command line DAQ
6537configuration in Lua form:
6538
6539daq =
6540{
6541    module_dirs =
6542    {
6543        '/usr/local/lib/daq',
6544        '/opt/lib/daq'
6545    },
6546    modules =
6547    {
6548        {
6549            name = 'afpacket',
6550            mode = 'inline',
6551            variables =
6552            {
6553                'debug',
6554                'fanout_type=hash'
6555            }
6556        }
6557    },
6558    inputs =
6559    {
6560        'eth1:eth2',
6561    },
6562    snaplen = 1518
6563}
6564
6565The daq.snaplen property was included for completeness and may be
6566omitted if the default value is acceptable.
6567
65686.2.3. DAQ Module Configuration Stacks
6569
6570Like briefly mentioned above, a DAQ configuration consists of a base
6571DAQ module and zero or more wrapper DAQ modules. DAQ wrapper modules
6572provide additional functionality layered on top of the base module in
6573a decorator pattern. For example, the Dump DAQ module will capture
6574all passed or injected packets and save them to a PCAP savefile. This
6575can be layered on top of something like the PCAP DAQ module to assess
6576which packets are making it through Snort without being dropped and
6577what actions Snort has taken that involved sending new or modified
6578packets out onto the network (e.g., TCP reset packets and TCP
6579normalizations).
6580
6581To configure a DAQ module stack from the command line, the --daq
6582option must be given multiple times with the base module specified
6583first followed by the wrapper modules in the desired order (building
6584up the stack). Each --daq option changes which module is being
6585configured by subsequent --daq-var and --daq mode options.
6586
6587When configuring the same sort of stack in Lua, everything lives in
6588the daq.modules[] property. daq.modules[] is an array of module
6589configurations pushed onto the stack from top to bottom. Each module
6590configuration must contain the name of the DAQ module. Additionally,
6591it may contain an array of variables (daq.modules[].variables[]) and/
6592or an operational mode (daq.modules[].mode).
6593
6594If only wrapper modules were specified, Snort will default to
6595implicitly configuring a base module with the name pcap in read-file
6596mode. This is a convenience to mimic the previous behavior when
6597selecting something like the old Dump DAQ module that may be removed
6598in the future.
6599
6600For any particularly complicated setup, it is recommended that one
6601configure via a Lua configuration file rather than using the command
6602line options.
6603
6604
66056.3. Interaction With Multiple Packet Threads
6606
6607--------------
6608
6609All packet threads will receive the same DAQ instance configuration
6610with the potential exception of the input specification.
6611
6612If Snort is in file readback mode, a full set of files will be
6613constructed from the -r/--pcap-file/--pcap-list/--pcap-dir/
6614--pcap-filter options. A number of packet threads will be started up
6615to the configured maximum (-z) to process these files one at a time.
6616As a packet thread completes processing of a file, it will be stopped
6617and then started again with a different file input to process. If the
6618number of packet threads configured exceeds the number of files to
6619process, or as the number of remaining input files dwindles below
6620that number, Snort will stop spawning new packet threads when it runs
6621out of unhandled input files.
6622
6623When Snort is operating on live interfaces (-i), all packet threads
6624up to the configured maximum will always be started. By default, if
6625only one input specification is given, all packet threads will
6626receive the same input in their configuration. If multiple inputs are
6627given, each thread will be given the matching input (ordinally),
6628falling back to the first if the number of packet threads exceeds the
6629number of inputs.
6630
6631
66326.4. DAQ Modules Included With Snort 3
6633
6634--------------
6635
66366.4.1. Socket Module
6637
6638The socket module provides provides a stream socket server that will
6639accept up to 2 simultaneous connections and bridge them together
6640while also passing data to Snort for inspection. The first connection
6641accepted is considered the client and the second connection accepted
6642is considered the server. If there is only one connection, stream
6643data can’t be forwarded but it is still inspected.
6644
6645Each read from a socket of up to snaplen bytes is passed as a packet
6646to Snort along with the ability to retrieve a DAQ_UsrHdr_t structure
6647via ioctl. DAQ_UsrHdr_t conveys IP4 address, ports, protocol, and
6648direction. Socket packets can be configured to be TCP or UDP. The
6649socket DAQ can be operated in inline mode and is able to block
6650packets.
6651
6652Packets from the socket DAQ module are handled by Snort’s stream_user
6653module, which must be configured in the Snort configuration.
6654
6655To use the socket DAQ, start Snort like this:
6656
6657./snort --daq-dir /path/to/lib/snort_extra/daq \
6658    --daq socket [--daq-var port=<port>] [--daq-var proto=<proto>] [-Q]
6659
6660<port> ::= 1..65535; default is 8000
6661<proto> ::= tcp | udp
6662
6663  * This module only supports ip4 traffic.
6664  * This module is only supported by Snort 3. It is not compatible
6665    with Snort 2.
6666  * This module is primarily for development and test.
6667
66686.4.2. File Module
6669
6670The file module provides the ability to process files directly
6671without having to extract them from pcaps. Use the file module with
6672Snort’s stream_file to get file type identification and signature
6673services. The usual IPS detection and logging, etc. is also
6674available.
6675
6676You can process all the files in a directory recursively using 8
6677threads with these Snort options:
6678
6679--pcap-dir path -z 8
6680
6681  * This module is only supported by Snort 3. It is not compatible
6682    with Snort 2.
6683  * This module is primarily for development and test.
6684
66856.4.3. Hext Module
6686
6687The hext module generates packets suitable for processing by Snort
6688from hex/plain text. Raw packets include full headers and are
6689processed normally. Otherwise the packets contain only payload and
6690are accompanied with flow information (4-tuple) suitable for
6691processing by stream_user.
6692
6693The first character of the line determines it’s purpose:
6694
6695'$' command
6696'#' comment
6697'"' quoted string packet data
6698'x' hex packet data
6699' ' empty line separates packets
6700
6701The available commands are:
6702
6703$client <ip4> <port>
6704$server <ip4> <port>
6705
6706$packet -> client
6707$packet -> server
6708
6709$packet <addr> <port> -> <addr> <port>
6710
6711$sof <i32:ingressZone> <i32:egressZone> <i32:ingressIntf> <i32:egressIntf> <s:srcIp> <i16:srcPort> <s:destIp> <i16:dstPort> <u32:opaque> <u64:initiatorPkts> <u64:responderPkts> <u64:initiatorPktsDropped> <u64:responderPktsDropped> <u64:initiatorBytesDropped> <u64:responderBytesDropped> <u8:isQosAppliedOnSrcIntf> <timeval:sof_timestamp> <timeval:eof_timestamp> <u16:vlan> <u16:address_space_id> <u8:protocol>
6712$eof <i32:ingressZone> <i32:egressZone> <i32:ingressIntf> <i32:egressIntf> <s:srcIp> <i16:srcPort> <s:destIp> <i16:dstPort> <u32:opaque> <u64:initiatorPkts> <u64:responderPkts> <u64:initiatorPktsDropped> <u64:responderPktsDropped> <u64:initiatorBytesDropped> <u64:responderBytesDropped> <u8:isQosAppliedOnSrcIntf> <timeval:sof_timestamp> <timeval:eof_timestamp> <u16:vlan> <u16:address_space_id> <u8:protocol>
6713
6714Client and server are determined as follows. $packet → client
6715indicates to the client (from server) and $packet → server indicates
6716a packet to the server (from client). $packet followed by a 4-tuple
6717uses the heuristic that the client is the side with the greater port
6718number.
6719
6720The default client and server are 192.168.1.1 12345 and 10.1.2.3 80
6721respectively. $packet commands with a 4-tuple do not change client
6722and server set with the other $packet commands.
6723
6724$packet commands should be followed by packet data, which may contain
6725any combination of hex and strings. Data for a packet ends with the
6726next command or a blank line. Data after a blank line will start
6727another packet with the same tuple as the prior one.
6728
6729$sof and $eof commands generate Start of Flow and End of Flow
6730metapackets respectively. They are followed by a definition of a
6731DAQ_FlowStats_t data structure which will be fed into Snort via the
6732metadata callback.
6733
6734Strings may contain the following escape sequences:
6735
6736\r = 0x0D = carriage return
6737\n = 0x0A = new line
6738\t = 0x09 = tab
6739\\ = 0x5C = \
6740
6741Format your input carefully; there is minimal error checking and
6742little tolerance for arbitrary whitespace. You can use Snort’s -L
6743hext option to generate hext input from a pcap.
6744
6745  * This module only supports ip4 traffic.
6746  * This module is only supported by Snort 3. It is not compatible
6747    with Snort 2.
6748  * This module is primarily for development and test.
6749
6750The hext DAQ also supports a raw mode which is activated by setting
6751the data link type. For example, you can input full ethernet packets
6752with --daq-var dlt=1 (Data link types are defined in the DAQ include
6753sfbpf_dlt.h.) Combine that with the hext logger in raw mode for a
6754quick (and dirty) way to edit pcaps. With --lua "log_hext = { raw =
6755true }", the hext logger will dump the full packet in a way that can
6756be read by the hext DAQ in raw mode. Here is an example:
6757
6758# 3 [96]
6759
6760x02 09 08 07 06 05 02 01 02 03 04 05 08 00 45 00 00 52 00 03  # ..............E..R..
6761x00 00 40 06 5C 90 0A 01 02 03 0A 09 08 07 BD EC 00 50 00 00  # ..@.\............P..
6762x00 02 00 00 00 02 50 10 20 00 8A E1 00 00 47 45 54 20 2F 74  # ......P.  .....GET /t
6763x72 69 67 67 65 72 2F 31 20 48 54 54 50 2F 31 2E 31 0D 0A 48  # rigger/1 HTTP/1.1..H
6764x6F 73 74 3A 20 6C 6F 63 61 6C 68 6F 73 74 0D 0A              # ost: localhost..
6765
6766A comment indicating packet number and size precedes each packet
6767dump. Note that the commands are not applicable in raw mode and have
6768no effect.
6769
6770