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