Snort User Manual
Snort User Manual
Snort User Manual
REVISION HISTORY
Contents
1 Overview 1
1.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Plugins and Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 New Http Inspector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 Binder and Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 Packet Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Getting Started 6
2.1 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Building . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.6 Common Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 Gotchas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.8 Bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.8.1 Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.8.2 Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.8.3 Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.8.4 snort2lua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.8.5 Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 Basic Modules 13
3.1 active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 attribute_table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 classifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.5 daq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.6 decode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.7 detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.8 event_filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.9 event_queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.10 file_id . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.11 host_tracker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.12 hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.13 ips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Snort++ User Manual iv
3.14 network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.15 output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.16 packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.17 ppm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.18 process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.19 profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.20 rate_filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.21 references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.22 rule_state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.23 search_engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.24 snort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.25 suppress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4 Codec Modules 27
4.1 arp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.2 auth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.3 eapol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.4 erspan2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.5 erspan3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.6 esp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.7 eth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.8 fabricpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.9 gre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.10 gtp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.11 icmp4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.12 icmp6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.13 igmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.14 ipv4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.15 ipv6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.16 mpls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.17 pgm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.18 pppoe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.19 tcp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.20 token_ring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.21 udp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.22 vlan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.23 wlan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Snort++ User Manual v
5 Inspector Modules 36
5.1 arp_spoof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.2 back_orifice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.3 binder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.4 data_log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.5 dce_smb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.6 dce_tcp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.7 dnp3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.8 dns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.9 dpx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.10 ftp_client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.11 ftp_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.12 ftp_server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.13 gtp_inspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.14 http_global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.15 http_inspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.16 imap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.17 modbus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.18 new_http_inspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.19 normalizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.20 perf_monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.21 pop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.22 port_scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.23 port_scan_global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.24 reputation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.25 rpc_decode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.26 sip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.27 smtp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.28 ssh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.29 ssl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.30 stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.31 stream_file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
5.32 stream_icmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.33 stream_ip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.34 stream_tcp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.35 stream_udp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.36 stream_user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.37 telnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.38 wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Snort++ User Manual vi
7.34 http_raw_cookie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.35 http_raw_header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.36 http_raw_uri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.37 http_stat_code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.38 http_stat_msg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.39 http_uri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.40 icmp_id . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.41 icmp_seq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.42 icode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.43 id . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.44 ip_proto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.45 ipopts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.46 isdataat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.47 itype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.48 md5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.49 metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.50 modbus_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.51 modbus_func . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.52 modbus_unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.53 msg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.54 pcre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.55 pkt_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.56 pkt_num . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.57 priority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.58 raw_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.59 reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.60 regex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.61 rem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.62 replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.63 rev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.64 rpc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.65 seq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.66 session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.67 sha256 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.68 sha512 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.69 sid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.70 sip_body . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.71 sip_header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.72 sip_method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Snort++ User Manual viii
7.73 sip_stat_code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.74 so . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.75 soid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.76 ssl_state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.77 ssl_version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.78 stream_reassemble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.79 stream_size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.80 tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.81 tos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.82 ttl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.83 urg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.84 window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
9 SO Rule Modules 91
10 Logger Modules 91
10.1 alert_csv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
10.2 alert_ex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
10.3 alert_fast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.4 alert_full . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.5 alert_syslog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.6 alert_unixsock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.7 log_codecs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.8 log_hext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.9 log_pcap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.10unified2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
11 DAQ Modules 93
11.1 Building the DAQ Library and DAQ Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
11.2 PCAP Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
11.3 AFPACKET Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
11.4 NFQ Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
11.5 IPQ Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
11.6 IPFW Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
11.7 Dump Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
11.8 Netmap Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
11.8.1 FreeBSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
11.8.2 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Snort++ User Manual ix
13 Snort2Lua 107
13.1 Snort2Lua Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
13.1.1 Usage: snort2lua [OPTIONS]. . . -c <snort_conf> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Options: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Required option: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Default values: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
13.2 Known Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
13.3 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
16 Reference 125
16.1 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
16.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
16.2.1 Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
16.2.2 Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
16.2.3 Sniffing and Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
16.2.4 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
16.2.5 IDS mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
16.3 Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
16.4 Output Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
16.4.1 DAQ Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
16.4.2 Logger Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
16.4.3 Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
16.4.4 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
16.5 Optional Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
16.6 Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
16.7 Command Line Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
16.8 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
16.9 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
16.10Counts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
16.11Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
16.12Builtin Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
16.13Command Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
16.14Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
16.15Configuration Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
16.16Module Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
16.16.1 Plugin Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Snort++ User Manual 1 / 204
1 Overview
Snort++ is an updated version of the Snort IPS (intrusion prevention system). This document assumes you have some familiarity
with Snort and are looking to see what Snort++ has to offer. Here are some of the basic goals for Snort++:
The above goals are met with this first alpha release. Additional, longer-term goals are:
This first alpha release is based on Snort 2.9.6-9 and excludes all but one of Snort’s dynamic preprocessors. Work is underway
to port that functionality and additions will be rolled out as they become available.
1.1 Configuration
Note that retaining backwards compatibility is not a goal. While Snort++ leverages some of the Snort code base, a lot has
changed. The configuration of Snort++ is done with Lua, so your old conf won’t work as is. Rules are still text based but
nonetheless incompatible. However, Snort2Lua will help you convert your conf and rules to the new format.
The original Snort manual may be useful for some background information not yet documented for Snort++. The configuration
differences are given in this manual.
1.2 Modules
Snort++ is organized into a collection of builtin and plugin modules. If a module has parameters, it is configured by a Lua table
of the same name. For example, we can see what the active module has to offer with this command:
$ snort --help-module active
Type: basic
Configuration:
string active.device: use ’ip’ for network layer responses or ’eth0’ etc
for link layer
This says active is a basic module that has several parameters. For each, you will see:
type module.name = default: help { range }
For example, the active module has a max_responses parameter that takes non-negative integer values and defaults to zero. We
can change that in Lua as follows:
Snort++ User Manual 3 / 204
active = { max_responses = 1 }
or:
active = { }
active.max_responses = 1
Most plugins can be built statically or dynamically. By default they are all static. There is no difference in functionality between
static or dynamic plugins but the dynamic build generates a slightly lighter weight binary. Either way you can add dynamic
plugins with --plugin-path and newer versions will replace older versions, even when built statically.
The power of plugins is that they have a very focused purpose and can be created with relative ease. For example, you can extend
the rule language by writing your own IpsOption and it will plug in and function just like existing options. The extra directory
has examples of each type of plugin.
Some things just need to be tweaked or prototyped quickly. In addition to the Lua conf, which is a script that can contain
functions to compute settings, etc., you can also script Loggers and IpsOptions.
One of the major undertakings for Snort 3.0 is developing a completely new HTTP inspector. It is incomplete right now but you
can examine the work-in-progress. You can configure it by adding:
new_http_inspect = {}
to your snort.lua configuration file. Or you can read it in the source code under src/service_inspectors/nhttp_inspect.
The classic HTTP preprocessor is still available in the alpha release as http_inspect. It’s probably the better choice for now if you
just want to do some work and do not feel like experimenting. Be sure not to configure both old and new HTTP inspectors at the
same time.
So why a new HTTP inspector?
For starters it is object-oriented. That’s good for us because we maintain this software. But it should also be really nice for
open-source developers. You can make meaningful changes and additions to HTTP processing without having to understand the
whole thing. In fact much of the new HTTP inspector’s knowledge of HTTP is centralized in a series of tables where it can be
easily reviewed and modified. Many significant changes can be made just by updating these tables.
Snort++ User Manual 4 / 204
New_http_inspect is the first inspector written specifically for the new Snort 3.0 architecture. That provides access to one of the
very best features of Snort 3.0: purely PDU-based inspection. Classic http_inspect processes HTTP messages, but even while
doing so it is constantly aware of IP packets and how they divide up the TCP data stream. The same HTTP message might be
processed differently depending on how the sender (bad guy) divided it up into IP packets.
New_http_inspect is free of this burden and can focus exclusively on HTTP. That makes it much more simple, easier to test,
and less prone to false positives. It also greatly reduces the opportunity for adversaries to probe the inspector for weak spots by
adjusting packet boundaries to disguise bad behavior.
Dealing solely with HTTP messages also opens the door for developing major new features. The new_http_inspect design
supports true stateful processing. Want to ask questions that involve both the client request and the server response? Or different
requests in the same session? These things are possible.
Another new feature on the horizon is HTTP/2 analysis. HTTP/2 derives from Google’s SPDY project and is in the process
of being standardized. Despite the name, it is better to think of HTTP/2 not as a newer version of HTTP/1.1, but rather a
separate protocol layer that runs under HTTP/1.1 and on top of TLS or TCP. It’s a perfect fit for the new Snort 3.0 architecture
because a new HTTP/2 inspector would naturally output HTTP/1.1 messages but not any underlying packets. Exactly what the
new_http_inspect wants to input.
New_http_inspect is taking a very different approach to HTTP header fields. Classic http_inspect divides all the HTTP headers
following the start line into cookies and everything else. It normalizes the two pieces using a generic process and puts them in
buffers that one can write rules against. There is some limited support for examining individual headers within the inspector but
it is very specific.
The new concept is that every header should be normalized in an appropriate and specific way and individually made available
for the user to write rules against it. If for example a header is supposed to be a date then normalization means put that date in a
standard format.
One of the fundamental differences between Snort and Snort++ concerns configuration related to networks and ports. Here is a
brief review of Snort’s configuration for network and service related components:
• Snort’s configuration has a default policy and optional policies selected by VLAN or network (with config binding).
• Each policy contains a user defined set of preprocessor configurations.
• Each preprocessor has a default configuration and some support non-default configurations selected by network.
• Most preprocessors have port configurations.
• The default policy may also contain a list of ports to ignore.
In Snort++, the above configurations are done in a single module called the binder. Here is an example:
binder =
{
-- allow all tcp port 22:
-- (similar to snort 2.X config ignore_ports)
{ when = { proto = ’tcp’, ports = ’22’ }, use = { action = ’allow’ } },
Bindings are evaluated when a session starts and again if and when service is identified on the session. Essentially, the bindings
are a list of when-use rules evaluated from top to bottom. The first matching network and service configurations are applied.
binder.when can contain any combination of criteria and binder.use can specify an action, config file, or inspector configuration.
Using the wizard enables port-independent configuration and the detection of malware command and control channels. If the
wizard is bound to a session, it peeks at the initial payload to determine the service. For example, GET would indicate HTTP
and HELO would indicate SMTP. Upon finding a match, the service bindings are reevaluated so the session can be handed off to
the appropriate inspector. The wizard is still under development; if you find you need to tweak the defaults please let us know.
Additional Details:
• If the wizard and one or more service inspectors are configured w/o explicitly configuring the binder, default bindings will be
generated which should work for most common cases.
• Also note that while Snort 2.X bindings can only be configured in the default policy, each Snort 3.0 policy can contain a binder
leading to an arbitrary hierarchy.
• The entire configuration can be reloaded and hot-swapped during run-time via signal or command in both Snort 2.X and 3.0.
Ultimately, Snort 3.0 will support commands to update the binder on the fly, thus enabling incremental reloads of individual
inspectors.
• Both Snort 2.X and 3.0 support server specific configurations via a hosts table (XML in Snort 2.X and Lua in Snort 3.0).
The table allows you to map network, protocol, and port to a service and policy. This table can be reloaded and hot-swapped
separately from the config file.
• You can find the specifics on the binder, wizard, and hosts tables in the manual or command line like this: snort --help-module
binder, etc.
One of the goals of Snort++ is to provide a more flexible framework for packet processing by implementing an event-driven
approach. Another is to produce data only when needed, to minimize expensive normalizations. To help explain these concepts,
let’s start by examining how Snort processes packets. The key steps are given in the following figure:
The preprocess step is highly configurable. Arbitrary preprocessors can be loaded dynamically at startup, configured in snort.conf,
and then executed at runtime. Basically, the preprocessors are put into a list which is iterated for each packet. Recent versions
have tweaked the list handling some, but the same basic architecture has allowed Snort to grow from a sniffer, with no prepro-
cessing, to a full-fledged IPS, with lots of preprocessing.
While this "list of plugins" approach has considerable flexibility, it hampers future development when the flow of data from one
preprocessor to the next depends on traffic conditions, a common situation with advanced features like application identification.
In this case, a preprocessor like HTTP may be extracting and normalizing data that ultimately is not used, or app ID may be
repeatedly checking for data that is just not available.
Snort++ User Manual 6 / 204
Callbacks help break out of the preprocess straightjacket. This is where one preprocessor supplies another with a function to call
when certain data is available. Snort has started to take this approach to pass some HTTP and SIP preprocessor data to app ID.
However, it remains a peripheral feature and still requires the production of data that may not be consumed.
The basic processing steps Snort++ takes are similar to Snort’s as seen in the following diagram. The preprocess step employs
specific inspector types instead of a generalized list, but the basic procedure includes stateless packet decoding, TCP stream
reassembly, and service specific analysis in both cases. (Snort++ provides hooks for arbitrary inspectors, but they are not central
to basic flow processing and are not shown.)
However, Snort++ also provides a more flexible mechanism than callback functions. By using inspection events, it is possible for
an inspector to supply data that other inspectors can process. This is known as the observer pattern or publish-subscribe pattern.
Note that the data is not actually published. Instead, access to the data is published, and that means that subscribers can access
the raw or normalized version(s) as needed. Normalizations are done only on the first access, and subsequent accesses get the
previously normalized data. This results in just in time (JIT) processing.
A basic example of this in action is provided by the extra data_log plugin. It is a passive inspector, ie it does nothing until it
receives the data it subscribed for (other in the above diagram). By adding data_log = { key = http_raw_uri } to your snort.lua
configuration, you will get a simple URI logger.
Inspection events coupled with pluggable inspectors provide a very flexible framework for implementing new features. And
JIT buffer stuffers allow Snort++ to work smarter, not harder. These capabilities will be leveraged more and more as Snort++
development continues.
2 Getting Started
2.1 Dependencies
Required:
Optional:
• lzma >= 5.1.2 from http://tukaani.org/xz/ for decompression of SWF and PDF files
• openssl from https://www.openssl.org for SHA and MD5 file signatures and the protected_content rule option
• hyperscan from https://github.com/01org/hyperscan to build new and improved regex and (coming soon) fast pattern support
• cpputest from http://cpputest.github.io to run additional unit tests with make check
• asciidoc from http://www.methods.co.nz/asciidoc/ to build the HTML manual
• dblatex from http://dblatex.sourceforge.net to build the pdf manual (in addition to asciidoc)
• w3m from http://sourceforge.net/projects/w3m/ to build the plain text manual
• source-highlight from http://www.gnu.org/software/src-highlite/ to generate the dev guide
2.2 Building
a. To build with autotools, simply do the usual from the top level directory:
./configure --prefix=$my_path
make -j 8
make install
b. To build with cmake and make, run configure_cmake.sh. It will automatically create and populate a new subdirectory
named build.
./configure_cmake.sh --prefix=$my_path
cd build
make -j 8
make install
ln -s $my_path/conf $my_path/etc
d. Or use ccmake directly to configure and generate from an arbitrary build directory like one of these:
Snort++ User Manual 8 / 204
2.3 Run
• Run IDS mode. To keep it brief, look at the first n packets in each file:
$my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample. ←-
rules \
-r <pcap> -A alert_test -n 100000
2.4 Tips
One of the goals of Snort++ is to make it easier to configure your sensor. Here is a summary of tips and tricks you may find
useful.
General Use
• Snort tries hard not to error out too quickly. It will report multiple semantic errors.
• Snort always assumes the simplest mode of operation. Eg, you can omit the -T option to validate the conf if you don’t provide
a packet source.
• Warnings are not emitted unless --warn-* is specified. --warn-all enables all warnings, and --pedantic makes such warnings
fatal.
• You can process multiple sources at one time by using the -z or --max-threads option.
• To make it easy to find the important data, zero counts are not output at shutdown.
• Load plugins from the command line with --plugin-path /path/to/install/lib.
• You can process multiple sources at one time by using the -z or --max-threads option.
• Unit tests are configured with --enable-unit-tests. They can then be run with snort --catch-test [tags]|all.
Lua Configuration
• Configure the wizard and default bindings will be created based on configured inspectors. No need to explicitly bind ports in
this case.
• You can override or add to your Lua conf with the --lua command line option.
• The Lua conf is a live script that is executed when loaded. You can add functions, grab environment variables, compute values,
etc.
• You can also rename symbols that you want to disable. For example, changing normalizer to Xnormalizer (an unknown
symbol) will disable the normalizer. This can be easier than commenting in some cases.
• By default, symbols unknown to Snort++ are silently ignored. You can generate warnings for them with --warn-unknown. To
ignore such symbols, export them in the environment variable SNORT_IGNORE.
• Like Snort, the # character starts a comment to end of line. In addition, all lines between #begin and #end are comments.
• The rem option allows you to write a comment that is conveyed with the rule.
• C style multi-line comments are allowed, which means you can comment out portions of a rule while testing it out by putting
the options between /* and */.
Output Files
To make it simple to configure outputs when you run with multiple packet threads, output files are not explicitly configured.
Instead, you can use the options below to format the paths:
<logdir>/[<run_prefix>][<id#>][<X>]<name>
2.5 Help
--help* and --list* options preempt other processing so should be last on the
command line since any following options are ignored. To ensure options like
--markup and --plugin-path take effect, place them ahead of the help or list
options.
require(’snort_config’)
PANIC: unprotected error in call to Lua API (cannot open snort_defaults.lua: No such file or directory)
• if xyz is the name of a module, make sure you are not assigning a scalar where a table is required (e.g. xyz = 2 should be xyz
= { }).
• module x does not have a parameter named y. check --help-module x for available parameters.
• the value z is out of range for x.y. check --help-config x.y for the range allowed.
• make sure that x = { } isn’t set later because it will override the earlier setting. same for x.y.
• if you any variables, you can squelch such warnings by setting them in an environment variable SNORT_IGNORE. to ignore
x, y, and z:
export SNORT_IGNORE="x y z"
2.7 Gotchas
• A nil key in a table will not caught. Neither will a nil value in a table. Neither of the following will cause errors, nor will they
actually set http_server.post_depth:
http_server = { post_depth }
http_server = { post_depth = undefined_symbol }
• It is not an error to set a value multiple times. The actual value applied may not be the last in the table either. It is best to avoid
such cases.
http_server =
{
post_depth = 1234,
post_depth = 4321
}
Snort++ User Manual 12 / 204
• Snort can’t tell you the exact filename or line number of a semantic error but it will tell you the fully qualified name.
• The dump DAQ will not work with multiple threads unless you use --daq-var file=/dev/null. This will be fixed in at some point
to use the Snort log directory, etc.
• Variables are currently processed in an order determined by the Lua hash table which is effectively random. That means you
will need to use Lua string concatenation to ensure Snort doesn’t try to use a variable before it is defined (even when it is
defined ahead of use in the file):
-- this may fail:
MY_SERVERS = [[ 172.20.0.0/16 172.21.0.0/16 ]]
EXTERNAL_NET = ’!$MY_SERVERS’
when you try to run src/snort, export DYLD_LIBRARY_PATH with the path to
libhs. You can also do:
2.8 Bugs
2.8.1 Build
• With cmake, make install will rebuild the docs even though when already built.
• Enabling large pcap may erroneously affect the number of packets processed from pcaps
• Enabling debug messages may erroneously affect the number of packets processed from pcaps
• g++ 4.9.2 with -O3 reports:
src/service_inspectors/back_orifice/back_orifice.cc:231:25: warning:
iteration 930u invokes undefined behavior [-Waggressive-loop-optimizations]
2.8.2 Config
• Parsing issue with IP lists. can’t parse rules with $EXTERNAL_NET defined as below because or the space between ! and 10.
HOME_NET = [[ 10.0.17.0/24 10.0.14.0/24 10.247.0.0/16 10.246.0.0/16 ]]
EXTERNAL_NET = ’! ’ .. HOME_NET
Snort++ User Manual 13 / 204
• Multiple versions of luajit scripts are not handled correctly. The first loaded version will always be executed even though
plugin manager saves the correct version.
• When using -c and -L together, the last on the command line wins (-c -L will dump; -L -c will analyze).
• Modules instantiated by command line only will not get default settings unless hard-coded. This notably applies to -A and -L
options.
• --lua can only be used in addition to, not in place of, a -c config. Ideally, --lua could be used in lieu of -c.
• Rule line numbers provided with syntax error messages are off by one. The first rule is unnumbered, the second rule is one,
etc. See nhttp_inspect/detection_buffers/bad_rules/expected for an example.
2.8.3 Rules
• metdata:service foo; metadata:service foo; won’t cause a duplicate service warning as does metadata:service foo, service foo;
• ip_proto doesn’t work properly with reassembled packets so it can’t be used to restrict the protocol of service rules.
• Inspector events generated while parsing TCP payload in non-IPS mode will indicate the wrong direction (ie they will be based
on the ACK packet). (Same is true for Snort.)
2.8.4 snort2lua
• Won’t convert packet rules (alert tcp etc.) to service rules (alert http etc.).
• alert_fast and alert_full: output configuration includes "file = foo.bar", but file is a bool and you cannot specify an output file
name in the configuration.
• preprocessor ports option: ports <number> not supported.
2.8.5 Runtime
• -B <mask> feature does not work. It does ordinary IP address obfuscation instead of using the mask.
• Obfuscation does not work for csv format.
• The hext DAQ will append a newline to text lines (starting with ").
• The hext DAQ does not support embedded quotes in text lines (use hex lines as a workaround).
• Stream TCP alert squash mechanism incorrectly squashes alerts for different TCP packets.
3 Basic Modules
Internal modules which are not plugins are termed "basic". These include configuration for core processing.
Snort++ User Manual 14 / 204
3.1 active
• int active.attempts = 0: number of TCP packets sent per response (with varying sequence numbers) { 0:20 }
• string active.device: use ip for network layer responses or eth0 etc for link layer
• string active.dst_mac: use format 01:23:45:67:89:ab
• int active.max_responses = 0: maximum number of responses { 0: }
3.2 alerts
• bool alerts.alert_with_interface_name = false: include interface in alert info (fast, full, or syslog only)
• bool alerts.default_rule_state = true: enable or disable ips rules
3.3 attribute_table
3.4 classifications
3.5 daq
Peg counts:
3.6 decode
3.7 detection
Peg counts:
3.8 event_filter
3.9 event_queue
3.10 file_id
3.11 host_tracker
3.12 hosts
3.13 ips
• bool ips.enable_builtin_rules = false: enable events from builtin rules w/o stubs
• int ips.id = 0: correlate unified2 events with configuration { 0:65535 }
• string ips.include: legacy snort rules and includes
• enum ips.mode: set policy mode { tap | inline | inline-test }
• string ips.rules: snort rules and includes
3.14 network
• multi network.checksum_drop = none: drop if checksum is bad { all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp |
none }
• multi network.checksum_eval = none: checksums to verify { all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none }
• bool network.decode_drops = false: enable dropping of packets by the decoder
• int network.id = 0: correlate unified2 events with configuration { 0:65535 }
• int network.min_ttl = 1: alert / normalize packets with lower ttl / hop limit (you must enable rules and / or normalization also)
{ 1:255 }
• int network.new_ttl = 1: use this value for responses and when normalizing { 1:255 }
• int network.layers = 40: The maximum number of protocols that Snort can correctly decode { 3:255 }
• int network.max_ip6_extensions = 0: The number of IP6 options Snort will process for a given IPv6 layer. If this limit is hit,
rule 116:456 may fire. 0 = unlimited { 0:255 }
• int network.max_ip_layers = 0: The maximum number of IP layers Snort will process for a given packet If this limit is hit,
rule 116:293 may fire. 0 = unlimited { 0:255 }
Snort++ User Manual 20 / 204
3.15 output
3.16 packets
• bool packets.address_space_agnostic = false: determines whether DAQ address space info is used to track fragments and
connections
• string packets.bpf_file: file with BPF to select traffic for Snort
• bool packets.enable_inline_init_failopen = true: whether to pass traffic during later stage of initialization to avoid drops
• int packets.limit = 0: maximum number of packets to process before stopping (0 is unlimited) { 0: }
• int packets.skip = 0: number of packets to skip before before processing { 0: }
• bool packets.vlan_agnostic = false: determines whether VLAN info is used to track fragments and connections
3.17 ppm
Rules:
3.18 process
3.19 profiler
3.20 rate_filter
3.21 references
3.22 rule_state
3.23 search_engine
• int search_engine.bleedover_port_limit = 1024: maximum ports in rule before demotion to any-any port group { 1: }
• bool search_engine.bleedover_warnings_enabled = false: print warning if a rule is demoted to any-any port group
• bool search_engine.enable_single_rule_group = false: put all rules into one group
• bool search_engine.debug = false: print verbose fast pattern info
• bool search_engine.debug_print_nocontent_rule_tests = false: print rule group info during packet evaluation
• bool search_engine.debug_print_rule_group_build_details = false: print rule group info during compilation
• bool search_engine.debug_print_rule_groups_uncompiled = false: prints uncompiled rule group information
• bool search_engine.inspect_stream_inserts = false: inspect reassembled payload - disabling is good for performance, bad
for detection
• dynamic search_engine.search_method = ac_bnfa: set fast pattern algorithm - choose available search engine { ac_banded |
ac_bnfa | ac_full | ac_sparse | ac_sparse_bands | ac_std | hyperscan }
3.24 snort
• string snort.-?: <option prefix> output matching command line option quick help (same as --help-options) { (optional) }
• implied snort.-f: turn off fflush() calls after binary log writes
Snort++ User Manual 24 / 204
• implied snort.-q: quiet mode - Don’t show banner and status report
• string snort.-R: <rules> include this rules file in the default policy
• string snort.-r: <pcap>. . . (same as --pcap-list)
• string snort.-S: <x=v> set config variable x equal to value v
• implied snort.-y: include year in timestamp in the alert and log files
• int snort.-z = 1: <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores
reported by the system; default is 1 { 0: }
• implied snort.--alert-before-pass: process alert, drop, sdrop, or reject before pass; default is pass before alert, drop,. . .
• string snort.--bpf: <filter options> are standard BPF options, as seen in TCPDump
• string snort.--c2x: output hex for given char (see also --x2c)
• implied snort.--create-pidfile: create PID file, even when not in Daemon mode
Snort++ User Manual 25 / 204
• string snort.--pcap-list: <list> a space separated list of pcaps to read - read mode is implied
• string snort.--pcap-dir: <dir> a directory to recurse to look for pcaps - read mode is implied
• string snort.--pcap-filter: <filter> filter to apply when getting pcaps from file or directory
• int snort.--pcap-loop: <count> read all pcaps <count> times; 0 will read until Snort is terminated { -1: }
• implied snort.--pcap-no-filter: reset to use no filter when getting pcaps from file or directory
• implied snort.--pcap-reload: if reading multiple pcaps, reload snort config between pcaps
• implied snort.--pcap-show: print a line saying what pcap is currently being read
• implied snort.--pedantic: warnings are fatal
• string snort.--plugin-path: <path> where to find plugins
• implied snort.--process-all-events: process all action groups
• string snort.--rule: <rules> to be added to configuration; may be repeated
• implied snort.--rule-to-hex: output so rule header to stdout for text rule on stdin
• implied snort.--rule-to-text: output plain so rule header to stdout for text rule on stdin
• string snort.--run-prefix: <pfx> prepend this to each output file
• string snort.--script-path: <path> to a luajit script or directory containing luajit scripts
• implied snort.--shell: enable the interactive command line
• implied snort.--show-plugins: list module and plugin versions
• int snort.--skip: <n> skip 1st n packets { 0: }
• int snort.--snaplen = 1514: <snap> set snaplen of packet (same as -s) { 68:65535 }
• implied snort.--stdin-rules: read rules from stdin until EOF or a line starting with END is read
• implied snort.--treat-drop-as-alert: converts drop, sdrop, and reject rules into alert rules during startup
• implied snort.--treat-drop-as-ignore: use drop, sdrop, and reject rules to ignore session traffic when not inline
• implied snort.--version: show version number (same as -V)
• implied snort.--warn-all: enable all warnings
• implied snort.--warn-conf: warn about configuration issues
• implied snort.--warn-daq: warn about DAQ issues, usually related to mode
• implied snort.--warn-flowbits: warn about flowbits that are checked but not set and vice-versa
• implied snort.--warn-hosts: warn about host table issues
• implied snort.--warn-plugins: warn about issues that prevent plugins from loading
• implied snort.--warn-rules: warn about duplicate rules and rule parsing issues
• implied snort.--warn-scripts: warn about issues discovered while processing Lua scripts
• implied snort.--warn-symbols: warn about unknown symbols in your Lua config
• implied snort.--warn-vars: warn about variable definition and usage issues
• int snort.--x2c: output ASCII char for given hex (see also --c2x)
• string snort.--x2s: output ASCII string for given byte code (see also --x2c)
Snort++ User Manual 27 / 204
Commands:
Peg counts:
3.25 suppress
4 Codec Modules
Codec is short for coder / decoder. These modules are used for basic protocol decoding, anomaly detection, and construction of
active responses.
Snort++ User Manual 28 / 204
4.1 arp
4.2 auth
4.3 eapol
4.4 erspan2
4.5 erspan3
4.6 esp
• bool esp.decode_esp = false: enable for inspection of esp traffic that has authentication but not encryption
Rules:
4.7 eth
4.8 fabricpath
4.9 gre
4.10 gtp
4.11 icmp4
• 116:443 (icmp4) ICMP destination unreachable communication with destination network is administratively prohibited
• 116:451 (icmp4) ICMP path MTU denial of service attempt
• 116:452 (icmp4) BAD-TRAFFIC Linux ICMP header DOS attempt
• 116:426 (icmp4) truncated ICMP4 header
Peg counts:
4.12 icmp6
Peg counts:
4.13 igmp
4.14 ipv4
Peg counts:
4.15 ipv6
• 116:281 (ipv6) IPv6 header includes an invalid value for the next header field
• 116:282 (ipv6) IPv6 header includes a routing extension header followed by a hop-by-hop header
• 116:283 (ipv6) IPv6 header includes two routing extension headers
• 116:292 (ipv6) IPv6 header has destination options followed by a routing header
• 116:291 (ipv6) IPV6 tunneled over IPv4, IPv6 header truncated, possible Linux kernel attack
• 116:295 (ipv6) IPv6 header includes an option which is too big for the containing header
4.16 mpls
• bool mpls.enable_mpls_overlapping_ip = false: enable if private network addresses overlap and must be differentiated by
MPLS label(s)
• int mpls.max_mpls_stack_depth = -1: set MPLS stack depth { -1: }
• enum mpls.mpls_payload_type = ip4: set encapsulated payload type { eth | ip4 | ip6 }
Rules:
Peg counts:
4.17 pgm
4.18 pppoe
4.19 tcp
• 116:59 (tcp) TCP window scale option found with length > 14
• 116:400 (tcp) XMAS attack detected
• 116:401 (tcp) Nmap XMAS attack detected
Peg counts:
4.20 token_ring
4.21 udp
• bool udp.deep_teredo_inspection = false: look for Teredo on all UDP ports (default is only 3544)
• bool udp.enable_gtp = false: decode GTP encapsulations
• bit_list udp.gtp_ports = 2152 3386: set GTP ports { 65535 }
Rules:
Peg counts:
4.22 vlan
4.23 wlan
What: support for wireless local area network protocol (DLT 105)
Type: codec
Rules:
5 Inspector Modules
These modules perform a variety of functions, including analysis of protocols beyond basic decoding.
5.1 arp_spoof
Rules:
Peg counts:
5.2 back_orifice
Peg counts:
5.3 binder
Peg counts:
5.4 data_log
Peg counts:
5.5 dce_smb
Rules:
• 145:12 (dce_smb) SMB - Remaining NetBIOS data length less than command byte count.
• 145:13 (dce_smb) SMB - Remaining NetBIOS data length less than command data size.
• 145:14 (dce_smb) SMB - Remaining total data count less than this command data size.
• 145:15 (dce_smb) SMB - Total data sent (STDu64) greater than command total data expected.
• 145:16 (dce_smb) SMB - Byte count less than command data size (STDu64)
• 145:17 (dce_smb) SMB - Invalid command data size for byte count.
• 145:18 (dce_smb) SMB - Excessive Tree Connect requests with pending Tree Connect responses.
• 145:19 (dce_smb) SMB - Excessive Read requests with pending Read responses.
• 145:20 (dce_smb) SMB - Excessive command chaining.
• 145:21 (dce_smb) SMB - Multiple chained tree connect requests.
• 145:34 (dce_smb) Connection-oriented DCE/RPC - Fragment length on non-last fragment less than maximum negotiated
fragment transmit size for client.
• 145:35 (dce_smb) Connection-oriented DCE/RPC - Fragment length greater than maximum negotiated fragment transmit size.
• 145:36 (dce_smb) Connection-oriented DCE/RPC - Alter Context byte order different from Bind
• 145:37 (dce_smb) Connection-oriented DCE/RPC - Call id of non first/last fragment different from call id established for
fragmented request.
• 145:38 (dce_smb) Connection-oriented DCE/RPC - Opnum of non first/last fragment different from opnum established for
fragmented request.
• 145:39 (dce_smb) Connection-oriented DCE/RPC - Context id of non first/last fragment different from context id established
for fragmented request.
• 145:44 (dce_smb) SMB - Invalid SMB version 1 seen.
• 145:45 (dce_smb) SMB - Invalid SMB version 2 seen.
Peg counts:
• dce_smb.connection-oriented server minimum fragment size: connection-oriented server minimum fragment size
• dce_smb.connection-oriented server segments reassembled: total connection-oriented server segments reassembled
• dce_smb.connection-oriented server fragments reassembled: total connection-oriented server fragments reassembled
5.6 dce_tcp
• enum dce_tcp.policy = WinXP: Target based policy to use { Win2000 | WinXP | WinVista | Win2003 | Win2008 | Win7 |
Samba | Samba-3.0.37 | Samba-3.0.22 | Samba-3.0.20 }
Rules:
• 145:35 (dce_tcp) Connection-oriented DCE/RPC - Fragment length greater than maximum negotiated fragment transmit size.
• 145:36 (dce_tcp) Connection-oriented DCE/RPC - Alter Context byte order different from Bind
• 145:37 (dce_tcp) Connection-oriented DCE/RPC - Call id of non first/last fragment different from call id established for
fragmented request.
• 145:38 (dce_tcp) Connection-oriented DCE/RPC - Opnum of non first/last fragment different from opnum established for
fragmented request.
Snort++ User Manual 42 / 204
• 145:39 (dce_tcp) Connection-oriented DCE/RPC - Context id of non first/last fragment different from context id established
for fragmented request.
Peg counts:
• dce_tcp.connection-oriented client minimum fragment size: connection-oriented client minimum fragment size
• dce_tcp.connection-oriented client segments reassembled: total connection-oriented client segments reassembled
• dce_tcp.connection-oriented client fragments reassembled: total connection-oriented client fragments reassembled
• dce_tcp.connection-oriented server maximum fragment size: connection-oriented server maximum fragment size
• dce_tcp.connection-oriented server minimum fragment size: connection-oriented server minimum fragment size
• dce_tcp.connection-oriented server segments reassembled: total connection-oriented server segments reassembled
• dce_tcp.connection-oriented server fragments reassembled: total connection-oriented server fragments reassembled
Snort++ User Manual 43 / 204
5.7 dnp3
Rules:
Peg counts:
5.8 dns
Peg counts:
5.9 dpx
Rules:
Peg counts:
5.10 ftp_client
• bool ftp_client.telnet_cmds = false: detect telnet escape sequences on ftp control channel
5.11 ftp_data
5.12 ftp_server
Rules:
Peg counts:
5.13 gtp_inspect
Rules:
Peg counts:
5.14 http_global
What: http inspector global configuration and client rules for use with http_server
Type: inspector
Configuration:
• int http_global.max_gzip_mem = 838860: total memory used for decompression across all active sessions { 3276: }
Snort++ User Manual 47 / 204
• int http_global.memcap = 150994944: limit of memory used for logging extra data { 2304: }
• bool http_global.proxy_alert = false: alert on proxy usage for servers without allow_proxy_use
• int http_global.unicode_map.code_page = 1252: select code page in map file { 0: }
Rules:
Peg counts:
5.15 http_inspect
• bool http_inspect.allow_proxy_use = false: don’t alert on proxy use for this server
• bool http_inspect.decompress_pdf = false: enable decompression of the compressed portions of PDF files
• bool http_inspect.decompress_swf = false: enable decompression of SWF (Adobe Flash content)
• enum http_inspect.profile.profile_type = default: set defaults appropriate for selected server { default | apache | iis | iis_40 |
iis_50 }
• int http_inspect.profile.server_flow_depth = 0: response payload to inspect; includes headers with extended_response_inspection
{ -1:65535 }
• bool http_inspect.profile.u_encode = true: decode %uXXXX character sequences
• bool http_inspect.profile.utf_8 = false: decode UTF-8 unicode sequences in URI
• bool http_inspect.profile.webroot = false: alert on directory traversals past the top level (web server root)
Rules:
5.16 imap
Rules:
Peg counts:
5.17 modbus
• 144:1 (modbus) length in Modbus MBAP header does not match the length needed for the given function
• 144:2 (modbus) Modbus protocol ID is non-zero
• 144:3 (modbus) Reserved Modbus function code in use
Peg counts:
5.18 new_http_inspect
• int new_http_inspect.request_depth = -1: maximum request message body bytes to examine (-1 no limit) { -1: }
• int new_http_inspect.response_depth = -1: maximum response message body bytes to examine (-1 no limit) { -1: }
• bool new_http_inspect.unzip = true: decompress gzip and deflate message bodies
Rules:
5.19 normalizer
• bool normalizer.tcp.req_pay = true: clear the urgent pointer and the urgent flag if there is no payload
• bool normalizer.tcp.rsv = true: clear the reserved bits in the TCP header
• bool normalizer.tcp.req_urp = true: clear the urgent flag if the urgent pointer is not set
• multi normalizer.tcp.allow_names: don’t clear given option names { sack | echo | partial_order | conn_count | alt_checksum |
md5 }
• string normalizer.tcp.allow_codes: don’t clear given option codes
Snort++ User Manual 55 / 204
Peg counts:
• normalizer.tcp syn options: SYN only options cleared from non-SYN packets
• normalizer.test tcp syn options: test SYN only options cleared from non-SYN packets
• normalizer.tcp options: packets with options cleared
• normalizer.tcp urgent ptr: packets without data with urgent pointer cleared
• normalizer.test tcp urgent ptr: test packets without data with urgent pointer cleared
• normalizer.tcp ecn pkt: packets with ECN bits cleared
• normalizer.test tcp ecn pkt: test packets with ECN bits cleared
• normalizer.tcp ts ecr: timestamp cleared on non-ACKs
• normalizer.test tcp ts ecr: test timestamp cleared on non-ACKs
• normalizer.tcp req urg: cleared urgent pointer when urgent flag is not set
• normalizer.test tcp req urg: test cleared urgent pointer when urgent flag is not set
• normalizer.tcp req pay: cleared urgent pointer and urgent flag when there is no payload
• normalizer.test tcp req pay: test cleared urgent pointer and urgent flag when there is no payload
• normalizer.tcp req urp: cleared the urgent flag if the urgent pointer is not set
• normalizer.test tcp req urp: test cleared the urgent flag if the urgent pointer is not set
• normalizer.tcp trim syn: tcp segments trimmed on SYN
5.20 perf_monitor
Peg counts:
5.21 pop
Rules:
Peg counts:
5.22 port_scan
• multi port_scan.protos = all: choose the protocols to monitor { tcp | udp | icmp | ip | all }
• multi port_scan.scan_types = all: choose type of scans to look for { portscan | portsweep | decoy_portscan | distributed_portscan
| all }
• enum port_scan.sense_level = medium: choose the level of detection { low | medium | high }
• string port_scan.watch_ip: list of CIDRs with optional ports to watch
• string port_scan.ignore_scanners: list of CIDRs with optional ports to ignore if the source of scan alerts
• string port_scan.ignore_scanned: list of CIDRs with optional ports to ignore if the destination of scan alerts
• bool port_scan.include_midstream = false: list of CIDRs with optional ports
• bool port_scan.logfile = false: write scan events to file
Rules:
5.23 port_scan_global
What: shared settings for port_scan inspectors for use with port_scan
Type: inspector
Configuration:
Peg counts:
5.24 reputation
Rules:
Peg counts:
5.25 rpc_decode
Peg counts:
5.26 sip
• bool sip.ignore_call_channel = false: enables the support for ignoring audio/video data channel
• int sip.max_call_id_len = 256: maximum call id field size { 0:65535 }
• int sip.max_contact_len = 256: maximum contact field size { 0:65535 }
• int sip.max_content_len = 1024: maximum content length of the message body { 0:65535 }
• int sip.max_dialogs = 4: maximum number of dialogs within one stream session { 1:4194303 }
• int sip.max_from_len = 256: maximum from field size { 0:65535 }
• int sip.max_requestName_len = 20: maximum request name field size { 0:65535 }
• int sip.max_sessions = 10000: maximum number of sessions that can be allocated { 1024:4194303 }
• int sip.max_to_len = 256: maximum to field size { 0:65535 }
• int sip.max_uri_len = 256: maximum request uri field size { 0:65535 }
• int sip.max_via_len = 1024: maximum via field size { 0:65535 }
• string sip.methods = invite cancel ack bye register options: list of methods to check in sip messages
Rules:
Peg counts:
• sip.ack: ack
• sip.bye: bye
• sip.register: register
• sip.options: options
• sip.refer: refer
• sip.subscribe: subscribe
• sip.update: update
• sip.join: join
• sip.info: info
• sip.message: message
• sip.notify: notify
• sip.prack: prack
• sip.total responses: total responses
• sip.1xx: 1xx
Snort++ User Manual 63 / 204
• sip.2xx: 2xx
• sip.3xx: 3xx
• sip.4xx: 4xx
• sip.5xx: 5xx
• sip.6xx: 6xx
• sip.7xx: 7xx
• sip.8xx: 8xx
• sip.9xx: 9xx
5.27 smtp
• int smtp.b64_decode_depth = 25: depth used to decode the base64 encoded MIME attachments { -1:65535 }
• string smtp.data_cmds: commands that initiate sending of data with an end of data delimiter
• int smtp.email_hdrs_log_depth = 1464: depth for logging email headers { 0:20480 }
• bool smtp.log_filename = false: log the MIME attachment filenames extracted from the Content-Disposition header within
the MIME body
• bool smtp.log_mailfrom = false: log the sender’s email address extracted from the MAIL FROM command
• bool smtp.log_rcptto = false: log the recipient’s email address extracted from the RCPT TO command
Rules:
Peg counts:
5.28 ssh
• int ssh.max_encrypted_packets = 25: ignore session after this many encrypted packets { 0:65535 }
• int ssh.max_client_bytes = 19600: number of unanswered bytes before alerting on challenge-response overflow or CRC32 {
0:65535 }
• int ssh.max_server_version_len = 80: limit before alerting on secure CRT server version string overflow { 0:255 }
Rules:
Peg counts:
5.29 ssl
• bool ssl.trust_servers = false: disables requirement that application (encrypted) data must be observed on both sides
• int ssl.max_heartbeat_length = 0: maximum length of heartbeat record allowed { 0:65535 }
Rules:
Peg counts:
5.30 stream
• int stream.udp_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.user_cache.max_sessions = 1024: maximum simultaneous sessions tracked before pruning { 1: }
• int stream.user_cache.memcap = 1048576: maximum cache memory before pruning (0 is unlimited) { 0: }
• int stream.user_cache.pruning_timeout = 30: minimum inactive time before being eligible for pruning { 1: }
• int stream.user_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.file_cache.max_sessions = 128: maximum simultaneous sessions tracked before pruning { 1: }
Peg counts:
5.31 stream_file
5.32 stream_icmp
Peg counts:
5.33 stream_ip
• int stream_ip.min_frag_length = 0: alert if fragment length is below this limit before or after trimming { 0: }
• int stream_ip.min_ttl = 1: discard fragments with ttl below the minimum { 1:255 }
• enum stream_ip.policy = linux: fragment reassembly policy { first | linux | bsd | bsd_right | last | windows | solaris }
Rules:
• 123:11 (stream_ip) TTL value less than configured minimum, not using for reassembly
Snort++ User Manual 69 / 204
Peg counts:
5.34 stream_tcp
What: stream inspector for TCP flow tracking and stream normalization and reassembly
Type: inspector
Configuration:
• int stream_tcp.flush_factor = 0: flush upon seeing a drop in segment size after given number of non-decreasing segments {
0: }
• bool stream_tcp.ignore_any_rules = false: process tcp content rules w/o ports only if rules with ports are present
• int stream_tcp.max_window = 0: maximum allowed tcp window { 0:1073725440 }
• int stream_tcp.overlap_limit = 0: maximum number of allowed overlapping segments per session { 0:255 }
• int stream_tcp.max_pdu = 16384: maximum reassembled PDU size { 1460:65535 }
• enum stream_tcp.policy = bsd: determines operating system characteristics like reassembly { first | last | linux | old_linux |
bsd | macos | solaris | irix | hpux11 | hpux10 | windows | win_2003 | vista | proxy }
• bool stream_tcp.reassemble_async = true: queue data for reassembly before traffic is seen in both directions
• int stream_tcp.require_3whs = -1: don’t track midstream sessions after given seconds from start up; -1 tracks all { -1:86400
}
• bool stream_tcp.show_rebuilt_packets = false: enable cmg like output of reassembled packets
• int stream_tcp.queue_limit.max_bytes = 1048576: don’t queue more than given bytes per session and direction { 0: }
• int stream_tcp.queue_limit.max_segments = 2621: don’t queue more than given segments per session and direction { 0: }
• int stream_tcp.small_segments.count = 0: limit number of small segments queued { 0:2048 }
• int stream_tcp.small_segments.maximum_size = 0: limit number of small segments queued { 0:2048 }
• int stream_tcp.session_timeout = 30: session tracking timeout { 1:86400 }
• int stream_tcp.footprint = 0: use zero for production, non-zero for testing at given size { 0: }
Rules:
Peg counts:
• stream_tcp.max bytes: number of times the maximum queued byte limit was reached
• stream_tcp.internal events: 135:X events generated
• stream_tcp.client cleanups: number of times data from server was flushed when session released
• stream_tcp.server cleanups: number of times data from client was flushed when session released
• stream_tcp.faults: number of times a new segment triggered a prune
• stream_tcp.memory: current memory in use
5.35 stream_udp
Peg counts:
5.36 stream_user
5.37 telnet
• int telnet.ayt_attack_thresh = -1: alert on this number of consecutive telnet AYT commands { -1: }
• bool telnet.check_encrypted = false: check for end of encryption
• bool telnet.encrypted_traffic = false: check for encrypted telnet and ftp
• bool telnet.normalize = false: eliminate escape sequences
Rules:
Peg counts:
5.38 wizard
Peg counts:
IPS actions allow you to perform custom actions when events are generated. Unlike loggers, these are invoked before thresholding
and can be used to control external agents.
Externally defined actions must be configured to become available to the parser. For the reject rule, you can set reject = { } to
get the rule to parse.
6.1 react
• bool react.msg = false: use rule msg in response page instead of default message
6.2 reject
6.3 rewrite
7.1 ack
• string ack.~range: check if packet payload size is size | min<>max | <max | >min
Snort++ User Manual 75 / 204
7.2 asn1
• implied asn1.bitstring_overflow: Detects invalid bitstring encodings that are known to be remotely exploitable.
• implied asn1.double_overflow: Detects a double ASCII encoding that is larger than a standard buffer.
• implied asn1.print: <>max | <max | >min
• int asn1.oversize_length: Compares ASN.1 type lengths with the supplied argument. { 0: }
7.3 base64_decode
What: rule option to decode base64 data - must be used with base64_data option
Type: ips_option
Configuration:
7.4 bufferlen
7.5 byte_extract
• int byte_extract.align = 0: round the number of converted bytes up to the next 2- or 4-byte boundary { 0:4 }
• implied byte_extract.big: big endian
• implied byte_extract.little: little endian
• implied byte_extract.dce: dcerpc2 determines endianness
• implied byte_extract.string: convert from string
• implied byte_extract.hex: convert from hex string
• implied byte_extract.oct: convert from octal string
• implied byte_extract.dec: convert from decimal string
7.6 byte_jump
7.7 byte_test
• string byte_test.~compare: variable name or value to test the converted result against
• string byte_test.~offset: variable name or number of bytes into the payload to start processing
• implied byte_test.relative: offset from cursor instead of start of buffer
• implied byte_test.big: big endian
• implied byte_test.little: little endian
• implied byte_test.dce: dcerpc2 determines endianness
• implied byte_test.string: convert from string
• implied byte_test.hex: convert from hex string
• implied byte_test.oct: convert from octal string
• implied byte_test.dec: convert from decimal string
7.8 classtype
7.9 content
7.10 cvs
7.11 dce_iface
7.12 dce_opnum
7.13 dce_stub_data
7.14 detection_filter
What: rule option to require multiple hits before a rule generates an event
Type: ips_option
Configuration:
7.15 dnp3_data
7.16 dnp3_func
7.17 dnp3_ind
7.18 dnp3_obj
7.19 dsize
• string dsize.~range: check if packet payload size is size | min<>max | <max | >min
7.20 file_data
7.21 flags
7.22 flow
7.23 flowbits
7.24 fragbits
7.25 fragoffset
• string fragoffset.~range: check if packet payload size is size | min<>max | <max | >min
Snort++ User Manual 81 / 204
7.26 gid
7.27 gtp_info
7.28 gtp_type
7.29 gtp_version
7.30 http_client_body
What: rule option to set the detection cursor to the request body
Type: ips_option
7.31 http_cookie
What: rule option to set the detection cursor to the HTTP cookie
Type: ips_option
7.32 http_header
What: rule option to set the detection cursor to the normalized header(s)
Type: ips_option
Configuration:
7.33 http_method
What: rule option to set the detection cursor to the HTTP request method
Type: ips_option
7.34 http_raw_cookie
What: rule option to set the detection cursor to the unnormalized cookie
Type: ips_option
7.35 http_raw_header
What: rule option to set the detection cursor to the unnormalized headers
Type: ips_option
7.36 http_raw_uri
What: rule option to set the detection cursor to the unnormalized URI
Type: ips_option
7.37 http_stat_code
What: rule option to set the detection cursor to the HTTP status code
Type: ips_option
7.38 http_stat_msg
What: rule option to set the detection cursor to the HTTP status message
Type: ips_option
7.39 http_uri
What: rule option to set the detection cursor to the normalized URI buffer
Type: ips_option
7.40 icmp_id
7.41 icmp_seq
• string icmp_seq.~range: check if icmp sequence number is seq | min<>max | <max | >min
7.42 icode
7.43 id
7.44 ip_proto
7.45 ipopts
7.46 isdataat
7.47 itype
7.48 md5
7.49 metadata
What: rule option for conveying arbitrary name, value data within the rule text
Type: ips_option
Configuration:
7.50 modbus_data
7.51 modbus_func
7.52 modbus_unit
7.53 msg
7.54 pcre
7.55 pkt_data
What: rule option to set the detection cursor to the normalized packet data
Type: ips_option
7.56 pkt_num
7.57 priority
7.58 raw_data
What: rule option to set the detection cursor to the raw packet data
Type: ips_option
7.59 reference
7.60 regex
What: rule option for matching payload data with hyperscan regex
Type: ips_option
Configuration:
7.61 rem
7.62 replace
What: rule option to overwrite payload data; use with rewrite action
Type: ips_option
Configuration:
7.63 rev
7.64 rpc
7.65 seq
• string seq.~range: check if packet payload size is size | min<>max | <max | >min
7.66 session
7.67 sha256
7.68 sha512
7.69 sid
7.70 sip_body
What: rule option to set the detection cursor to the request body
Type: ips_option
7.71 sip_header
What: rule option to set the detection cursor to the SIP header buffer
Type: ips_option
7.72 sip_method
7.73 sip_stat_code
7.74 so
7.75 soid
7.76 ssl_state
7.77 ssl_version
7.78 stream_reassemble
7.79 stream_size
7.80 tag
• enum tag.~: log all packets in session or all packets to or from host { session|host_src|host_dst }
7.81 tos
• string tos.~range: check if packet payload size is size | min<>max | <max | >min
7.82 ttl
• string ttl.~range: check if packet payload size is size | min<>max | <max | >min
7.83 urg
7.84 window
• string window.~range: check if packet payload size is size | min<>max | <max | >min
Search engines perform multipattern searching of packets and payload to find rules that should be evaluated. There are currently
no specific modules, although there are several search engine plugins. Related configuration is done with the basic detection
module.
9 SO Rule Modules
SO rules are dynamic rules that require custom coding to perform detection not possible with the existing rule options. These
rules typically do not have associated modules.
10 Logger Modules
10.1 alert_csv
10.2 alert_ex
10.3 alert_fast
10.4 alert_full
10.5 alert_syslog
• enum alert_syslog.facility = auth: part of priority applied to each message { auth | authpriv | daemon | user | local0 | local1 |
local2 | local3 | local4 | local5 | local6 | local7 }
• enum alert_syslog.level = info: part of priority applied to each message { emerg | alert | crit | err | warning | notice | info | debug
}
• multi alert_syslog.options: used to open the syslog connection { cons | ndelay | perror | pid }
10.6 alert_unixsock
10.7 log_codecs
10.8 log_hext
10.9 log_pcap
10.10 unified2
11 DAQ Modules
The Data AcQuisition library (DAQ), provides pluggable packet I/O. The DAQ replaces direct calls to libraries like libpcap with
an abstraction layer that facilitates operation on a variety of hardware and software interfaces without requiring changes to Snort.
It is possible to select the DAQ type and mode when invoking Snort to perform pcap readback or inline operation, etc. The DAQ
library may be useful for other packet processing applications and the modular nature allows you to build new modules for other
platforms.
The DAQ library is provided as an external package on snort.org. There are a few additional modules provided with Snort++.
This section summarizes the important things you need to know to use these DAQ modules. There are also 3rd DAQ modules
available.
Snort++ User Manual 94 / 204
The DAQ is bundled with Snort but must be built first using these steps:
./configure
make
sudo make install
This will build and install both static and dynamic DAQ modules.
Note that pcap >= 1.0.0 is required. pcap 1.1.1 is available at the time of this writing and is recommended.
Also, libdnet is required for IPQ and NFQ DAQs. If you get a relocation error trying to build those DAQs, you may need to
reinstall libdnet and configure it with something like this:
./configure "CFLAGS=-fPIC -g -O2"
You may also experience problems trying to find the dynamic dnet library because it isn’t always named properly. Try creating a
link to the shared library (identified by its .x or .x.y etc. extension) with the same name but with ".so" inserted as follows:
$ ln -s libdnet.1.1 libdnet.so.1.1
$ ldconfig -Rv /usr/local/lib 2>&1 | grep dnet
Adding /usr/local/lib/libdnet.so.1.1
When the DAQ library is built, both static and dynamic flavors will be generated. The various DAQ modules will be built if the
requisite headers and libraries are available. You can disable individual modules, etc. with options to configure. For the complete
list of configure options, run:
./configure --help
pcap is the default DAQ. If snort is run w/o any DAQ arguments, it will operate as it always did using this module. These are
equivalent:
./snort -i <device>
./snort -r <file>
afpacket functions similar to the pcap DAQ but with better performance:
./snort --daq afpacket -i <device>
[--daq-var buffer_size_mb=<#MB>]
[--daq-var debug]
If you want to run afpacket in inline mode, you must craft the device string as one or more interface pairs, where each member
of a pair is separated by a single colon and each pair is separated by a double colon like this:
eth0:eth1
or this:
eth0:eth1::eth2:eth3
By default, the afpacket DAQ allocates 128MB for packet memory. You can change this with:
--daq-var buffer_size_mb=<#MB>
Note that the total allocated is actually higher, here’s why. Assuming the default packet memory with a snaplen of 1518, the
numbers break down like this:
• The frame size is 1518 (snaplen) + the size of the AFPacket header (66 bytes) = 1584 bytes.
Note
Linux kernel version 2.6.31 or higher is required for the AFPacket DAQ module due to its dependency on both TPACKET v2
and PACKET_TX_RING support.
This module can not run unprivileged so ./snort -u -g will produce a warning and won’t change user or group.
Notes on iptables are given below.
Snort++ User Manual 96 / 204
IPQ is the old way to process iptables packets. It replaces the inline version available in pre-2.9 versions built with this:
./configure --enable-inline
Note that layer 2 resets are not supported with the IPQ DAQ:
config layer2resets[: <mac>]
This module can not run unprivileged so ./snort -u -g will produce a warning and won’t change user or group.
Notes on iptables are given below.
IPFW is available for BSD systems. It replaces the inline version available in pre-2.9 versions built with this:
./configure --enable-ipfw
The dump DAQ allows you to test the various inline mode features available in 2.9 Snort like injection and normalization.
./snort -i <device> --daq dump
./snort -r <pcap> --daq dump
By default a file named inline-out.pcap will be created containing all packets that passed through or were generated by snort.
You can optionally specify a different name.
./snort --daq dump --daq-var file=<name>
dump uses the pcap daq for packet acquisition. It therefore does not count filtered packets (a pcap limitation).
Note that the dump DAQ inline mode is not an actual inline mode. Furthermore, you will probably want to have the pcap DAQ
acquire in another mode like this:
./snort -r <pcap> -Q --daq dump --daq-var load-mode=read-file
./snort -i <device> -Q --daq dump --daq-var load-mode=passive
Snort++ User Manual 97 / 204
The netmap project is a framework for very high speed packet I/O. It is available on both FreeBSD and Linux with varying
amounts of preparatory setup required. Specific notes for each follow.
./snort --daq netmap -i <device>
[--daq-var debug]
If you want to run netmap in inline mode, you must craft the device string as one or more interface pairs, where each member of
a pair is separated by a single colon and each pair is separated by a double colon like this:
em1:em2
or this:
em1:em2::em3:em4
Inline operation performs Layer 2 forwarding with no MAC filtering, akin to the AFPacket module’s behavior. All packets
received on one interface in an inline pair will be forwarded out the other interface unless dropped by the reader and vice versa.
Important
The interfaces will need to be up and in promiscuous mode in order to function (ifconfig em1 up promisc). The DAQ
module does not currently do either of these configuration steps for itself.
11.8.1 FreeBSD
In FreeBSD 10.0, netmap has been integrated into the core OS. In order to use it, you must recompile your kernel with the line
device netmap
11.8.2 Linux
You will need to download the netmap source code from the project’s repository:
https://code.google.com/p/netmap/
Follow the instructions on the project’s homepage for compiling and installing the code:
http://info.iet.unipi.it/~luigi/netmap/
It will involve a standalone kernel module (netmap_lin) as well as patching and rebuilding the kernel module used to drive your
network adapters. The following drivers are supported under Linux at the time of writing (June 2014):
e1000
e1000e
forcedeth
igb
ixgbe
r8169
virtio
TODO:
These notes are just a quick reminder that you need to set up iptables to use the IPQ or NFQ DAQs. Doing so may cause problems
with your network so tread carefully. The examples below are intentionally incomplete so please read the related documentation
first.
Here is a blog post by Marty for historical reference:
http://archives.neohapsis.com/archives/snort/2000-11/0394.html
Be sure to start Snort prior to routing packets through NFQ with iptables. Such packets will be dropped until Snort is started.
The queue-num is the number you must give Snort.
If you are running on a system with both NFQ and IPQ support, you may experience some start-up failures of the sort:
The solution seems to be to remove both modules from the kernel like this:
modprobe -r nfnetlink_queue
modprobe -r ip_queue
or:
modprobe nfnetlink_queue
These DAQs should be run with a snaplen of 65535 since the kernel defrags the packets before queuing. Also, no need to
configure frag3.
Snort++ User Manual 99 / 204
/boot/loader.conf:
ipfw_load="YES"
ipdivert_load="YES"
$ kldload -v ipdivert
Loaded ipdivert, id=4
$ ipfw list
...
00075 divert 8000 icmp from any to any
00080 allow icmp from any to any
...
• https://forums.snort.org/forums/support/topics/snort-inline-on-freebsd-ipfw
• http://freebsd.rogness.net/snort_inline/
NAT gateway can be used with divert sockets if the network environment is conducive to using NAT.
The steps to set up NAT with ipfw are as follows:
1. Set up NAT with two interface em0 and em1 by adding the following to /etc/rc.conf. Here em0 is connected to external
network and em1 to host-only LAN.
Snort++ User Manual 100 / 204
gateway_enable="YES"
natd_program="/sbin/natd" # path to natd
natd_enable="YES" # Enable natd (if firewall_enable == YES)
natd_interface="em0" # Public interface or IP Address
natd_flags="-dynamic" # Additional flags
defaultrouter=""
ifconfig_em0="DHCP"
ifconfig_em1="inet 192.168.1.2 netmask 255.255.255.0"
firewall_enable="YES"
firewall_script="/etc/rc.firewall"
firewall_type="simple"
2. Add the following divert rules to divert packets to Snort above and below the NAT rule in the "Simple" section of
/etc/rc.firewall.
...
# Inspect outbound packets (those arriving on "inside" interface)
# before NAT translation.
${fwcmd} add divert 8000 all from any to any in via ${iif}
case ${natd_enable} in
[Yy][Ee][Ss])
if [ -n "${natd_interface}" ]; then
${fwcmd} add divert natd all from any to any via ${natd_interface}
fi
;;
esac
...
# Inspect inbound packets (those arriving on "outside" interface)
# after NAT translation that aren’t blocked for other reasons,
# after the TCP "established" rule.
${fwcmd} add divert 8000 all from any to any in via ${oif}
2. Set up interfaces
$ dhclient vic1
$ dhclient vic2
$ pfctl -v -f rules.txt
The socket module provides provides a stream socket server that will accept up to 2 simultaneous connections and bridge them
together while also passing data to Snort++ for inspection. The first connection accepted is considered the client and the second
connection accepted is considered the server. If there is only one connection, stream data can’t be forwarded but it is still
inspected.
Each read from a socket of up to snaplen bytes is passed as a packet to Snort++ along with a DAQ_SktHdr_t pointer in
DAQ_PktHdr_t→priv_ptr. DAQ_SktHdr_t conveys IP4 address, ports, protocol, and direction. Socket packets can be configured
to be TCP or UDP. The socket DAQ can be operated in inline mode and is able to block packets.
The socket DAQ uses DLT_SOCKET and requires that Snort++ load the socket codec which is included in the extra package.
To use the socket DAQ, start Snort++ like this:
./snort --plugin-path /path/to/lib/snort_extra \
--daq socket [--daq-var port=<port>] [--daq-var proto=<proto>] [-Q]
The file module provides the ability to process files directly w/o having to extract them from pcaps. Use the file module with
Snort’s stream_file to get file type identification and signature services. The usual IPS detection and logging etc. is available too.
You can process all the files in a directory recursively using 8 threads with these Snort options:
--pcap-dir path -z 8
The hext module generates packets suitable for processing by Snort from hex/plain text. Raw packets include full headers and are
processed normally. Otherwise the packets contain only payload and are accompanied with flow information (4-tuple) suitable
for processing by stream_user.
The first character of the line determines it’s purpose:
’$’ command
’#’ comment
’"’ quoted string packet data
’x’ hex packet data
’ ’ empty line separates packets
Client and server are determined as follows. $packet → client indicates to the client (from server) and $packet → server indicates
a packet to the server (from client). $packet followed by a 4-tuple uses the heuristic that the client is the side with the lower port
number.
The default client and server are 192.168.1.1 12345 and 10.1.2.3 80 respectively. $packet commands with a 4-tuple do not change
client and server set with the other $packet commands.
$packet commands should be followed by packet data, which may contain any combination of hex and strings. Data for a packet
ends with the next command or a blank line. Data after a blank line will start another packet with the same tuple as the prior one.
Strings may contain the following escape sequences:
\r = 0x0D = carriage return
\n = 0x0A = new line
\t = 0x09 = tab
\\ = 0x5C = \
Format your input carefully; there is minimal error checking and little tolerance for arbitrary whitespace. You can use Snort’s -L
hext option to generate hext input from a pcap.
The hext DAQ also supports a raw mode which is activated by setting the data link type. For example, you can input full ethernet
packets with --daq-var dlt=1 (Data link types are defined in the DAQ include sfbpf_dlt.h.) Combine that with the hext logger in
raw mode for a quick (and dirty) way to edit pcaps. With --lua "log_hext = { raw = true }", the hext logger will dump the full
packet in a way that can be read by the hext DAQ in raw mode. Here is an example:
# 3 [96]
Snort++ User Manual 103 / 204
x02 09 08 07 06 05 02 01 02 03 04 05 08 00 45 00 00 52 00 03 # ..............E..R ←-
..
x00 00 40 06 5C 90 0A 01 02 03 0A 09 08 07 BD EC 00 50 00 00 # ..@.\............P ←-
..
x00 02 00 00 00 02 50 10 20 00 8A E1 00 00 47 45 54 20 2F 74 # ......P. .....GET ←-
/t
x72 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
x6F 73 74 3A 20 6C 6F 63 61 6C 68 6F 73 74 0D 0A # ost: localhost..
A comment indicating packet number and size precedes each packet dump. Note that the commands are not applicable in raw
mode and have no effect.
12 Snort++ vs Snort
• --pause loads config and waits for resume before processing packets
• --require-rule-sid is hardened
• --shell enables interactive Lua shell
• -T is assumed if no input given
• added --help-config prefix to dump all matching settings
• added --script-path
• added -K text; -K text/pcap is old dump/log mode
• added -z <#> and --max-packet-threads <#>
• delete --enable-mpls-multicast, --enable-mpls-overlapping-ip, --max-mpls-labelchain-len, --mpls-payload-type
• deleted --pid-path and --no-interface-pidfile
Snort++ User Manual 104 / 204
• deleting command line options which will be available with --lua or some such including: -I, -h, -F, -p, --disable-inline-init-
failopen
• hardened -n < 0
• removed --search-method
• replaced "unknown args are bpf" with --bpf
• replaced --dynamic-*-lib[-dir] with --plugin-path (with : separators)
• removed -b, -N, -Z and, --perfmon-file options
• Snort++ will not enforce an upper bound on memcaps and the like within 64 bits
• Snort++ will supply a default *_global config if not specified (Snort would fatal; e.g. http_inspect_server w/o http_inspect_global)
• address list syntax changes: [[ and ]] must be [ [ and ] ] to avoid Lua string parsing errors (unless in quoted string)
• because the Lua conf is live code, we lose file:line locations in app error messages (syntax errors from Lua have file:line)
• changed search-method names for consistency
• delete config include_vlan_in_alerts (not used in code)
• delete config so_rule_memcap (not used in code)
• deleted --disable-attribute-table-reload-thread
• deleted config decode_*_{alerts,drops} (use rules only)
• deleted config dump-dynamic-rules-path
• deleted http and ftp alert options (now strictly rule based)
• preprocessor disabled settings deleted since no longer relevant
• sessions are always created; snort config stateful checks eliminated
• stream5_tcp: prune_log_max deleted; to be replaced with histogram
• stream5_tcp: max_active_responses, min_response_seconds moved to active.max_responses, min_interval
12.4 Rules
12.5 Output
• Snort++ queues decoder and inspector events to the main event queue before ips policy is selected; since some events may not
be enabled, the queue needs to be sized larger than with Snort which used an intermediate queue for decoder events.
• deleted the intermediate http and ftp_telnet event queues
• alert_unified2 and log_unified2 have been deleted
This section describes the changes to the Http Inspect config option "profile".
Snort 2.X allows users to select pre-defined HTTP server profiles using the config option "profile". The user can choose one of
five predefined profiles. When defined, this option will set defaults for other config options within Http Inspect.
With Snort++, the user has the flexibility of defining and fine tuning custom profiles along with the five predefined profiles.
Snort 2.X conf
preprocessor http_inspect_server: server default \
profile apache ports { 80 3128 } max_headers 200
binder =
{
{
when = { proto = ’tcp’, ports = ’80 3128’, },
use = { type = ’http_inspect’ },
},
}
Note
The "profile" option now that points to a table "http_profile_apache" which is defined in "snort_defaults.lua" (as follows).
http_profile_apache =
{
profile_type = ’apache’,
server_flow_depth = 300,
client_flow_depth = 300,
post_depth = -1,
chunk_length = 500000,
ascii = true,
multi_slash = true,
directory = true,
webroot = true,
utf_8 = true,
apache_whitespace = true,
non_strict = true,
normalize_utf = true,
normalize_javascript = false,
max_header_length = 0,
max_headers = 0,
max_spaces = 200,
Snort++ User Manual 107 / 204
max_javascript_whitespaces = 200,
whitespace_chars =’0x9 0xb 0xc 0xd’
}
Note
The config option "max_headers" is set to 0 in the profile, but overwritten by "http_inspect.profile.max_headers = 200".
Conversion
Snort2lua can convert the existing snort.conf with the "profile" option to Snort3.0 compatible "profile". Please refer to the
Snort2Lua post for more details.
Examples
"profile all" ==> "profile = http_profile_default"
"profile apache" ==> "profile = http_profile_apache"
"profile iis" ==> "profile = http_profile_iis"
"profile iis_40" ==> "profile = http_profile_iis_40"
"profile iis_50" ==> "profile = http_profile_iis_50"
The new Http Inspect (new_http_inspect) implementation of config options is still under development.
13 Snort2Lua
One of the major differences between Snort 2.9.X and Snort 3.0 is the configuration. Snort 2.9.X configuration files are written
in Snort-specific syntax while Snort 3.0 configuration files are written in Lua. Snort2Lua is a program specifically designed to
convert Snort 2.9.X configuration files into Lua files that Snort 3.0 can understand.
Snort2Lua reads your legacy Snort conf file(s) and generates Snort++ Lua and rules files. When running this program, the only
mandatory option is to provide Snort2Lua with a Snort configuration file. The default output file file is snort.lua, the default error
file will be snort.rej, and the default rule file is the output file (default is snort.lua). When Snort2Lua finishes running, the resulting
configuration file can be successfully run as the Snort3.0 configuration file. The sole exception to this rule is when Snort2Lua
cannot find an included file. If that occurs, the file will still be included in the output file and you will need to manually adjust
or comment the file name. Additionally, if the exit code is not zero, some of the information may not be successfully converted.
Check the error file for all of the conversion problems.
Those errors can occur for a multitude of reasons and are not necessarily bad. For instance, Snort2Lua will only convert prepro-
cessors that are currently supported. Therefore, any unsupported preprocessors or configuration options including DCERP, SIP,
and SMTP, will cause an error in Snort2Lua since Snort3.0 does not support those preprocessors. Additionally, any rule options
associated with those preprocessors are also not supported. Finally, Snort2Lua expects a valid Snort configuration. Therefore,
if the configuration is invalid or has questionable syntax, Snort2Lua may fail to parse the configuration file or create an invalid
Snort3.0 configuration file.
There are a also few peculiarities of Snort2Lua that may be confusing to a first time user. Specifically, aside from an initial
configuration file (which is specified from the command line or as the file in ‘config binding’), every file that is included into
Snort3.0 must be either a Lua file or a rule file; the file cannot contain both rules and Lua syntax. Therefore, when parsing a
file specified with the ‘include’ command, Snort2Lua will output both a Lua file and a rule file. Additionally, any line that is a
comment in a configuration file will be added in to a comments section at the bottom of the main configuration file. Finally, rules
that contain unsupported options will be converted to the best of Snort2Lua’s capability and then printed as a comment in the
rule file.
Snort++ User Manual 108 / 204
By default, Snort2Lua will attempt to parse every ‘include’ file and every ‘binding’ file. There is an option to change this
functionality.
When specifying a rule file with one of the command line options, Snort2Lua will output all of the converted rules to that specified
rule file. This is especially useful when you are only interesting in converting rules since there is no Lua syntax in rule files.
There is also an option that tells Snort2Lua to output every rule for a given configuration into a single rule file. Similarly, there
is an option pull all of the Lua syntax from every ‘include’ file into the output file.
There are currently three output modes: default, quiet, and differences. As expected, quiet mode produces a Snort++ configura-
tion. All errors (aside from Fatal Snort2Lua errors), differences, and comments will omitted from the final output file. Default
mode will print everything. That mean you will be able to see exactly what changes have occurred between Snort and Snort++
in addition to the new syntax, the original file’s comments, and all errors that have occurred. Finally, differences mode will
not actually output a valid Snort3.0 configuration. Instead, you can see the exact options from the input configuration that have
changed.
Converts the Snort configuration file specified by the -c or --conf-file options into a Snort++ configuration file
Options:
• -? show usage
• -h this overview of snort2lua
• -t when parsing <include_file>, write <include_file>’s information, excluding rules, to <out_file>. Meaningles if -i provided
• -V Print the current Snort2Lua version
• --conf-file Same as -c. A Snort <snort_conf> file which will be converted
• --dont-parse-includes Same as -p. if <snort_conf> file contains any <include_file> or <policy_file> (i.e. include path/to/con-
f/other_conf ), do NOT parse those files
• --error-file=<error_file> Same as -e. output all errors to <error_file>
• --help Same as -h. this overview of snort2lua
• --output-file=<out_file> Same as -o. output the new Snort++ lua configuration to <out_file>
• --print-all Same as -a. default option. print all data
• --print-differences Same as -d. output the differences, and only the differences, between the Snort and Snort++ configurations
to the <out_file>
• --quiet Same as -q. quiet mode. Only output valid confiration information to the <out_file>
• --remark same as -m. add a remark to the end of every converted rule
• --rule-file=<rule_file> Same as -r. output any converted rule to <rule_file>
• --single-conf-file Same as -t. when parsing <include_file>, write <include_file>’s information, excluding rules, to <out_file>
• --single-rule-file Same as -s. when parsing <include_file>, write <include_file>’s rules to <rule_file>.
• --version Same as -V. Print the current Snort2Lua version
Required option:
Default values:
• <out_file> = snort.lua
• <rule_file> = <out_file> = snort.lua. Rules are written to the local_rules variable in the <out_file>
• <error_file> = snort.rej. This file will not be created in quiet mode.
• Any Snort ‘string’ which is dependent on a variable will no longer have that variable in the Lua string.
• Snort2Lua currently does not handle variables well. First, that means variables will not always be parsed correctly. Second,
sometimes a variables value will be outoput in the lua file rather than a variable For instance, if Snort2Lua attempted to convert
the line include $RULE_PATH/example.rule, the output may ouput include /etc/rules/example.rule instead.
• When Snort2Lua parses a ‘binding’ configuration file, the rules and configuration will automatically be combined into the
same file. Also, the new files name will automatically become the old file’s name with a .lua extension. There is currently no
way to specify or change that files name.
• If a rule’s action is a custom ruletype, that rule action will be silently converted to the rultype’s type. No warnings or errors are
currently emmitted. Additionally, the custom ruletypes outputs will be silently discarded.
• If the original configuration contains a binding that points to another file and the binding file contains an error, Snort2Lua will
output the number of rejects for the binding file in addition to the number of rejects in the main file. The two numbers will
eventually be combined into one output.
13.3 Usage
Snort2Lua is included in the Snort 3.0 distribution. The Snort2Lua source code is located in the tools/snort2lua directory. The
program is automatically built and installed.
Translating your configuration
To run Snort2Lua, the only requirement is a file containing Snort 2.9.X syntax. Assuming your configuration file is named
snort.conf, run the command
Snort++ User Manual 110 / 204
snort2lua -c snort.conf
Snort2Lua will output a file named snort.lua. Assuming your snort.conf file is a valid Snort 2.9.X configuration file, than the
resulting snort.lua file will always be a valid Snort 3.0 configuration file; any errors that occur are because Snort 3.0 currently
does not support all of the Snort 2.9.X options.
Every keyword from the Snort configuration can be found in the output file. If the option or keyword has changed, then a
comment containing both the option or keyword’s old name and new name will be present in the output file.
Translating a rule file
Snort2Lua can also accommodate translating individual rule files. Assuming the Snort 2.9.X rule file is named snort.rules and
you want the new rule file to be name updated.rules, run the command
snort2lua -c snort.rules -r updated.rules
Snort2Lua will output a file named updated.rules. That file, updated.rules, will always be a valid Snort 3.0 rule file. Any rule that
contains unsupported options will be a comment in the output file.
Understanding the Output
Although Snort2Lua outputs very little to the console, there are several things that occur when Snort2Lua runs. This is a list of
Snort2Lua outputs.
The console. Every line that Snort2Lua is unable to translate from the Snort 2.9.X format to the Snort 3.0 format is considered
an error. Upon exiting, Snort2Lua will print the number of errors that occurred. Snort2Lua will also print the name of the error
file.
The output file. As previously mentioned, Snort2Lua will create a Lua file with valid Snort 3.0 syntax. The default Lua file is
named snort.lua. This file is the equivalent of your main Snort 2.9.X configuration file.
The rule file. By default, all rules will be printed to the Lua file. However, if a rule file is specified on the command line, any
rules found in the Snort 2.9.X configuration will be written to the rule file instead
The error file. By default, the error file is snort.rej. It will only be created if errors exist. Every error referenced on the command
line can be found in this file. There are two reasons an error can occur.
• The Snort 2.9.X configuration file has invalid syntax. If Snort 2.9.X cannot parse the configuration file, neither can Snort2Lua.
In the example below, Snort2Lua could not convert the line config bad_option. Since that is not valid Snort 2.9.X syntax, this
is a syntax error.
• The Snort 2.9.X configuration file contains preprocessors and rule options that are not supported in Snort 3.0. If Snort 2.9.X
can parse a line that Snort2Lua cannot parse, than Snort 3.0 does not support something in the line. As Snort 3.0 begins
supporting these preprocessors and rule options, Snort2Lua will also begin translating these lines. One example of such an
error is dcerpc2.
Additional .lua and .rules files. Every time Snort2Lua parses the include or binding keyword, the program will attempt to parse
the file referenced by the keyword. Snort2Lua will then create one or two new files. The new files will have a .lua or .rules
extension appended to the original filename.
14 Extending Snort++
14.1 Plugins
Snort++ uses a variety of plugins to accomplish much of its processing objectives, including:
Plugins have an associated API defined for each type, all of which share a common header, called the BaseApi. A dynamic
library makes its plugins available by exporting the snort_plugins symbol, which is a null terminated array of BaseApi pointers.
The BaseApi includes type, name, API version, plugin version, and function pointers for constructing and destructing a Module.
The specific API add various other data and functions for their given roles.
14.2 Modules
The Module is pervasive in Snort+.It is how everything, including plugins, are configured.It al
so provides access to builtin rules.And as the glue that binds functionality to Snort+,
the capabilities of a Module are expected to grow to include statistics support, etc.
Module configuration is handled by a list of Parameters. Most parameters can be validated by the framework, which means for
example that conversion from string to number is done in exactly one place. Providing the builtin rules allows the documentation
to include them automatically and also allows for autogenerating the rules at startup.
If we are defining a new Inspector called, say, gadget, it might be configured in snort.lua like this:
gadget =
{
brain = true,
claw = 3
}
When the gadget table is processed, Snort++ will look for a module called gadget. If that Module has an associated API, it will
be used to configure a new instance of the plugin. In this case, a GadgetModule would be instantiated, brain and claw would be
set, and the Module instance would be passed to the GadgetInspector constructor.
Module has three key virtual methods:
• begin() - called when Snort++ starts processing the associated Lua table. This is a good place to allocate any required data and
set defaults.
• set() - called to set each parameter after validation.
• end() - called when Snort++ finishes processing the associated Lua table. This is where additional integrity checks of related
parameters should be done.
The configured Module is passed to the plugin constructor which pulls the configuration data from the Module. For non-trivial
configurations, the working paradigm is that Module hands a pointer to the configured data to the plugin instance which takes
ownership.
Note that there is at most one instance of a given Module, even if multiple plugin instances are created which use that Module.
(Multiple instances require Snort++ binding configuration.)
Snort++ User Manual 112 / 204
14.3 Inspectors
There are several types of inspector, which determines which inspectors are executed when:
• IT_PACKET - used to process all packets before session and service processing (e.g. normalize)
• IT_NETWORK - processes packets w/o service (e.g. arp_spoof, back_orifice)
• IT_STREAM - for flow tracking, ip defrag, and tcp reassembly
14.4 Codecs
The Snort3.0 Codecs decipher raw packets. These Codecs are now completely pluggable; almost every Snort3.0 Codec can be
built dynamically and replaced with an alternative, customized Codec. The pluggable nature has also made it easier to build new
Codecs for protocols without having to touch the Snort3.0 code base.
The first step in creating a Codec is defining its class and protocol. Every Codec must inherit from the Snort3.0 Codec class
defined in "framework/codec.h". The following is an example Codec named "example" and has an associated struct that is 14
bytes long.
#include <cstdint>
#include <arpa/inet.h>
#include “framework/codec.h”
#include "main/snort_types.h"
struct Example
{
uint8_t dst[6];
uint8_t src[6];
uint16_t ethertype;
After defining ExCodec, the next step is adding the Codec’s decode functionality. The function below does this by implementing
a valid decode function. The first parameter, which is the RawData struct, provides both a pointer to the raw data that has come
from a wire and the length of that raw data. The function takes this information and validates that there are enough bytes for this
protocol. If the raw data’s length is less than 14 bytes, the function returns false and Snort3.0 discards the packet; the packet is
neither inspected nor processed. If the length is greater than 14 bytes, the function populates two fields in the CodecData struct,
next_prot_id and lyr_len. The lyr_len field tells Snort3.0 the number of bytes that this layer contains. The next_prot_id field
provides Snort3.0 the value of the next EtherType or IP protocol number.
bool ExCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
{
if ( raw.len < Example::size() )
return false;
For instance, assume this decode function receives the following raw data with a validated length of 32 bytes:
00 11 22 33 44 55 66 77 88 99 aa bb 08 00 45 00
00 38 00 01 00 00 40 06 5c ac 0a 01 02 03 0a 09
The Example struct’s EtherType field is the 13 and 14 bytes. Therefore, this function tells Snort that the next protocol has an
EtherType of 0x0800. Additionally, since the lyr_len is set to 14, Snort knows that the next protocol begins 14 bytes after the
beginning of this protocol. The Codec with EtherType 0x0800, which happens to be the IPv4 Codec, will receive the following
data with a validated length of 18 ( == 32 – 14):
45 00 00 38 00 01 00 00 40 06 5c ac 0a 01 02 03
0a 09
How does Snort3.0 know that the IPv4 Codec has an EtherType of 0x0800? The Codec class has a second virtual function named
get_protocol_ids(). When implementing the function, a Codec can register for any number of values between 0x0000 - 0xFFFF.
Then, if the next_proto_id is set to a value for which this Codec has registered, this Codec’s decode function will be called. As
a general note, the protocol ids between [0, 0x00FF] are IP protocol numbers, [0x0100, 0x05FF] are custom types, and [0x0600,
0xFFFF] are EtherTypes.
For example, in the get_protocol_ids function below, the ExCodec registers for the protocols numbers 17, 787, and 2054. 17
happens to be the protocol number for UDP while 2054 is ARP’s EtherType. Therefore, this Codec will now attempt to decode
UDP and ARP data. Additionally, if any Codec sets the next_protocol_id to 787, ExCodec’s decode function will be called.
Some custom protocols are already defined in the file "protocols/protocol_ids.h"
void ExCodec::get_protocol_ids(std::vector<uint16_t>&v)
{
v.push_back(0x0011); // == 17 == UDP
v.push_back(0x1313); // == 787 == custom
v.push_back(0x0806); // == 2054 == ARP
}
To register a Codec for Data Link Type’s rather than protocols, the function get_data_link_type() can be similarly implemented.
The final step to creating a pluggable Codec is the snort_plugins array. This array is important because when Snort3.0 loads a
dynamic library, the program only find plugins that are inside the snort_plugins array. In other words, if a plugin has not been
added to the snort_plugins array, that plugin will not be loaded into Snort3.0.
Although the details will not be covered in this post, the following code snippet is a basic CodecApi that Snort3.0 can load. This
snippet can be copied and used with only three minor changes. First, in the function ctor, ExCodec should be replaced with the
name of the Codec that is being built. Second, EX_NAME must match the Codec’s name or Snort will be unable to load this
Codec. Third, EX_HELP should be replaced with the general description of this Codec. Once this code snippet has been added,
ExCodec is ready to be compiled and plugged into Snort3.0.
Snort++ User Manual 114 / 204
Two example Codecs are available in the extra directory on git and the extra tarball on the Snort3.0 page. One of those examples
is the Token Ring Codec while the other example is the PIM Codec.
As a final note, there are four more virtual functions that a Codec should implement: encode, format, update, and log. If the
functions are not implemented Snort will not throw any errors. However, Snort may also be unable to accomplish some of its
basic functionality.
• encode is called whenever Snort actively responds and needs to builds a packet, i.e. whenever a rule using an IPS ACTION
like react, reject, or rewrite is triggered. This function is used to build the response packet protocol by protocol.
• format is called when Snort is rebuilding a packet. For instance, every time Snort reassembles a TCP stream or IP fragment,
format is called. Generally, this function either swaps any source and destination fields in the protocol or does nothing.
• update is similar to format in that it is called when Snort is reassembling a packet. Unlike format, this function only sets length
fields.
• log is called when either the log_codecs logger or a custom logger that calls PacketManager::log_protocols is used when
running Snort3.0.
Action plugins specify a builtin action in the API which is used to determine verdict. (Conversely, builtin actions don’t have an
associated plugin function.)
Snort++ User Manual 115 / 204
In order to assist with plugin development, an experimental mode called "piglet" mode is provided. With piglet mode, you can
call individual methods for a specific plugin. The piglet tests are specified as Lua scripts. Each piglet test script defines a test for
a specific plugin.
Here is a minimal example of a piglet test script for the IPv4 Codec plugin:
plugin =
{
type = "piglet",
name = "codec::ipv4",
use_defaults = true,
test = function()
local daq_header = DAQHeader.new()
local raw_buffer = RawBuffer.new("some data")
local codec_data = CodecData.new()
local decode_data = DecodeData.new()
return Codec.decode(
daq_header,
raw_buffer,
codec_data,
decode_data
)
end
}
To run snort in piglet mode, first build snort with the BUILD_PIGLET option turned on (pass the flag -DBUILD_PIGLET:BOOL=ON
in cmake).
Then, run the following command:
snort --script-path $test_scripts --piglet
This section documents the API that piglet exposes to Lua. Refer to the piglet directory in the source tree for examples of usage.
Note: Because of the differences between the Lua and C++ data model and type system, not all parameters map directly to the
parameters of the underlying C\++ member functions. Every effort has been made to keep the mappings consist, but there are
still some differences. They are documented below.
For each test, piglet instantiates plugin specified in the name field of the plugin table. The virtual methods of the instance are
exposed in a table unique to each plugin type. The name of the table is the CamelCase name of the plugin type.
For example, codec plugins have a virtual method called decode. This method is called like this:
Snort++ User Manual 116 / 204
Codec.decode(...)
Codec
Differences:
• In Codec.update(), the (uint64_t) flags parameter has been split into flags_hi and flags_lo
Inspector
• Inspector.configure()
• Inspector.tinit()
• Inspector.tterm()
• Inspector.likes(Packet)
• Inspector.eval(Packet)
• Inspector.clear(Packet)
• Inspector.get_buf_from_key(string[key], Packet, RawBuffer) → bool
• Inspector.get_buf_from_id(uint[id], Packet, RawBuffer) → bool
• Inspector.get_buf_from_type(uint[type], Packet, RawBuffer) → bool
• Inspector.get_splitter(bool[to_server]) → StreamSplitter
Differences: * In Inspector.configure(), the SnortConfig* parameter is passed implicitly. * the overloaded get_
buf() member function has been split into three separate methods.
IpsOption
• IpsOption.hash() → int
• IpsOption.is_relative() → bool
• IpsOption.fp_research() → bool
• IpsOption.get_cursor_type() → int
• IpsOption.eval(Cursor, Packet) → int
• IpsOption.action(Packet)
IpsAction
Snort++ User Manual 117 / 204
• IpsAction.exec(Packet)
Logger
• Logger.open()
• Logger.close()
• Logger.reset()
• Logger.alert(Packet, string[message], Event)
• Logger.log(Packet, string[message], Event)
SearchEngine
Currently, SearchEngine does not expose any methods.
SoRule
Currently, SoRule does not expose any methods.
Interface Objects
Many of the plugins take C++ classes and structs as arguments. These objects are exposed to the Lua API as Lua userdata.
Exposed objects are instantiated by calling the new method from each object’s method table.
For example, the DecodeData object can be instantiated and exposed to Lua like this:
local decode_data = DecodeData.new(...)
Each object also exposes useful methods for getting and setting member variables, and calling the C++ methods contained in the
the object. These methods can be accessed using the : accessor syntax:
decode_data:set({ sp = 80, dp = 3500 })
Since this is just syntactic sugar for passing the object as the first parameter of the function DecodeData.set, an equivalent
form is:
decode_data.set(decode_data, { sp = 80, dp = 3500 })
or even:
DecodeData.set(decode_data, { sp = 80, dp = 3500 })
Buffer
• Buffer.new(string[data]) → Buffer
• Buffer.new(uint[length]) → Buffer
• Buffer.new(RawBuffer) → Buffer
• Buffer:allocate(uint[length]) → bool
• Buffer:clear()
CodecData
• CodecData.new() → CodecData
• CodecData.new(uint[next_prot_id]) → CodecData
Snort++ User Manual 118 / 204
• CodecData.new(fields) → CodecData
• CodecData:get() → fields
• CodecData:set(fields)
• next_prot_id
• lyr_len
• invalid_bytes
• proto_bits
• codec_flags
• ip_layer_cnt
• ip6_extension_count
• curr_ip6_extension
• ip6_csum_proto
Cursor
• Cursor.new() → Cursor
• Cursor.new(Packet) → Cursor
• Cursor.new(string[data]) → Cursor
• Cursor.new(RawBuffer) → Cursor
• Cursor:reset()
• Cursor:reset(Packet)
• Cursor:reset(string[data])
• Cursor:reset(RawBuffer)
DAQHeader
• DAQHeader.new() → DAQHeader
• DAQHeader.new(fields) → DAQHeader
• DAQHeader:get() → fields
• DAQHeader:set(fields)
• caplen
• pktlen
• ingress_index
• egress_index
• ingress_group
Snort++ User Manual 119 / 204
• egress_group
• flags
• opaque
DecodeData
• DecodeData.new() → DecodeData
• DecodeData.new(fields) → DecodeData
• DecodeData:reset()
• DecodeData:get() → fields
• DecodeData:set(fields)
• DecodeData:set_ipv4_hdr(RawBuffer, uint[offset])
• sp
• dp
• decode_flags
• type
EncState
• EncState.new() → EncState
• EncState.new(uint[flags_lo]) → EncState
• EncState.new(uint[flags_lo], uint[flags_hi]) → EncState
Event
• Event.new() → Event
• Event.new(fields) → Event
• Event:get() → fields
• Event:set(fields)
• event_id
• event_reference
• sig_info
Snort++ User Manual 120 / 204
– generator
– id
– rev
– class_id
– priority
– text_rule
– num_services
Flow
• Flow.new() → Flow
• Flow:reset()
Packet
• Packet.new() → Packet
• Packet.new(string[data]) → Packet
• Packet.new(uint[size]) → Packet
• Packet.new(fields) → Packet
• Packet.new(RawBuffer) → Packet
• Packet.new(DAQHeader) → Packet
• Packet:set_decode_data(DecodeData)
• Packet:set_data(uint[offset], uint[length])
• Packet:set_flow(Flow)
• Packet:get() → fields
• Packet:set()
• Packet:set(string[data])
• Packet:set(uint[size])
• Packet:set(fields)
• Packet:set(RawBuffer)
• Packet:set(DAQHeader)
• packet_flags
• xtradata_mask
• proto_bits
• application_protocol_ordinal
• alt_dsize
• num_layers
Snort++ User Manual 121 / 204
• iplist_id
• user_policy_id
• ps_proto
Note: Packet.new() and Packet:set() accept multiple arguments of the types described above in any order
RawBuffer
• RawBuffer.new() → RawBuffer
• RawBuffer.new(uint[size]) → RawBuffer
• RawBuffer.new(string[data]) → RawBuffer
• RawBuffer:size() → int
• RawBuffer:resize(uint[size])
• RawBuffer:write(string[data])
• RawBuffer:write(string[data], uint[size])
• RawBuffer:read() → string
• RawBuffer:read(uint[end]) → string
• RawBuffer:read(uint[start], uint[end]) → string
Note: StreamSplitter does not have a new() method, it must be created by an inspector via Inspector.get_splitter()
15 Coding Style
All new code should try to follow these style guidelines. These are not yet firm so feedback is welcome to get something we can
live with.
15.1 General
15.2 Naming
• Use camel case for namespaces, classes, and types like WhizBangPdfChecker.
• Use lower case identifiers with underscore separators, e.g. some_function() and my_var.
• Use lower case filenames with underscores.
15.3 Comments
• Write comments sparingly with a mind towards future proofing. Often the comments can be obviated with better code. Clear
code is better than a comment.
• Function comment blocks are generally just noise that quickly becomes obsolete. If you absolutely must comment on pa-
rameters, put each on a separate line along with the comment. That way changing the signature may prompt a change to the
comments too.
• Use FIXIT (not FIXTHIS or TODO or whatever) to mark things left for a day or even just a minute. That way we can find
them easily and won’t lose track of them.
• Presently using FIXIT-X where X = P | H | M | L, indicating perf, high, med, or low priority. For now, H, M, or L can indicate
alpha 1, 2, or 3. Perf changes fall between alpha 1 and 2.
• Put the copyright(s) and license in a comment block at the top of each source file (.h and .cc). Don’t bother with trivial scripts
and make foo. Some interesting Lua code should get a comment block too. Copy and paste exactly from src/main.h (don’t
reformat).
• Put author, description, etc. in separate comment(s) following the license. Do not put such comments in the middle of the
license foo. Be sure to put the author line ahead of the header guard to exclude them from the developers guide.
• Each header should have a comment immediately after the header guard to give an overview of the file so the user knows
what’s going on.
15.4 Logging
• Messages intended for the user should not look like debug messages. Eg, the function name should not be included.
• Most debug messages should just be deleted.
• Don’t bang your error messages (no !). The user feels bad enough about the problem already w/o you shouting at him.
15.5 Types
• Use logical types to make the code clearer and to help the compiler catch problems. typedef uint16_t Port; bool foo(Port) is
way better than int foo(int port).
• Use forward declarations (e.g. struct SnortConfig;) instead of void*.
• Try not to use extern data unless absolutely necessary and then put the extern in an appropriate header.
• Use const liberally. In most cases, const char* s = "foo" should be const char* const s = "foo". The former goes in the initialized
data section and the latter in read only data section.
• But use const char s[] = "foo" instead of const char* s = "foo" when possible. The latter form allocates a pointer variable and
the data while the former allocates only the data.
• Use static wherever possible to minimize public symbols and eliminate unneeded relocations.
• Declare functions virtual only in the parent class introducing the function (not in a derived class that is overriding the function).
This makes it clear which class introduces the function.
Snort++ User Manual 123 / 204
• Declare functions as override if they are intended to override a function. This makes it possible to find derived implementations
that didn’t get updated and therefore won’t get called due a change in the parent signature.
• Use bool functions instead of int unless there is truly a need for multiple error returns. The C-style use of zero for success
and -1 for error is less readable and often leads to messy code that either ignores the various errors anyway or needlessly and
ineffectively tries to do something aobut them.
• In many cases, even in C++, use #define name "value" instead of a const char* const name = "value" because it will eliminate
a symbol from the binary.
• Use inline functions instead of macros where possible (pretty much all cases except where stringification is necessary). Func-
tions offer better typing, avoid re-expansions, and a debugger can break there.
• All macros except simple const values should be wrapped in () and all args should be wrapped in () too to avoid surprises upon
expansion. Example:
#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)
• Multiline macros should be blocked (i.e. inside { }) to avoid if-else type surprises.
15.7 Formatting
Yes:
calling_a_func_with_a_long_name(
arg1, arg2, arg3);
• Put function signature on one line, except when breaking for the arg list:
No:
inline
bool foo()
{ // ...
Yes:
inline bool foo()
{ // ...
• Put conditional code on the line following the if so it is easy to break on the conditional block:
No:
if ( test ) foo();
Snort++ User Manual 124 / 204
Yes:
if ( test )
foo();
15.8 Classes
• Use the order public, protected, private top to bottom in a class declaration.
• Keep inline functions in a class declaration very brief, preferably just one line. If you need a more complex inline function,
move the definition outside the class declaration.
• The goal is to have highly readable class declarations. The user shouldn’t have to sift through implementation details to see
what is available to the client.
15.9 Headers
• Don’t hesitate to create a new header if it is needed. Don’t lump unrelated stuff into an header because it is convenient.
• Write header guards like this (leading underscores are reserved for system stuff). In my_header.h:
#ifndef MY_HEADER_H
#define MY_HEADER_H
// ...
#endif
• Includes from a different directory should specify parent directory. This makes it clear exactly what is included and avoids the
primordial soup that results from using -I this -I that -I the_other_thing . . . .
// given:
src/foo/foo.cc
src/bar/bar.cc
src/bar/baz.cc
// in baz.cc
#include "bar.h"
// in foo.cc
#include "bar/bar.h"
15.10 Warnings
15.11 Other
• Prefer and over && and or over || for new source files.
15.12 Uncrustify
Currently using uncrustify from at https://github.com/bengardner/uncrustify to reformat legacy code and anything that happens
to need a makeover at some point.
The working config is crusty.cfg in the top level directory. It does well but will munge some things. Specially formatted
INDENT-OFF comments were added in 2 places to avoid a real mess.
You can use uncrustify something like this:
uncrustify -c crusty.cfg --replace file.cc
16 Reference
16.1 Terminology
• basic module: a module integrated into Snort that does not come from a plugin.
• binder: inspector that maps configuration to traffic
• builtin rules: codec and inspector rules for anomalies detected internally.
• codec: short for coder / decoder. These plugins are used for basic protocol decoding, anomaly detection, and construction of
active responses.
• data module: an adjunct configuration plugin for use with certain inspectors.
• inspector: plugin that processes packets (similar to the legacy Snort preprocessor)
• IPS: intrusion prevention system, like Snort.
Snort++ User Manual 126 / 204
• IPS action: plugin that allows you to perform custom actions when events are generated. Unlike loggers, these are invoked
before thresholding and can be used to control external agents or send active responses.
• IPS option: this plugin is the building blocks of IPS rules.
• logger: a plugin that performs output of events and packets. Events are thresholded before reaching loggers.
• module: the user facing portion of a Snort component. Modules chiefly provide configuration parameters, but may also provide
commands, builtin rules, profiling statistics, peg counts, etc. Note that not all modules are plugins and not all plugins have
modules.
• spell: a type of protocol magic that the wizard uses to identify ASCII protocols.
• text rule: a rule loaded from the configuration that has a header and body. The header specifies action, protocol, source and
destination IP addresses and ports, and direction. The body specifies detection and non-detection options.
• wizard: inspector that applies protocol magic to determine which inspectors should be bound to traffic absent a port specific
binding. See hex and spell.
16.2 Usage
For the following examples "$my_path" is assumed to be the path to the Snort++ install directory. Additionally, it is assumed
that "$my_path/bin" is in your PATH.
16.2.1 Environment
LUA_PATH is used directly by Lua to load and run required libraries. SNORT_LUA_PATH is used by Snort to load supplemental
configuration files.
export LUA_PATH=$my_path/include/snort/lua/\?.lua\;\;
export SNORT_LUA_PATH=$my_path/etc/snort
16.2.2 Help
Note
Snort++ stops reading command-line options after the "--help-" and "--list-" options, so any other options should be placed
before them.
Read a pcap:
snort -r /path/to/my.pcap
Note
Command line options must be specified separately. "snort -de" won’t work. You can still concatenate options and their
arguments, however, so "snort -Ldump" will work.
16.2.4 Configuration
Log any generated alerts to the console using the "-A" option:
snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A alert_full
Add or modify a configuration from the command line using the "--lua" option:
snort -c $my_path/etc/snort/snort.lua -r /path/to/my.pcap -A cmg \
--lua ’ips = { enable_builtin_rules = true }’
Note
The "--lua" option can be specified multiple times.
Run Snort++ in IDS mode on an entire directory of pcaps, processing each input source on a separate thread:
snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
--pcap-filter ’*.pcap’ --max-packet-threads 8
16.3 Plugins
To make it simple to configure outputs when you run with multiple packet threads, output files are not explicitly configured.
Instead, you can use the options below to format the paths:
<logdir>/[<run_prefix>][<id#>][<X>]<name>
Run 4 packet threads and log with thread number prefix (0-3):
snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
--pcap-filter ’*.pcap’ -z 4 -A unified2
Note
subdirectories are created automatically if required. Log filename is based on module name that writes the file. All text mode
outputs default to stdout. These options can be combined.
Process a directory of plain files (ie non-pcap) with 4 threads with 8K buffers:
snort -c $my_path/etc/snort/snort.lua \
--daq-dir $my_path/lib/snort/daqs --daq file \
--pcap-dir path/to/files -z 4 -s 8192
Snort++ User Manual 130 / 204
Bridge two TCP connections on port 8000 and inspect the traffic:
snort -c $my_path/etc/snort/snort.lua \
--daq-dir $my_path/lib/snort/daqs --daq socket
Output timestamp, pkt_num, proto, pkt_gen, dgm_len, dir, src_ap, dst_ap, rule, action for each alert:
snort -c $my_path/etc/snort/snort.lua -A csv
16.4.3 Shell
You must build with --enable-shell to make the command line shell available.
Enable shell mode:
snort --shell <args>
You will see the shell mode command prompt, which looks like this:
o")~
In that case you must issue the resume() command to continue. Enter quit() to terminate Snort or detach() to exit the shell. You
can list the available commands with help().
To enable local telnet access on port 12345:
snort --shell -j 12345 <args>
The command line interface is still under development. Suggestions are welcome.
16.4.4 Signals
Note
The following examples assume that Snort++ is currently running and has a process ID of <pid>.
Shutdown normally:
kill -term <pid>
Note
The available signals may vary from platform to platform.
The features listed below must be explicitly enabled so they are built into the Snort binary. For a full list of build features, run
./configure --help.
• --enable-shell: enable building local and remote command line shell support.
These features are built only if the required libraries and headers are present. There is no need to explicitly enable.
If you need to use headers and/or libraries in non-standard locations, you can use these options:
These can be use for pcap, luajit, pcre, dnet, daq, lzma, openssl, intel-soft-cpm, and hyperscan packages. For more information
on these libraries see the Getting Started section of the manual.
• HOSTTYPE: optional string that is output with the version at end of line.
• LUA_PATH: you must export as follows so LuaJIT can find required files.
LUA_PATH=$install_dir/include/snort/lua/\?.lua\;\;
• SNORT_IGNORE: the list of symbols Snort should ignore when parsing the Lua conf. Unknown symbols not in SNORT_IGNORE
will cause warnings with --warn-unknown or fatals with --warn-unknown --pedantic.
• SNORT_LUA_PATH: an optional path where Snort can find supplemental conf files such as classification.lua.
• SNORT_PROMPT: the character sequence that is printed at startup, shutdown, and in the shell. The default is the mini-pig:
o")~ .
• SNORT_PLUGIN_PATH: an optional path where Snort can find supplemental shared libraries. This is only used when Snort
is building manuals. Modules in supplemental shared libraries will be added to the manuals.
Snort++ User Manual 132 / 204
• --alert-before-pass process alert, drop, sdrop, or reject before pass; default is pass before alert, drop,. . .
• --bpf <filter options> are standard BPF options, as seen in TCPDump
• --c2x output hex for given char (see also --x2c)
• --create-pidfile create PID file, even when not in Daemon mode
• --daq <type> select packet acquisition module (default is pcap)
• --daq-dir <dir> tell snort where to find desired DAQ
• --daq-list list packet acquisition modules available in optional dir, default is static modules only
• --daq-mode <mode> select the DAQ operating mode
• --daq-var <name=value> specify extra DAQ configuration variable
• --dirty-pig don’t flush packets on shutdown
• --dump-builtin-rules [<module prefix>] output stub rules for selected modules
• --dump-defaults [<module prefix>] output module defaults in Lua format (optional)
• --dump-dynamic-rules output stub rules for all loaded rules libraries
• --dump-version output the version, the whole version, and only the version (optional)
• --enable-inline-test enable Inline-Test Mode Operation
• --help list command line options
• --help-commands [<module prefix>] output matching commands (optional)
• --help-config [<module prefix>] output matching config options (optional)
• --help-counts [<module prefix>] output matching peg counts (optional)
• --help-module <module> output description of given module
• --help-modules list all available modules with brief help
• --help-options <option prefix> output matching command line option quick help (same as -?) (optional)
• --help-plugins list all available plugins with brief help
• --help-signals dump available control signals
• --id-subdir create/use instance subdirectories in logdir instead of instance filename prefix
• --id-zero use id prefix / subdirectory even with one packet thread
• --list-buffers output available inspection buffers
• --list-builtin <module prefix> output matching builtin rules (optional)
• --list-gids [<module prefix>] output matching generators (optional)
• --list-modules [<module type>] list all known modules of given type (optional)
• --list-plugins list all known plugins
• --logid <0xid> log Identifier to uniquely id events for multiple snorts (same as -G) (0:65535)
• --lua <chunk> extend/override conf with chunk; may be repeated
• --markup output help in asciidoc compatible format
Snort++ User Manual 133 / 204
• --max-packet-threads <count> configure maximum number of packet threads (same as -z) (0:)
• --nolock-pidfile do not try to lock Snort PID file
• --nostamps don’t include timestamps in log file names
• --pause wait for resume/quit command before processing packets/terminating
• --pcap-dir <dir> a directory to recurse to look for pcaps - read mode is implied
• --pcap-file <file> file that contains a list of pcaps to read - read mode is implied
• --pcap-filter <filter> filter to apply when getting pcaps from file or directory
• --pcap-list <list> a space separated list of pcaps to read - read mode is implied
• --pcap-loop <count> read all pcaps <count> times; 0 will read until Snort is terminated (-1:)
• --pcap-no-filter reset to use no filter when getting pcaps from file or directory
• --pcap-reload if reading multiple pcaps, reload snort config between pcaps
• --pcap-show print a line saying what pcap is currently being read
• --pedantic warnings are fatal
• --plugin-path <path> where to find plugins
• --process-all-events process all action groups
• --rule <rules> to be added to configuration; may be repeated
• --rule-to-hex output so rule header to stdout for text rule on stdin
• --rule-to-text output plain so rule header to stdout for text rule on stdin
• --run-prefix <pfx> prepend this to each output file
• --script-path <path> to a luajit script or directory containing luajit scripts
• --shell enable the interactive command line
• --show-plugins list module and plugin versions
• --skip <n> skip 1st n packets (0:)
• --snaplen <snap> set snaplen of packet (same as -s) (68:65535)
• --stdin-rules read rules from stdin until EOF or a line starting with END is read
• --treat-drop-as-alert converts drop, sdrop, and reject rules into alert rules during startup
• --treat-drop-as-ignore use drop, sdrop, and reject rules to ignore session traffic when not inline
• --version show version number (same as -V)
• --warn-all enable all warnings
• --warn-conf warn about configuration issues
• --warn-daq warn about DAQ issues, usually related to mode
• --warn-flowbits warn about flowbits that are checked but not set and vice-versa
• --warn-hosts warn about host table issues
• --warn-plugins warn about issues that prevent plugins from loading
• --warn-rules warn about duplicate rules and rule parsing issues
Snort++ User Manual 134 / 204
• -x same as --pedantic
• -y include year in timestamp in the alert and log files
• -z <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by
the system; default is 1 (0:)
16.8 Parameters
The parameter name may be adorned in various ways to indicate additional information about the type and use of the parameter:
• For Lua configuration (not IPS rules), if the name ends with [] it is a list item and can be repeated.
• For IPS rules only, names starting with ~ indicate positional parameters. The names of such parameters do not appear in the
rule.
Snort++ User Manual 136 / 204
• IPS rules may also have a wild card parameter, which is indicated by a *. Only used for metadata that Snort ignores.
• The snort module has command line options starting with a -.
• Table and variable names are case sensitive; use lower case only.
• String values are case sensitive too; use lower case only.
• Numeric ranges may be of the form low:high where low and high are bounds included in the range. If either is omitted, there
is no hard bound. E.g. 0: means any x where x >= 0.
• Strings may have a numeric range indicating a length limit; otherwise there is no hard limit.
• bit_list is typically used to store a set of byte, port, or VLAN ID values.
16.9 Configuration
• string ack.~range: check if packet payload size is size | min<>max | <max | >min
• int active.attempts = 0: number of TCP packets sent per response (with varying sequence numbers) { 0:20 }
• string active.device: use ip for network layer responses or eth0 etc for link layer
• string active.dst_mac: use format 01:23:45:67:89:ab
• int active.max_responses = 0: maximum number of responses { 0: }
• int active.min_interval = 255: minimum number of seconds between responses { 1: }
• multi alert_csv.fields = timestamp pkt_num proto pkt_gen dgm_len dir src_ap dst_ap rule action: selected fields will be output
in given order left to right { action | dir | dgm_len | dst_addr | dst_ap | dst_port | eth_dst | eth_len | eth_src | eth_type | gid |
icmp_code | icmp_id | icmp_seq | icmp_type | iface | ip_id | ip_len | msg | pkt_gen | pkt_num | proto | rev | rule | sid | src_addr |
src_ap | src_port | tcp_ack | tcp_flags | tcp_len | tcp_seq | tcp_win | timestamp | tos | ttl | udp_len }
• bool alert_csv.file = false: output to alert_csv.txt instead of stdout
• int alert_csv.limit = 0: set limit (0 is unlimited) { 0: }
• string alert_csv.separator = , : separate fields with this character sequence
• enum alert_csv.units = B: bytes | KB | MB | GB { B | K | M | G }
• bool alert_ex.upper = false: true/false → convert to upper/lower case
• bool alert_fast.file = false: output to alert_fast.txt instead of stdout
• int alert_fast.limit = 0: set limit (0 is unlimited) { 0: }
• bool alert_fast.packet = false: output packet dump with alert
• enum alert_fast.units = B: bytes | KB | MB | GB { B | K | M | G }
• bool alert_full.file = false: output to alert_full.txt instead of stdout
• int alert_full.limit = 0: set limit (0 is unlimited) { 0: }
• enum alert_full.units = B: limit is in bytes | KB | MB | GB { B | K | M | G }
• enum alert_syslog.facility = auth: part of priority applied to each message { auth | authpriv | daemon | user | local0 | local1 |
local2 | local3 | local4 | local5 | local6 | local7 }
• enum alert_syslog.level = info: part of priority applied to each message { emerg | alert | crit | err | warning | notice | info | debug
}
Snort++ User Manual 137 / 204
• multi alert_syslog.options: used to open the syslog connection { cons | ndelay | perror | pid }
• bool alerts.alert_with_interface_name = false: include interface in alert info (fast, full, or syslog only)
• bool alerts.default_rule_state = true: enable or disable ips rules
• int alerts.detection_filter_memcap = 1048576: set available memory for filters { 0: }
• int alerts.event_filter_memcap = 1048576: set available memory for filters { 0: }
• string alerts.order = pass drop alert log: change the order of rule action application
• int alerts.rate_filter_memcap = 1048576: set available memory for filters { 0: }
• string alerts.reference_net: set the CIDR for homenet (for use with -l or -B, does NOT change $HOME_NET in IDS mode)
• bool alerts.stateful = false: don’t alert w/o established session (note: rule action still taken)
• string alerts.tunnel_verdicts: let DAQ handle non-allow verdicts for GTP|Teredo|6in4|4in6 traffic
• ip4 arp_spoof.hosts[].ip: host ip address
• mac arp_spoof.hosts[].mac: host mac address
• int asn1.absolute_offset: Absolute offset from the beginning of the packet. { 0: }
• implied asn1.bitstring_overflow: Detects invalid bitstring encodings that are known to be remotely exploitable.
• implied asn1.double_overflow: Detects a double ASCII encoding that is larger than a standard buffer.
• int asn1.oversize_length: Compares ASN.1 type lengths with the supplied argument. { 0: }
• implied asn1.print: <>max | <max | >min
• int asn1.relative_offset: relative offset from the cursor.
• int attribute_table.max_hosts = 1024: maximum number of hosts in attribute table { 32:207551 }
• int attribute_table.max_metadata_services = 8: maximum number of services in rule metadata { 1:256 }
• int attribute_table.max_services_per_host = 8: maximum number of services per host entry in attribute table { 1:65535 }
• int base64_decode.bytes: Number of base64 encoded bytes to decode. { 1: }
• int base64_decode.offset = 0: Bytes past start of buffer to start decoding. { 0: }
• implied base64_decode.relative: Apply offset to cursor instead of start of buffer.
• enum binder[].use.action = inspect: what to do with matching traffic { reset | block | allow | inspect }
• string binder[].use.file: use configuration in given file
• string binder[].use.name: symbol name (defaults to type)
• string binder[].use.service: override automatic service identification
• string binder[].use.type: select module for binding
• bit_list binder[].when.ifaces: list of interface indices { 255 }
• addr_list binder[].when.nets: list of networks
• int binder[].when.policy_id = 0: unique ID for selection of this config by external logic { 0: }
• bit_list binder[].when.ports: list of ports { 65535 }
• enum binder[].when.proto: protocol { any | ip | icmp | tcp | udp | user | file }
• enum binder[].when.role = any: use the given configuration on one or any end of a session { client | server | any }
Snort++ User Manual 138 / 204
• int byte_extract.align = 0: round the number of converted bytes up to the next 2- or 4-byte boundary { 0:4 }
• implied byte_extract.big: big endian
• implied byte_extract.dce: dcerpc2 determines endianness
• string byte_test.~offset: variable name or number of bytes into the payload to start processing
• string byte_test.~operator: variable name or number of bytes into the buffer to start processing
• string classifications[].name: name used with classtype rule option
• int classifications[].priority = 1: default priority for class { 0: }
• enum http_inspect.profile.profile_type = default: set defaults appropriate for selected server { default | apache | iis | iis_40 |
iis_50 }
• int http_inspect.profile.server_flow_depth = 0: response payload to inspect; includes headers with extended_response_inspection
{ -1:65535 }
• int http_inspect.small_chunk_count = 5: alert if more than this limit of consecutive chunks are below small_chunk_length {
0:255 }
• int http_inspect.small_chunk_length = 10: alert if more than small_chunk_count consecutive chunks below this limit { 0:255
}
• bool http_inspect.tab_uri_delimiter = false: whether a tab not preceded by a space is considered a delimiter or part of URI
• bool http_inspect.unlimited_decompress = true: decompress across multiple packets
• bool http_inspect.xff_headers = false: not implemented
• string icmp_id.~range: check if icmp id is id | min<>max | <max | >min
• string icmp_seq.~range: check if icmp sequence number is seq | min<>max | <max | >min
• string icode.~range: check if ICMP code is code | min<>max | <max | >min
• string id.~range: check if the IP ID is id | min<>max | <max | >min
Snort++ User Manual 146 / 204
• bool ips.enable_builtin_rules = false: enable events from builtin rules w/o stubs
• int ips.id = 0: correlate unified2 events with configuration { 0:65535 }
• string ips.include: legacy snort rules and includes
• enum ips.mode: set policy mode { tap | inline | inline-test }
• string md5.offset: var or number of bytes from start of buffer to start search
• implied md5.relative = false: offset from cursor instead of start of buffer
• string md5.~hash: data to match
• string metadata.*: additional parameters not used by snort
• enum mpls.mpls_payload_type = ip4: set encapsulated payload type { eth | ip4 | ip6 }
• string msg.~: message describing rule
• multi network.checksum_drop = none: drop if checksum is bad { all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp |
none }
• multi network.checksum_eval = none: checksums to verify { all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none }
• bool network.decode_drops = false: enable dropping of packets by the decoder
• int network.id = 0: correlate unified2 events with configuration { 0:65535 }
• int network.layers = 40: The maximum number of protocols that Snort can correctly decode { 3:255 }
• int network.max_ip6_extensions = 0: The number of IP6 options Snort will process for a given IPv6 layer. If this limit is hit,
rule 116:456 may fire. 0 = unlimited { 0:255 }
• int network.max_ip_layers = 0: The maximum number of IP layers Snort will process for a given packet If this limit is hit,
rule 116:293 may fire. 0 = unlimited { 0:255 }
• int network.min_ttl = 1: alert / normalize packets with lower ttl / hop limit (you must enable rules and / or normalization also)
{ 1:255 }
• int network.new_ttl = 1: use this value for responses and when normalizing { 1:255 }
• int new_http_inspect.request_depth = -1: maximum request message body bytes to examine (-1 no limit) { -1: }
• int new_http_inspect.response_depth = -1: maximum response message body bytes to examine (-1 no limit) { -1: }
• bool new_http_inspect.unzip = true: decompress gzip and deflate message bodies
• bool normalizer.icmp4 = false: clear reserved flag
• bool normalizer.icmp6 = false: clear reserved flag
• bool normalizer.ip4.base = true: clear options
• bool normalizer.ip4.df = false: clear don’t frag flag
• bool normalizer.ip4.rf = false: clear reserved flag
• bool normalizer.ip4.tos = false: clear tos / differentiated services byte
• bool normalizer.ip4.trim = false: truncate excess payload beyond datagram length
• bool normalizer.ip6 = false: clear reserved flag
• string normalizer.tcp.allow_codes: don’t clear given option codes
• multi normalizer.tcp.allow_names: don’t clear given option names { sack | echo | partial_order | conn_count | alt_checksum |
md5 }
• bool normalizer.tcp.base = true: clear reserved bits and option padding and fix urgent pointer / flags issues
• bool normalizer.tcp.block = true: allow packet drops during TCP normalization
• select normalizer.tcp.ecn = off: clear ecn for all packets | sessions w/o ecn setup { off | packet | stream }
• bool normalizer.tcp.ips = false: ensure consistency in retransmitted data
• bool normalizer.tcp.opts = true: clear all options except mss, wscale, timestamp, and any explicitly allowed
• bool normalizer.tcp.pad = true: clear any option padding bytes
• bool normalizer.tcp.req_pay = true: clear the urgent pointer and the urgent flag if there is no payload
• bool normalizer.tcp.req_urg = true: clear the urgent pointer if the urgent flag is not set
Snort++ User Manual 148 / 204
• bool normalizer.tcp.req_urp = true: clear the urgent flag if the urgent pointer is not set
• bool normalizer.tcp.rsv = true: clear the reserved bits in the TCP header
• bool normalizer.tcp.trim = false: enable all of the TCP trim options
• bool output.dump_payload_verbose = false: dumps raw packet starting at link layer (same as -X)
• int output.event_trace.max_data = 0: maximum amount of packet data to capture { 0:65535 }
• bool output.log_ipv6_extra_data = false: log IPv6 source and destination addresses as unified2 extra data records
• int output.tagged_packet_limit = 256: maximum number of packets tagged for non-packet metrics { 0: }
• bool output.verbose = false: be verbose (same as -v)
• bool packets.address_space_agnostic = false: determines whether DAQ address space info is used to track fragments and
connections
• bool perf_monitor.reset = true: reset (clear) statistics after each reporting interval
• int perf_monitor.seconds = 60: report interval; 0 means report at exit only { 0: }
• string pkt_num.~range: check if packet number is in given range
• int pop.b64_decode_depth = 1460: base64 decoding depth { -1:65535 }
• string port_scan.ignore_scanned: list of CIDRs with optional ports to ignore if the destination of scan alerts
• string port_scan.ignore_scanners: list of CIDRs with optional ports to ignore if the source of scan alerts
• bool port_scan.include_midstream = false: list of CIDRs with optional ports
• bool port_scan.logfile = false: write scan events to file
• multi port_scan.protos = all: choose the protocols to monitor { tcp | udp | icmp | ip | all }
• multi port_scan.scan_types = all: choose type of scans to look for { portscan | portsweep | decoy_portscan | distributed_portscan
| all }
• enum port_scan.sense_level = medium: choose the level of detection { low | medium | high }
• string process.threads[].source: set cpu affinity for this source (either pcap or <iface>
• int process.threads[].thread = 0: set cpu affinity for the <cur_thread_num> thread that runs { 0: }
• string process.umask: set process umask (same as -m)
• bool process.utc = false: use UTC instead of local time for timestamps
• int profiler.memory.count = 0: limit results to count items per level (0 = no limit) { 0: }
• int profiler.memory.max_depth = -1: limit depth to max_depth (-1 = no limit) { -1: }
• bool profiler.memory.show = true: show module memory profile stats
• enum profiler.memory.sort = total_used: sort by given field { none | allocations | total_used | avg_allocation }
• int profiler.modules.count = 0: limit results to count items per level (0 = no limit) { 0: }
• int profiler.modules.max_depth = -1: limit depth to max_depth (-1 = no limit) { -1: }
• enum profiler.rules.sort = total_time: sort by given field { none | checks | avg_check | total_time | matches | no_matches |
avg_match | avg_no_match }
• string rate_filter[].apply_to: restrict filter to these addresses according to track
• int rate_filter[].count = 1: number of events in interval before tripping { 0: }
• bool search_engine.search_optimize = false: tweak state machine construction for better performance
• bool search_engine.split_any_any = false: evaluate any-any rules separately to save memory
• string seq.~range: check if packet payload size is size | min<>max | <max | >min
• enum session.~mode: output format { printable|binary|all }
• int sha256.length: number of octets in plain text { 1:65535 }
• string sha256.offset: var or number of bytes from start of buffer to start search
• implied sha256.relative = false: offset from cursor instead of start of buffer
• string sha256.~hash: data to match
• int sha512.length: number of octets in plain text { 1:65535 }
• string sha512.offset: var or number of bytes from start of buffer to start search
• implied sha512.relative = false: offset from cursor instead of start of buffer
• string sha512.~hash: data to match
• int sid.~: signature id { 1: }
• bool sip.ignore_call_channel = false: enables the support for ignoring audio/video data channel
• int sip.max_call_id_len = 256: maximum call id field size { 0:65535 }
• int sip.max_contact_len = 256: maximum contact field size { 0:65535 }
• int sip.max_content_len = 1024: maximum content length of the message body { 0:65535 }
• int sip.max_dialogs = 4: maximum number of dialogs within one stream session { 1:4194303 }
• int sip.max_from_len = 256: maximum from field size { 0:65535 }
• int sip.max_requestName_len = 20: maximum request name field size { 0:65535 }
• int sip.max_sessions = 10000: maximum number of sessions that can be allocated { 1024:4194303 }
• int sip.max_to_len = 256: maximum to field size { 0:65535 }
• int sip.max_uri_len = 256: maximum request uri field size { 0:65535 }
• int sip.max_via_len = 1024: maximum via field size { 0:65535 }
• string sip.methods = invite cancel ack bye register options: list of methods to check in sip messages
• string sip_method.*method: sip method
• int sip_stat_code.*code: stat code { 1:999 }
• string smtp.alt_max_command_line_len[].command: command string
• int smtp.alt_max_command_line_len[].length = 0: specify non-default maximum for command { 0: }
• string smtp.auth_cmds: commands that initiate an authentication exchange
• int smtp.b64_decode_depth = 25: depth used to decode the base64 encoded MIME attachments { -1:65535 }
• string smtp.binary_data_cmds: commands that initiate sending of data and use a length value after the command
• int smtp.bitenc_decode_depth = 25: depth used to extract the non-encoded MIME attachments { -1:65535 }
• string smtp.data_cmds: commands that initiate sending of data with an end of data delimiter
• int smtp.email_hdrs_log_depth = 1464: depth for logging email headers { 0:20480 }
Snort++ User Manual 153 / 204
• bool smtp.log_email_hdrs = false: log the SMTP email headers extracted from SMTP data
• bool smtp.log_filename = false: log the MIME attachment filenames extracted from the Content-Disposition header within
the MIME body
• bool smtp.log_mailfrom = false: log the sender’s email address extracted from the MAIL FROM command
• bool smtp.log_rcptto = false: log the recipient’s email address extracted from the RCPT TO command
• int smtp.max_command_line_len = 0: max Command Line Length { 0:65535 }
• int smtp.max_header_line_len = 0: max SMTP DATA header line { 0:65535 }
• implied snort.--alert-before-pass: process alert, drop, sdrop, or reject before pass; default is pass before alert, drop,. . .
• string snort.--bpf: <filter options> are standard BPF options, as seen in TCPDump
• string snort.--c2x: output hex for given char (see also --x2c)
• implied snort.--create-pidfile: create PID file, even when not in Daemon mode
• string snort.--dump-defaults: [<module prefix>] output module defaults in Lua format { (optional) }
• implied snort.--dump-dynamic-rules: output stub rules for all loaded rules libraries
• string snort.--dump-version: output the version, the whole version, and only the version { (optional) }
• implied snort.--enable-inline-test: enable Inline-Test Mode Operation
• implied ssl_state.!server_hello: check for records that are not server hello
• implied ssl_state.!server_keyx: check for records that are not server keyx
• implied ssl_state.!unknown: check for records that are not unknown
• implied ssl_state.client_hello: check for client hello
• implied ssl_state.client_keyx: check for client keyx
• implied ssl_state.server_hello: check for server hello
• implied ssl_state.server_keyx: check for server keyx
• implied ssl_state.unknown: check for unknown record
• implied ssl_version.!sslv2: check for records that are not sslv2
• implied ssl_version.!sslv3: check for records that are not sslv3
• implied ssl_version.!tls1.0: check for records that are not tls1.0
• implied ssl_version.!tls1.1: check for records that are not tls1.1
• implied ssl_version.!tls1.2: check for records that are not tls1.2
• implied ssl_version.sslv2: check for sslv2
• implied ssl_version.sslv3: check for sslv3
• implied ssl_version.tls1.0: check for tls1.0
• implied ssl_version.tls1.1: check for tls1.1
• implied ssl_version.tls1.2: check for tls1.2
• int stream.file_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.file_cache.max_sessions = 128: maximum simultaneous sessions tracked before pruning { 1: }
• int stream.file_cache.memcap = 0: maximum cache memory before pruning (0 is unlimited) { 0: }
• int stream.file_cache.pruning_timeout = 30: minimum inactive time before being eligible for pruning { 1: }
• int stream.icmp_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.icmp_cache.max_sessions = 32768: maximum simultaneous sessions tracked before pruning { 1: }
• int stream.icmp_cache.memcap = 1048576: maximum cache memory before pruning (0 is unlimited) { 0: }
• int stream.icmp_cache.pruning_timeout = 30: minimum inactive time before being eligible for pruning { 1: }
• int stream.ip_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.ip_cache.max_sessions = 16384: maximum simultaneous sessions tracked before pruning { 1: }
• int stream.ip_cache.memcap = 23920640: maximum cache memory before pruning (0 is unlimited) { 0: }
• int stream.ip_cache.pruning_timeout = 30: minimum inactive time before being eligible for pruning { 1: }
• int stream.tcp_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
• int stream.tcp_cache.max_sessions = 131072: maximum simultaneous sessions tracked before pruning { 1: }
• int stream.tcp_cache.memcap = 268435456: maximum cache memory before pruning (0 is unlimited) { 0: }
• int stream.tcp_cache.pruning_timeout = 30: minimum inactive time before being eligible for pruning { 1: }
• int stream.udp_cache.idle_timeout = 180: maximum inactive time before retiring session tracker { 1: }
Snort++ User Manual 158 / 204
16.10 Counts
• sip.2xx: 2xx
• sip.3xx: 3xx
• sip.4xx: 4xx
• sip.5xx: 5xx
• sip.6xx: 6xx
• sip.7xx: 7xx
• sip.8xx: 8xx
• sip.9xx: 9xx
• sip.ack: ack
• sip.bye: bye
• sip.cancel: cancel
• sip.dialogs: total dialogs
• sip.events: events generated
• sip.ignored channels: total channels ignored
• sip.ignored sessions: total sessions ignored
• sip.info: info
• sip.invite: invite
• sip.join: join
• sip.message: message
• sip.notify: notify
• sip.options: options
• sip.packets: total packets
• sip.prack: prack
• sip.refer: refer
• sip.register: register
• sip.sessions: total sessions
• sip.subscribe: subscribe
• sip.total requests: total requests
• sip.total responses: total responses
• sip.update: update
• smtp.b64 attachments: total base64 attachments decoded
• smtp.b64 decoded bytes: total base64 decoded bytes
• smtp.concurrent sessions: total concurrent smtp sessions
• smtp.max concurrent sessions: maximum concurrent smtp sessions
• smtp.non-encoded attachments: total non-encoded attachments extracted
Snort++ User Manual 168 / 204
16.11 Generators
• 105: back_orifice
• 106: rpc_decode
• 112: arp_spoof
• 116: arp
• 116: auth
• 116: decode
• 116: eapol
• 116: erspan2
• 116: erspan3
• 116: esp
• 116: eth
Snort++ User Manual 172 / 204
• 116: fabricpath
• 116: gre
• 116: gtp
• 116: icmp4
• 116: icmp6
• 116: igmp
• 116: ipv4
• 116: ipv6
• 116: mpls
• 116: pgm
• 116: pppoe
• 116: tcp
• 116: token_ring
• 116: udp
• 116: vlan
• 116: wlan
• 119: http_global
• 120: http_inspect
• 122: port_scan
• 123: stream_ip
• 124: smtp
• 125: ftp_server
• 126: telnet
• 128: ssh
• 129: stream_tcp
• 131: dns
• 134: ppm
• 136: reputation
• 137: ssl
• 140: sip
• 141: imap
• 142: pop
• 143: gtp_inspect
• 144: modbus
• 145: dce_smb
Snort++ User Manual 173 / 204
• 145: dce_tcp
• 145: dnp3
• 219: new_http_inspect
• 256: dpx
• 145:15 (dce_smb) SMB - Total data sent (STDu64) greater than command total data expected.
• 145:16 (dce_smb) SMB - Byte count less than command data size (STDu64)
• 145:17 (dce_smb) SMB - Invalid command data size for byte count.
• 145:18 (dce_smb) SMB - Excessive Tree Connect requests with pending Tree Connect responses.
• 145:19 (dce_smb) SMB - Excessive Read requests with pending Read responses.
• 145:20 (dce_smb) SMB - Excessive command chaining.
• 145:34 (dce_smb) Connection-oriented DCE/RPC - Fragment length on non-last fragment less than maximum negotiated
fragment transmit size for client.
• 145:34 (dce_tcp) Connection-oriented DCE/RPC - Fragment length on non-last fragment less than maximum negotiated frag-
ment transmit size for client.
• 145:35 (dce_smb) Connection-oriented DCE/RPC - Fragment length greater than maximum negotiated fragment transmit size.
• 145:35 (dce_tcp) Connection-oriented DCE/RPC - Fragment length greater than maximum negotiated fragment transmit size.
• 145:36 (dce_smb) Connection-oriented DCE/RPC - Alter Context byte order different from Bind
• 145:36 (dce_tcp) Connection-oriented DCE/RPC - Alter Context byte order different from Bind
• 145:37 (dce_smb) Connection-oriented DCE/RPC - Call id of non first/last fragment different from call id established for
fragmented request.
• 145:37 (dce_tcp) Connection-oriented DCE/RPC - Call id of non first/last fragment different from call id established for
fragmented request.
Snort++ User Manual 185 / 204
• 145:38 (dce_smb) Connection-oriented DCE/RPC - Opnum of non first/last fragment different from opnum established for
fragmented request.
• 145:38 (dce_tcp) Connection-oriented DCE/RPC - Opnum of non first/last fragment different from opnum established for
fragmented request.
• 145:39 (dce_smb) Connection-oriented DCE/RPC - Context id of non first/last fragment different from context id established
for fragmented request.
• 145:39 (dce_tcp) Connection-oriented DCE/RPC - Context id of non first/last fragment different from context id established
for fragmented request.
16.14 Signals
Important
Signal numbers are for the system that generated this documentation and are not applicable elsewhere.
• raw_data (ips_option): rule option to set the detection cursor to the raw packet data
• react (ips_action): send response to client and terminate session
• reference (ips_option): rule option to indicate relevant attack identification system
• references (basic): define reference systems used in rules
• regex (ips_option): rule option for matching payload data with hyperscan regex
• reject (ips_action): terminate session with TCP reset or ICMP unreachable
• rem (ips_option): rule option to convey an arbitrary comment in the rule body
• replace (ips_option): rule option to overwrite payload data; use with rewrite action
• reputation (inspector): reputation inspection
• rev (ips_option): rule option to indicate current revision of signature
• rewrite (ips_action): overwrite packet contents
• rpc (ips_option): rule option to check SUNRPC CALL parameters
• rpc_decode (inspector): RPC inspector
• rule_state (basic): enable/disable specific IPS rules
• search_engine (basic): configure fast pattern matcher
• seq (ips_option): rule option to check TCP sequence number
• session (ips_option): rule option to check user data from TCP sessions
• sha256 (ips_option): payload rule option for hash matching
• sha512 (ips_option): payload rule option for hash matching
• sid (ips_option): rule option to indicate signature number
• sip (inspector): sip inspection
• sip_body (ips_option): rule option to set the detection cursor to the request body
• sip_header (ips_option): rule option to set the detection cursor to the SIP header buffer
• sip_method (ips_option): detection option for sip stat code
• sip_stat_code (ips_option): detection option for sip stat code
• smtp (inspector): smtp inspection
• snort (basic): command line configuration and shell commands
• so (ips_option): rule option to call custom eval function
• soid (ips_option): rule option to specify a shared object rule ID
• ssh (inspector): ssh inspection
• ssl (inspector): ssl inspection
• ssl_state (ips_option): detection option for ssl state
• ssl_version (ips_option): detection option for ssl version
• stream (inspector): common flow tracking
• stream_file (inspector): stream inspector for file flow tracking and processing
Snort++ User Manual 198 / 204
• codec::wlan: support for wireless local area network protocol (DLT 105)
• inspector::arp_spoof: detect ARP attacks and anomalies
• inspector::back_orifice: back orifice detection
• inspector::binder: configure processing based on CIDRs, ports, services, etc.
• inspector::data_log: log selected published data to data.log
• inspector::dce_smb: dce over smb inspection
• inspector::dce_tcp: dce over tcp inspection
• inspector::dnp3: dnp3 inspection
• inspector::dns: dns inspection
• inspector::dpx: dynamic inspector example
• inspector::ftp_client: FTP inspector client module
• inspector::ftp_data: FTP data channel handler
• inspector::ftp_server: FTP inspector server module
• inspector::gtp_inspect: gtp control channel inspection
• inspector::http_global: shared HTTP inspector settings
• inspector::http_inspect: main HTTP inspector module
• inspector::imap: imap inspection
• inspector::modbus: modbus inspection
• inspector::new_http_inspect: the new HTTP inspector!
• inspector::normalizer: packet scrubbing for inline mode
• inspector::perf_monitor: performance monitoring and flow statistics collection
• inspector::pop: pop inspection
• inspector::port_scan: port scan inspector; also configure port_scan_global
• inspector::port_scan_global: shared settings for port_scan inspectors for use with port_scan
• inspector::reputation: reputation inspection
• inspector::rpc_decode: RPC inspector
• inspector::sip: sip inspection
• inspector::smtp: smtp inspection
• inspector::ssh: ssh inspection
• inspector::ssl: ssl inspection
• inspector::stream: common flow tracking
• inspector::stream_file: stream inspector for file flow tracking and processing
• inspector::stream_icmp: stream inspector for ICMP flow tracking
• inspector::stream_ip: stream inspector for IP flow tracking and defragmentation
• inspector::stream_tcp: stream inspector for TCP flow tracking and stream normalization and reassembly
Snort++ User Manual 201 / 204