Showing posts with label Cyber Security. Show all posts
Showing posts with label Cyber Security. Show all posts

Wednesday, August 18, 2021

TShark : Finding data with "contains" and "matches" (Regular Expression)

Recently, I've been working with the SANS Institute on some Livestream sessions, promoting the SEC503: Intrusion Detection In Depth class. As a result, I produced some videos using TShark. In the first of those videos, we did an intro to TShark by focusing on reconnaissance at the IP layer. In the second session, we focused on reconnaissance at the transport layer and working with some common application protocols. In the 3rd session, we extracted suspicious and malicious content from PCAPS.

In a session prior to these, I focused on Full Packet Capturing with TShark for Continuous Monitoring & Threat Intel via IP, Domains, & URLS. While I did not do blog posts for those (and I wish I had thought about it before),  I've chosen to do a blog post for the TShark and working with regular expressions

Many times, when looking at packets or logs, I leverage "grep --perl-regexp". However, when looking at packets for patterns, sequence of bytes, etc., do we really need to leverage grep or another external tool? Let's see.

In session three in which I exported suspicious and malicious content, I used the following for example to identify the name of the malicious file:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r attack-trace.pcap -V | grep ssms.exe
0030  63 68 6f 20 67 65 74 20 73 73 6d 73 2e 65 78 65   cho get ssms.exe
0070  26 73 73 6d 73 2e 65 78 65 0d 0a                  &ssms.exe..
0000  73 73 6d 73 2e 65 78 65 0d 0a                     ssms.exe..
0000  52 45 54 52 20 73 73 6d 73 2e 65 78 65 0d 0a      RETR ssms.exe..

... and the following example to identify bytes within the suspicious file.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# xxd -groupsize 1 -u decode-as.pcap | grep '0A 25 25 45'
0192b620: 72 65 66 0A 32 38 34 30 32 38 32 34 0A 25 25 45  ref.28402824.%%E

Let's now see how TShark can help us out here. First let's leverage the "contains" display filter:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'frame contains WWW.SecurityNik.com'

Oooops!! Looks like we are starting off on the wrong foot. No result was returned. Well the reason no result was returned, is because contains is case sensitive. Let's try this again.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'frame contains www.securitynik.com' -x | more                                        
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d 00 00 45 00 00 ae 95 8e 40 00 40 06 e9 5e   4...E.....@.@..^
0020  0a 00 02 0f 8e fb 20 53 e1 cc 00 50 14 d2 bd 46   ...... S...P...F
0030  00 00 fa 02 50 18 fa f0 bb fd 00 00 47 45 54 20   ....P.......GET 
0040  2f 32 30 31 38 2f 30 37 2f 68 6f 73 74 2d 62 61   /2018/07/host-ba
0050  73 65 64 2d 74 68 72 65 61 74 2d 68 75 6e 74 69   sed-threat-hunti
0060  6e 67 2d 77 69 74 68 2e 68 74 6d 6c 20 48 54 54   ng-with.html HTT
0070  50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 77 77 77   P/1.1..Host: www
0080  2e 73 65 63 75 72 69 74 79 6e 69 6b 2e 63 6f 6d   .securitynik.com
0090  0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 53 65   ..User-Agent: Se
00a0  63 75 72 69 74 79 4e 69 6b 20 54 65 73 74 69 6e   curityNik Testin
00b0  67 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a   g..Accept: */*..
00c0  0d 0a                                             ..

Much better! Important take away, is that contains is case sensitive. 

In the previous example, we looked at contents from the frame level. Let's move up to the IP layer.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'ip contains sans.org' -x | more                                                      
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d a8 d6 45 00 00 7c 54 40 40 00 40 06 8d cf   4...E..|T@@.@...
0020  0a 00 02 0f 2d 3c 1f 22 a3 0a 00 50 68 1a f9 d1   ....-<."...Ph...
0030  00 0b b8 02 50 18 fa f0 58 db 00 00 47 45 54 20   ....P...X...GET 
0040  2f 20 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74   / HTTP/1.1..Host
0050  3a 20 77 77 77 2e 73 61 6e 73 2e 6f 72 67 0d 0a   : www.sans.org..
0060  55 73 65 72 2d 41 67 65 6e 74 3a 20 53 65 63 75   User-Agent: Secu
0070  72 69 74 79 4e 69 6b 20 54 65 73 74 69 6e 67 0d   rityNik Testing.
0080  0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 0d 0a   .Accept: */*....

Making progress! Similarly, I look at the TCP layer

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'tcp contains siriuscom.com' -x | more                                                
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d e6 73 45 00 00 81 e1 00 40 00 40 06 ca c4   4..sE.....@.@...
0020  0a 00 02 0f d1 3b b1 67 c5 ba 00 50 af 30 ea 13   .....;.g...P.0..
0030  00 08 ca 02 50 18 fa f0 8f 25 00 00 47 45 54 20   ....P....%..GET 
0040  2f 20 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74   / HTTP/1.1..Host
0050  3a 20 77 77 77 2e 73 69 72 69 75 73 63 6f 6d 2e   : www.siriuscom.
0060  63 6f 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a   com..User-Agent:
0070  20 53 65 63 75 72 69 74 79 4e 69 6b 20 54 65 73    SecurityNik Tes
0080  74 69 6e 67 0d 0a 41 63 63 65 70 74 3a 20 2a 2f   ting..Accept: */
0090  2a 0d 0a 0d 0a                                    *....

And finally, let's look at the application layer.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.host contains "www.siriuscom.com"' -x | more
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d e6 73 45 00 00 81 e1 00 40 00 40 06 ca c4   4..sE.....@.@...
0020  0a 00 02 0f d1 3b b1 67 c5 ba 00 50 af 30 ea 13   .....;.g...P.0..
0030  00 08 ca 02 50 18 fa f0 8f 25 00 00 47 45 54 20   ....P....%..GET 
0040  2f 20 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74   / HTTP/1.1..Host
0050  3a 20 77 77 77 2e 73 69 72 69 75 73 63 6f 6d 2e   : www.siriuscom.
0060  63 6f 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a   com..User-Agent:
0070  20 53 65 63 75 72 69 74 79 4e 69 6b 20 54 65 73    SecurityNik Tes
0080  74 69 6e 67 0d 0a 41 63 63 65 70 74 3a 20 2a 2f   ting..Accept: */
0090  2a 0d 0a 0d 0a                                    *....

Contains is a really a hex filter. If there is no colon after the first byte, the input is considered as ASCII.

Let's see some different ways we can detect "sans".

A similar (not the same) display filter may look like: 'dns.qry.name == "www.sans.org"'. Do note, I say similar because the first one is not fully www.sans.org but just the string sans.

First up, using hex escaped characters.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns.qry.name contains "\x73\x61\x6e\x73"' -x | more
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d 00 00 45 00 00 3a e9 8a 40 00 40 11 05 0c   4...E..:..@.@...
0020  0a 00 02 0f 40 47 ff c6 e1 93 00 35 00 26 4c 54   ....@G.....5.&LT
0030  da 6f 01 00 00 01 00 00 00 00 00 00 03 77 77 77   .o...........www
0040  04 73 61 6e 73 03 6f 72 67 00 00 01 00 01         .sans.org.....

Next up, using a combination of ASCII and hex escaped characters.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns.qry.name contains "www.\x73\x61\x6e\x73.org"' -x | more
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d 00 00 45 00 00 3a e9 8a 40 00 40 11 05 0c   4...E..:..@.@...
0020  0a 00 02 0f 40 47 ff c6 e1 93 00 35 00 26 4c 54   ....@G.....5.&LT
0030  da 6f 01 00 00 01 00 00 00 00 00 00 03 77 77 77   .o...........www
0040  04 73 61 6e 73 03 6f 72 67 00 00 01 00 01         .sans.org.....

Finally, looking at the bytes separated by colons

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns.qry.name contains 73:61:6e:73' -x | more                                         
0000  08 00 00 00 00 00 00 02 00 01 04 06 08 00 27 0e   ..............'.
0010  34 8d 00 00 45 00 00 3a e9 8a 40 00 40 11 05 0c   4...E..:..@.@...
0020  0a 00 02 0f 40 47 ff c6 e1 93 00 35 00 26 4c 54   ....@G.....5.&LT
0030  da 6f 01 00 00 01 00 00 00 00 00 00 03 77 77 77   .o...........www
0040  04 73 61 6e 73 03 6f 72 67 00 00 01 00 01         .sans.org.....


Let's now look at regular expression using matches;

When using matches, the filter expression is processed twice. Once by the Wireshark display filter engine and the second by PCRE library

Because of above, you are better of using \\. rather than \. when using matches for the dot/period.

While contains is good for finding a particular string, what about if you want to find a particular pattern. This is where matches is helpful. To see the power of matches, let's look at it first through the lens of "contains".

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y '(http.request.method contains GET) || (http.request.method contains POST)' | more 
   13   5.134106    10.0.2.15 → 142.251.32.83 HTTP 194 GET /2018/07/host-based-threat-hunting-with.html HTTP/1.1 
  344  47.459625    10.0.2.15 → 142.251.41.83 HTTP 194 GET /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  634  64.722770    10.0.2.15 → 209.59.177.103 HTTP 149 GET / HTTP/1.1 
  722  84.262193    10.0.2.15 → 45.60.31.34  HTTP 144 GET / HTTP/1.1 
  809 163.016781    10.0.2.15 → 45.60.31.34  HTTP 145 POST / HTTP/1.1 
  861 174.261670    10.0.2.15 → 209.59.177.103 HTTP 150 POST / HTTP/1.1 
  917 186.636330    10.0.2.15 → 142.251.33.179 HTTP 195 POST /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  933 200.366293    10.0.2.15 → 172.217.165.19 HTTP 195 POST /2018/07/host-based-threat-hunting-with.html HTTP/1.1 

As can be seen above, contains was able to help us find the match. However, it took a little bit more bytes. A little bit more typing. Let's see what matches.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.request.method matches "(GET|POST)"' | more
   13   5.134106    10.0.2.15 → 142.251.32.83 HTTP 194 GET /2018/07/host-based-threat-hunting-with.html HTTP/1.1 
  344  47.459625    10.0.2.15 → 142.251.41.83 HTTP 194 GET /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  634  64.722770    10.0.2.15 → 209.59.177.103 HTTP 149 GET / HTTP/1.1 
  722  84.262193    10.0.2.15 → 45.60.31.34  HTTP 144 GET / HTTP/1.1 
  809 163.016781    10.0.2.15 → 45.60.31.34  HTTP 145 POST / HTTP/1.1 
  861 174.261670    10.0.2.15 → 209.59.177.103 HTTP 150 POST / HTTP/1.1 
  917 186.636330    10.0.2.15 → 142.251.33.179 HTTP 195 POST /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  933 200.366293    10.0.2.15 → 172.217.165.19 HTTP 195 POST /2018/07/host-based-threat-hunting-with.html HTTP/1.1 

As can been seen above, matches have allowed us to simplify the process using regular expression. Above, we simply looked for GET or POST. That was easy!

If you remember from above, contains is case sensitive. Matches, is however case insensitive.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.request.method matches "(get|post)"'
   13   5.134106    10.0.2.15 → 142.251.32.83 HTTP 194 GET /2018/07/host-based-threat-hunting-with.html HTTP/1.1 
  344  47.459625    10.0.2.15 → 142.251.41.83 HTTP 194 GET /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  634  64.722770    10.0.2.15 → 209.59.177.103 HTTP 149 GET / HTTP/1.1 
  722  84.262193    10.0.2.15 → 45.60.31.34  HTTP 144 GET / HTTP/1.1 
  809 163.016781    10.0.2.15 → 45.60.31.34  HTTP 145 POST / HTTP/1.1 
  861 174.261670    10.0.2.15 → 209.59.177.103 HTTP 150 POST / HTTP/1.1 
  917 186.636330    10.0.2.15 → 142.251.33.179 HTTP 195 POST /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  933 200.366293    10.0.2.15 → 172.217.165.19 HTTP 195 POST /2018/07/host-based-threat-hunting-with.html HTTP/1.1 

As seen above, even those get and post are in lowercase, we still got results returned. This is unlike what was experienced with contains.

If we wanted to enforce the case sensitivity, we can use (?-i). We know from the previous command that both GET and POST methods are in this PCAP and in uppercase. Let's look for uppercase GET and lowercase POST. Remember we are showing how to handle case sensitivity not insensitivity.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.request.method matches "(?-i)(GET|post)"'
   13   5.134106    10.0.2.15 → 142.251.32.83 HTTP 194 GET /2018/07/host-based-threat-hunting-with.html HTTP/1.1 
  344  47.459625    10.0.2.15 → 142.251.41.83 HTTP 194 GET /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  634  64.722770    10.0.2.15 → 209.59.177.103 HTTP 149 GET / HTTP/1.1 
  722  84.262193    10.0.2.15 → 45.60.31.34  HTTP 144 GET / HTTP/1.1 

From the results returned, we can see only GET and not post. This is because we enforced case sensitivity as in we asked for GET in uppercase and POST in lowercase

Let's now see if there is any other method other than GET or POST.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.request.method matches "[^(get|post)]"'

No results were returned. This suggests there are no other HTTP methods in the file. Let's confirm that our command is working as expected and that this is not a false negative situation. To confirm this actually works, let's remove the "post". If it works, we should see post as we are negating the get.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'http.request.method matches "[^(get)]"'
  809 163.016781    10.0.2.15 → 45.60.31.34  HTTP 145 POST / HTTP/1.1 
  861 174.261670    10.0.2.15 → 209.59.177.103 HTTP 150 POST / HTTP/1.1 
  917 186.636330    10.0.2.15 → 142.251.33.179 HTTP 195 POST /2018/07/understanding-ip-fragmentation.html HTTP/1.1 
  933 200.366293    10.0.2.15 → 172.217.165.19 HTTP 195 POST /2018/07/host-based-threat-hunting-with.html HTTP/1.1 

Good stuff! We have results so we know our filter is correct. Sometimes, you need to find other ways to validate your command works.

There might be times when you know the first or first few and probably the last or last few letters. Matches can help here too! Let's say we are aware of a DNS request or response starting and ending with "s", has 2 characters in the middle but you not sure what those characters are. We can use the following:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns matches "s..s"'
  715  84.199441    10.0.2.15 → 64.71.255.198 DNS 78 Standard query 0xda6f A www.sans.org
  716  84.199465    10.0.2.15 → 64.71.255.198 DNS 78 Standard query 0x686d AAAA www.sans.org
  717  84.222652 64.71.255.198 → 10.0.2.15    DNS 165 Standard query response 0x686d AAAA www.sans.org SOA ns-1746.awsdns-26.co.uk

What about those times when it has x or more characters in the middle? Below it has 5 or more characters

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns matches "sec.{5,}com"'                                                           
    3   0.000235    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x4872 A www.securitynik.com
    4   0.000241    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x0d7d AAAA www.securitynik.com
    5   0.150729 64.71.255.198 → 10.0.2.15    DNS 166 Standard query response 0x4872 A www.securitynik.com CNAME www.securitynik.com.ghs.googlehosted.com CNAME ghs.googlehosted.com A 172.217.165.19

Similarly, we can say we would only like to see results where there is a minimum of 1 or a maximum of 3 characters after the s:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'dns matches "s.{1,3}\.org"'
  715  84.199441    10.0.2.15 → 64.71.255.198 DNS 78 Standard query 0xda6f A www.sans.org
  716  84.199465    10.0.2.15 → 64.71.255.198 DNS 78 Standard query 0x686d AAAA www.sans.org
  717  84.222652 64.71.255.198 → 10.0.2.15    DNS 165 Standard query response 0x686d AAAA www.sans.org SOA ns-1746.awsdns-26.co.uk

Let's say, we have a PCAP file with the following IP addresses:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap  -T fields -e ip.src | sort | uniq
10.0.2.15
10.0.2.2
142.251.32.83
142.251.33.179
142.251.41.83
172.217.1.19
172.217.165.19
209.59.177.103
45.60.31.34
64.71.255.198

What we need to do now, is to extract the IPs where octet 1 starts with 142. Octet 2 only contains the number 1, 2 or 5 and up to 3 numbers. Octet 3 can only be 32 or 33. Octet 4 can only have be 3 numbers anywhere between 0 and 9.

Let's say we to look for source IPs that match a particular pattern. In this case let's just say 142.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'ip.src matches "142"' | more
tshark: ip.src (type=IPv4 address) cannot participate in 'matches' comparison.

Ooops! Looks like we got an error about type mismatch. Let's convert this IPv4 address type field to a string and build out our filter at the same time. Our filter will look for a source IP address which starts with 142 in the first octet. The second octet should only consist of the number 1, 2 or 5. The third octet has to be either the number 32 or 33 and the final octet can be any 3 digit number between 0 and 9.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'string(ip.src) matches "^142\\.[1,2,5]{1,3}\\.(32|33)\\.[0-9]{3}"' -T fields -e ip.src | sort | uniq
142.251.33.179

A little bit more detail of the same filter.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'string(ip.src) matches "^142\\.[1,2,5]{1,3}\\.(32|33)\\.[0-9]{3}"'
  915 186.636198 142.251.33.179 → 10.0.2.15    TCP 66 80 → 37398 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460
  918 186.636629 142.251.33.179 → 10.0.2.15    TCP 66 80 → 37398 [ACK] Seq=1 Ack=136 Win=65535 Len=0
  919 186.651759 142.251.33.179 → 10.0.2.15    TCP 1490 HTTP/1.0 411 Length Required  [TCP segment of a reassembled PDU]
  921 186.653506 142.251.33.179 → 10.0.2.15    HTTP 355 HTTP/1.0 411 Length Required  (text/html)
  922 186.653509 142.251.33.179 → 10.0.2.15    TCP 66 80 → 37398 [FIN, ACK] Seq=1726 Ack=136 Win=65535 Len=0
  925 186.653877 142.251.33.179 → 10.0.2.15    TCP 66 80 → 37398 [ACK] Seq=1727 Ack=137 Win=65535 Len=0

Similarly, let's look for destinations:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap  -T fields -e ip.dst | sort | uniq
10.0.0.100
10.0.2.15
142.251.32.83
142.251.33.179
142.251.41.83
172.217.1.19
172.217.165.19
209.59.177.103
45.60.31.34
64.71.255.198

Let's now extract the destinations where we have the first octet starts with 2 numbers between 0 and 9. The second octet is exactly 0. The third octet can only have 1 number and it can only be 0 or 2. Octet 4, ends with either 100 or 15. 

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'string(ip.dst) matches "^[0-9]{2}\\.0\\.[0,2]{1}\\.(100|15)$"' -T fields -e ip.dst | sort | uniq
10.0.0.100
10.0.2.15

Let's now wrap this up by grabbing some frames numbers. First up, the first frame:

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'string(frame.number) matches "^1$"'
    1   0.000000 08:00:27:0e:34:8d →              ARP 48 Who has 10.0.2.2? Tell 10.0.2.15

Next, frames 1 to 9.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y 'string(frame.number) matches "^[0-9]$"'
    1   0.000000 08:00:27:0e:34:8d →              ARP 48 Who has 10.0.2.2? Tell 10.0.2.15
    2   0.000154 52:54:00:12:35:02 →              ARP 66 10.0.2.2 is at 52:54:00:12:35:02
    3   0.000235    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x4872 A www.securitynik.com
    4   0.000241    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x0d7d AAAA www.securitynik.com
    5   0.150729 64.71.255.198 → 10.0.2.15    DNS 166 Standard query response 0x4872 A www.securitynik.com CNAME www.securitynik.com.ghs.googlehosted.com CNAME ghs.googlehosted.com A 172.217.165.19
    6   5.004124    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x4872 A www.securitynik.com
    7   5.106980 64.71.255.198 → 10.0.2.15    DNS 166 Standard query response 0x4872 A www.securitynik.com CNAME www.securitynik.com.ghs.googlehosted.com CNAME ghs.googlehosted.com A 142.251.32.83
    8   5.107044    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x0d7d AAAA www.securitynik.com
    9   5.119889 64.71.255.198 → 10.0.2.15    DNS 178 Standard query response 0x0d7d AAAA www.securitynik.com CNAME www.securitynik.com.ghs.googlehosted.com CNAME ghs.googlehosted.com AAAA 2607:f8b0:400b:807::2013

Ok! I one more. We Took advantage of various fields by their names. Let's instead close this off my look at combination of offset and field.

┌──(rootđź’€securitynik)-[~/tshark-series]
└─# tshark -n -r securitynik_regex.pcap -Y '(udp[25:] matches "s.{10,20}\.com") && (string(ip.src) matches "^[0-9]{2}\\.0\\.[0,2]{1}\\.(15)$")' | more
    3   0.000235    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x4872 A www.securitynik.com
    4   0.000241    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x0d7d AAAA www.securitynik.com
    6   5.004124    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x4872 A www.securitynik.com
    8   5.107044    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x0d7d AAAA www.securitynik.com
   17   5.282030    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x3e8d A www.securitynik.com
   18   5.282048    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x6688 AAAA www.securitynik.com
  337  47.326990    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x7c44 A www.securitynik.com
  338  47.327019    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x8443 AAAA www.securitynik.com
  348  47.549609    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x5543 A www.securitynik.com
  349  47.549690    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x677e AAAA www.securitynik.com
  910 186.517304    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x49f7 A www.securitynik.com
  911 186.517330    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x9bf2 AAAA www.securitynik.com
  926 200.282904    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x2bdf A www.securitynik.com
  927 200.282930    10.0.2.15 → 64.71.255.198 DNS 85 Standard query 0x1cd0 AAAA www.securitynik.com

Ok! Well that's it for finding data using TShark's contain and matches. Obviously, we don't have to use additional tools such as grep to find data within packets. However, you may still find grep helpful in many other cases.

References:
securitynik_regex.pcap - PCAP used above 

https://sharkfestus.wireshark.org/assets/presentations16/16.pdf
https://www.wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html
https://www.cellstream.com/reference-reading/tipsandtricks/431-finding-text-strings-in-wireshark-captures
https://www.cellstream.com/resources/2013-09-10-11-55-21/cellstream-public-documents/wireshark-related/83-wireshark-display-filter-cheat-sheet/file
https://www.securityinbits.com/malware-analysis/tools/wireshark-filters/
https://blog.packet-foo.com/2013/05/the-notorious-wireshark-out-of-memory-problem/
https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_GRegex.html
https://luca.ntop.org/gr2021/altre_slides/CorsoWireshark.pdf
https://stackoverflow.com/questions/9655164/regex-ignore-case-sensitivity
https://www.hscripts.com/tutorials/regular-expression/metacharacter-list.php

Friday, February 5, 2021

Snort3 on Ubuntu 20 - The Initial Setup

Now that Cisco has released Snort3 via general availability, I decided to do a quick 4 part series on its installation, learning a little about Snort3, feeding the pig and Snort3 housekeeping.

Back in 2014, I did a post on "Building snort 3.0 (snort++)". With 6 years elapsing, I wanted to see what has changed with the installation and thus this new series.

Additionally and more importantly, I'm sure we will eventually transition the SANS SEC503 Intrusion Detection in Depth class to Snort3. When we do, I doubt whether we will show you how to install and configure Snort3. Thus this 4 part series and the associated reference materials below, are also being made available, so our SEC503 students are in a position to have the resources readily available, if and or when they choose to perform an install and or configuration of Snort3.

For this post, we will leverage my previous post in conjunction with Snort 3.1.0.0 on Ubuntu 18 & 20 - Configuring a Full NIDS & SIEM by Noah Dietrich from the snort.org website as well as additional information from other sources.

This is all based on a clean installation of Ubuntu 20 minimal install on VirtualBox.

1
2
3
4
5
6
securitynik@snort3:~$ lsb_release --all
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.1 LTS
Release:	20.04
Codename:	focal

Note: If you choose to install VirtualBox tools from the "CD", you may get an error about  "**This system is currently not set up to build kernel modules.". To resolve, this execute:

1
securitynik@snort3:~$ sudo apt install virtualbox-guest-utils virtualbox-guest-dkms

As always, we expect your system to be fully updated and hardened. There are various hardening guides online, such as those from the Center For Internet Security. However, to ensure your system is at least updated, run the following:

1
securitynik@snort3:~$ sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade -y

Depending on your install you may also need to install gcc and make

1
securitynik@snort3:~$ sudo apt-get install gcc make

Time if of great importance. To ensure your system time reflects your time zone, use the following commands. Note, also that you should consider taking advantage of NTP as I've done below, rather than manually configuring your time.

First list the available time zones

securitynik@snort3:~$ sudo timedatectl list-timezones
Africa/Abidjan
Africa/Accra
Africa/Algiers

....
America/Tijuana
America/Toronto
America/Vancouver
America/Whitehorse
America/Winnipeg
....

I will set mine as America/Toronto, while I set my time to UTC time and use a NTP server. Local time can be problematic when using NTP, as the time may not be properly updated during shifts to and from daylight saving time.

securitynik@snort3:~$ sudo timedatectl set-timezone America/Toronto
securitynik@snort3:~$ sudo timedatectl set-local-rtc False
securitynik@snort3:~$ sudo timedatectl set-ntp True

Verifying the time configuration.

securitynik@snort3:~$ sudo timedatectl 
               Local time: Wed 2021-01-27 11:14:29 EST 
           Universal time: Wed 2021-01-27 16:14:29 UTC 
                 RTC time: Wed 2021-01-27 16:14:29     
                Time zone: America/Toronto (EST, -0500)
System clock synchronized: yes                         
              NTP service: active                      
          RTC in local TZ: no

Do note, if you are monitoring intrusion events (via Snort, SIEM or any other tool) across different time zones, you are better off having your systems in UTC time. This makes it easy to correlate activities across these various time zones. 

With time properly configured, let's now install Snort3 by starting with its dependencies.

In my previous install, I did a lot of compiling of code. It looks like that is still the case at this time and will probably be that way for a while. I hope sooner rather than later, it is incorporated within a package manager.

Let's first create a directory to store our downloaded files

securitynik@snort3:~$ pwd
/home/securitynik
securitynik@snort3:~$ mkdir snort-files
securitynik@snort3:~$ cd snort-files/

Now that we are inside the snort-files folder, let's grab the pre-requisites.

securitynik@snort3:~/snort-files$ sudo apt-get install -y build-essential \ 
autotools-dev libdumbnet-dev libluajit-5.1-dev libpcap-dev zlib1g-dev \
pkg-config libhwloc-dev cmake liblzma-dev openssl libssl-dev cpputest \ 
libsqlite3-dev libtool uuid-dev git autoconf bison flex libcmocka-dev \
libnetfilter-queue-dev libunwind-dev libmnl-dev ethtool

Next install Safe C Library (safeclib) from GitHub.

securitynik@snort3:~/snort-files$ git clone https://github.com/rurban/safeclib.git
securitynik@snort3:~/snort-files$ cd safeclib/
securitynik@snort3:~/snort-files/safeclib$ build-aux/autogen.sh
securitynik@snort3:~/snort-files/safeclib$ ./configure && make && sudo make install

Next we install pcre-8.44 as specified so that we can leverage Hyperscan for fast pattern matching.

securitynik@snort3:~/snort-files$ wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
securitynik@snort3:~/snort-files$ tar --extract --verbose --gzip --file pcre-8.44.tar.gz
securitynik@snort3:~/snort-files$ cd pcre-8.44/
securitynik@snort3:~/snort-files/pcre-8.44$ ./configure && make && sudo make install

After pcre-8.44 we next install gperftools (originally Google Performance Tools)

securitynik@snort3:~/snort-files$ git clone https://github.com/gperftools/gperftools.git
securitynik@snort3:~/snort-files/gperftools$ cd gperftools
securitynik@snort3:~/snort-files/gperftools$ ./autogen.sh 
securitynik@snort3:~/snort-files/gperftools$ ./configure && make && sudo make install

Next up install Ragel State Machine Compiler. If you wish to install the latest version as of this writing which is 7.0.3, you will need to install Colm Programming Language. I stuck with version 6 as described in the Snort document as Colm produced some errors which I did not wish to spend much time troubleshooting .

securitynik@snort3:~/snort-files$ wget http://www.colm.net/files/ragel/ragel-6.10.tar.gz
securitynik@snort3:~/snort-files$ tar --extract --gzip --verbose --file ragel-6.10.tar.gz 
securitynik@snort3:~/snort-files$ cd ragel-6.10/
securitynik@snort3:~/snort-files/ragel-6.10$ ./configure && make && sudo make install

Next up, we download but DO NOT install boost c++ libraries. We also verify the file hash based on the SHA256 Hash from the website.

securitynik@snort3:~/snort-files$ wget https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz

securitynik@snort3:~/snort-files$ sha256sum boost_1_75_0.tar.gz 
aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a  boost_1_75_0.tar.gz

securitynik@snort3:~/snort-files$ tar --extract --verbose --file boost_1_75_0.tar.gz 

Let's grab Hyperscan.

securitynik@snort3:~/snort-files$ git clone https://github.com/intel/hyperscan
securitynik@snort3:~/snort-files$ cd hyperscan
securitynik@snort3:~/snort-files/hyperscan$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBOOST_ROOT=~/snort-files/boost_1_75_0/ ../hyperscan/
securitynik@snort3:~/snort-files/hyperscan$ make && sudo make install

Install flatbuffers

securitynik@snort3:~/snort-files$ git clone https://github.com/google/flatbuffers.git
securitynik@snort3:~/snort-files$ mkdir flatbuffers-build
securitynik@snort3:~/snort-files$ cd flatbuffers-build/
securitynik@snort3:~/snort-files/flatbuffers-build$ cmake ../flatbuffers
securitynik@snort3:~/snort-files/flatbuffers-build$ make && sudo make install

Next up, install the Data Acquisition Library (DAQ)

securitynik@snort3:~/snort-files$ git clone https://github.com/snort3/libdaq.git
securitynik@snort3:~/snort-files$ cd libdaq/
securitynik@snort3:~/snort-files/libdaq$ ./bootstrap 
securitynik@snort3:~/snort-files/libdaq$ ./configure && make && sudo make install

Wheewwww! That is a lot of pre-prequisites. Hopefully, they can package all of these up via package manager to make the install process easier. Note, if you don't install them in the order provided, you can expect to find one or more products complaining about dependency related to other products.

Finally, lets update the shared libraries.

securitynik@snort3:~$ sudo ldconfig

Now for the main course. Let's install Snort3. Because sometime after this install I would like to see what the command shell looks like, I'm also enabling that via the configure script along with the ability to process PCAPs over two Gigabytes.

securitynik@snort3:~/snort-files$ wget https://www.snort.org/downloads/snortplus/snort3-3.1.0.0.tar.gz
securitynik@snort3:~/snort-files$ tar --extract --verbose --gzip --file snort3-3.1.0.0.tar.gz 
securitynik@snort3:~/snort-files$ cd snort3-3.1.0.0/
securitynik@snort3:~/snort-files/snort3-3.1.0.0$ ./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc  --enable-shell --enable-large-pcap  
securitynik@snort3:~/snort-files/snort3-3.1.0.0$ cd build/
securitynik@snort3:~/snort-files/snort3-3.1.0.0/build$ make && sudo make install

Once I run snort --version, we see wat seems to suggest we are good to go.

scuritynik@snort3:~$ snort --version

   ,,_     -*> Snort++ <*-
  o"  )~   Version 3.1.0.0
   ''''    By Martin Roesch & The Snort Team
           http://snort.org/contact#team
           Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
           Copyright (C) 1998-2013 Sourcefire, Inc., et al.
           Using DAQ version 3.0.0
           Using LuaJIT version 2.1.0-beta3
           Using OpenSSL 1.1.1f  31 Mar 2020
           Using libpcap version 1.9.1 (with TPACKET_V3)
           Using PCRE version 8.44 2020-02-12
           Using ZLIB version 1.2.11
           Using FlatBuffers 1.12.0
           Using Hyperscan version 5.4.0 2021-01-28
           Using LZMA version 5.2.4

Running a test using the default configuration, we see below Snort successfully validated the configuration (with 0 warnings).

securitynik@snort3:~$ snort -c /usr/local/etc/snort/snort.lua 
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
Loading /usr/local/etc/snort/snort.lua:
Loading snort_defaults.lua:
Finished snort_defaults.lua:
Loading file_magic.lua:
Finished file_magic.lua:
	ssh
	hosts
	host_cache
	pop
	...
	stream_file
Finished /usr/local/etc/snort/snort.lua:
--------------------------------------------------
pcap DAQ configured to passive.

Snort successfully validated the configuration (with 0 warnings).
o")~   Snort exiting

Oink! Onik! Our piggy is preparing to fly. See you in the next post where we learn a little bit more about Snort3 before feeding it via rules and performing house keeping.


References:

https://www.snort.org/snort3

https://snort.org/documents

https://www.snort.org/downloads

https://www.securitynik.com/2014/12/building-snort-30-snort.html

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/003/979/original/Snort3_3.1.0.0_on_Ubuntu_18___20.pdf

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/000/175/original/Snort_3_Multiple_Packet_Threads_Processing.pdf

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/000/013/original/Snort_IPS_using_DAQ_AFPacket.pdf

https://www.youtube.com/watch?v=W1pb9DFCXLw&list=PLpPXZRVU-dX33VNUeqWrMmBNf5FeKVmi-&index=1

https://askubuntu.com/questions/1140770/this-system-is-currently-not-set-up-to-build-kernel-modules-please-install-the

https://github.com/rurban/safeclib

https://www.hyperscan.io/

https://github.com/intel/hyperscan

https://github.com/gperftools/gperftools

https://www.colm.net/open-source/ragel/

https://www.boost.org/

http://google.github.io/flatbuffers/

https://www.snort.org/faq/readme-daq

http://manual-snort-org.s3-website-us-east-1.amazonaws.com/node7.html

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/000/023/original/ids2ips.txt

https://github.com/snort3/libdaq

https://snort-org-site.s3.amazonaws.com/production/release_files/files/000/016/344/original/snort_reference.html

https://snort-org-site.s3.amazonaws.com/production/release_files/files/000/016/343/original/snort_user.html

https://snort-org-site.s3.amazonaws.com/production/release_files/files/000/016/342/original/snort_devel.html

https://blog.snort.org/2015/03/basic-snort-usage.html

https://geekflare.com/nginx-error-while-loading-shared-libraries-libpcre-so-1/

https://usermanual.wiki/Document/snortmanual.1752822391.pdf

https://www.youtube.com/watch?v=PYP0YH2PVuo&list=PLpPXZRVU-dX33VNUeqWrMmBNf5FeKVmi-&index=2

https://www.usenix.org/sites/default/files/conference/protected-files/nsdi19_slides_wang_xiang.pdf

Snort3 on Ubuntu 20 - Learning a little about our installation - Getting Help, Running Snort3, etc

In the previous post, we performed the install of Snort3. In this post, we learn a little about Snort3 before we start feeding it via rules and then perform some housekeeping.

Getting help!

securitynik@snort3:~$ snort --help

Snort has several options to get more help:

-? list command line options (same as --help)
--help this overview of help
--help-commands [<module prefix>] output matching commands
--help-config [<module prefix>] output matching config options
--help-counts [<module prefix>] output matching peg counts
--help-limits print the int upper bounds denoted by max*
--help-module <module> output description of given module
--help-modules list all available modules with brief help
....

To get help for a particular component, we can then say.

securitynik@snort3:~$ snort --help-commands
appid.enable_debug(proto, src_ip, src_port, dst_ip, dst_port): enable appid debugging
appid.disable_debug(): disable appid debugging
appid.reload_third_party(): reload appid third-party module
appid.reload_detectors(): reload appid detectors
host_cache.dump(file_name): dump host cache
...

To learn about the plugins

securitynik@snort3:~$ snort --list-plugins | more
codec::arp v0 static
codec::auth v0 static
codec::bad_proto v0 static
codec::ciscometadata v0 static
codec::erspan2 v0 static
codec::erspan3 v0 static
codec::esp v0 static
codec::eth v0 static
codec::fabricpath v0 static
codec::gre v0 static
....

To see some of the command line options available, you can look at the --help-options.

securitynik@snort3:~$ snort --help-options
-? <option prefix> output matching command line option quick help (same as --help-options) (optional)
-A <mode> set alert mode: none, cmg, or alert_*
-B <mask> obfuscated IP addresses in alerts and packet dumps using CIDR mask
-C print out payloads with character data only (no hex)
-c <conf> use this configuration
-D run Snort in background (daemon) mode
-d dump the Application Layer
-e display the second layer header info
-f turn off fflush() calls after binary log writes
-G <0xid> (same as --logid) (0:65535)
-g <gname> run snort gid as <gname> group (or gid) after initialization
-H make hash tables deterministic
-i <iface>... list of interfaces
...

While this system has tcpdump installed by default, let's also install TShark.

securitynik@snort3:~$ sudo apt-get install tshark

Using tcpdump I captured over 21,044 packets, using the following.

securitynik@snort3:~$ securitynik@snort3:~$ sudo tcpdump -n --interface enp0s3 -v -w securitynik-sample.pcap
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
Got 1448

Got 1448
^C21044 packets captured
21044 packets received by filter
0 packets dropped by kernel

Using TShark, let's now see what is in this file.

securitynik@snort3:~$ tshark -n -r securitynik-sample.pcap -q -z io,phs
===================================================================
Protocol Hierarchy Statistics
Filter: 

eth                                      frames:21044 bytes:178288931
  ip                                     frames:20780 bytes:178275019
    udp                                  frames:851 bytes:118457
      dns                                frames:819 bytes:115601
      ntp                                frames:24 bytes:2160
      mdns                               frames:8 bytes:696
    tcp                                  frames:19929 bytes:178156562
      http                               frames:156 bytes:28081
        media                            frames:1 bytes:1448
          tcp.segments                   frames:1 bytes:1448
      tls                                frames:7855 bytes:164523943
        tcp.segments                     frames:7572 bytes:164188303
          tls                            frames:7555 bytes:163997610
  arp                                    frames:256 bytes:13056
  ipv6                                   frames:8 bytes:856
    udp                                  frames:8 bytes:856
      mdns                               frames:8 bytes:856
===================================================================

Doing some basic processing on the file with Snort3, we see 1 PCAP with 21,044 records received and analyzed, just as we captured. We also got information on the timing for the processing of these packets. Looks like Snort3 processed all 21,044 packets in under 1 second.

securitynik@snort3:~$  snort --pcap-list securitynik-sample.pcap 
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
--------------------------------------------------
pcap DAQ configured to read-file.
Commencing packet processing
++ [0] securitynik-sample.pcap
-- [0] securitynik-sample.pcap
--------------------------------------------------
Packet Statistics
--------------------------------------------------
daq
                    pcaps: 1
                 received: 21044
                 analyzed: 21044
                    allow: 21044
                 rx_bytes: 16259569
--------------------------------------------------
codec
                    total: 21044       	(100.000%)
                 discards: 17392       	( 82.646%)
                      arp: 256         	(  1.216%)
                      eth: 21044       	(100.000%)
                     ipv4: 20780       	( 98.745%)
                     ipv6: 8           	(  0.038%)
                      tcp: 11046       	( 52.490%)
                      udp: 859         	(  4.082%)
--------------------------------------------------
Module Statistics
--------------------------------------------------
detection
                 analyzed: 21044
--------------------------------------------------
tcp
        bad_tcp4_checksum: 8071
--------------------------------------------------
udp
        bad_udp4_checksum: 430
        bad_udp6_checksum: 8
--------------------------------------------------
Summary Statistics
--------------------------------------------------
timing
                  runtime: 00:00:00
                  seconds: 0.486754
                 pkts/sec: 21044
                Mbits/sec: 124
o")~   Snort exiting

If you wish to dump contents of the PCAP file add the "-L dump" option or go even further by adding the "-d" to dump the application data. In this case I will add "-n" to only show 1 packet.

securitynik@snort3:~$ snort --pcap-list securitynik-sample.pcap -L dump -d -n 1 
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
--------------------------------------------------
pcap DAQ configured to read-file.
Commencing packet processing
++ [0] securitynik-sample.pcap
pkt:1	
eth(DLT):  08:00:27:2A:BA:15 -> 52:54:00:12:35:02  type:0x0800
ipv4(0x0800):  10.0.2.15 -> 64.71.255.198
	Next:0x11 TTL:64 TOS:0x0 ID:55133 IpLen:20 DgmLen:86 DF

snort.raw[66]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
9F 59 00 35 00 42 4C 70  9C 9D 01 00 00 01 00 00  .Y.5.BLp ........
00 00 00 01 12 63 6F 6E  6E 65 63 74 69 76 69 74  .....con nectivit
79 2D 63 68 65 63 6B 06  75 62 75 6E 74 75 03 63  y-check. ubuntu.c
6F 6D 00 00 01 00 01 00  00 29 02 00 00 00 00 00  om...... .)......
00 00                                             ..
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

While reading back data from a PCAP file is cool, Snort3 is more than likely going to be running in live mode most of the time. Here is what it looks like once you decide to run snort from the command line.

First off, decide on the interface or interfaces you wish to capture traffic on. Here are my list of interfaces on my VM.

securitynik@snort3:~$  ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:2a:ba:15 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp0s3
       valid_lft 59259sec preferred_lft 59259sec
    inet6 fe80::8adb:ccd9:2479:82c3/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:eb:40:cd brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.116/24 brd 10.0.0.255 scope global dynamic noprefixroute enp0s8
       valid_lft 459sec preferred_lft 459sec
    inet6 fe80::2cf1:a00b:bcce:f58c/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Let's tell Snort3 to capture traffic on the two non-loopback interfaces. Note, while I'm using two interfaces separated by colon, you can instead use 1 interface as would be the case on most installs of an IDS.

securitynik@snort3:~$ sudo snort -i enp0s3:enp0s8
[sudo] password for securitynik: 
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
--------------------------------------------------
pcap DAQ configured to passive.
Commencing packet processing
++ [0] enp0s3:enp0s8
...

You might notice above that "DAQ configured for passive". To enable inline mode operations, leverage the -Q option within your configuration.

securitynik@snort3:~$ sudo snort -i enp0s3:enp0s8 -v -Q
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
--------------------------------------------------
Inspection Policy : policy id 0 : 
--------------------------------------------------
pcap DAQ configured to inline.
--------------------------------------------------
host_cache
    memcap: 8388608 bytes
Commencing packet processing
++ [0] enp0s3:enp0s8
Instance 0 daq pool size: 256
Instance 0 daq batch size: 64
...

You more than likely want to run snort in IDS or IPS mode. Thus you would take advantage of a configuration file. Let's use the default one which comes with Snort3 and which we used in the previous post.

securitynik@snort3:~$ sudo snort -i enp0s3:enp0s8 -v -Q -c /usr/local/etc/snort/snort.lua 
--------------------------------------------------
o")~   Snort++ 3.1.0.0
--------------------------------------------------
Loading /usr/local/etc/snort/snort.lua:
....

Finished /usr/local/etc/snort/snort.lua:
--------------------------------------------------
Inspection Policy : policy id 0 : /usr/local/etc/snort/snort.lua
--------------------------------------------------
.....
stream_tcp:
             flush_factor: 0
                  max_pdu: 16384
               max_window: 0
                   no_ack: disabled
            overlap_limit: 0
                   policy: bsd
              queue_limit: { max_bytes = 1048576, max_segments = 2621 }
         reassemble_async: enabled
             require_3whs: -1 (disabled)
          session_timeout: 30
           small_segments: { count = 0, maximum_size = 0 }
               track_only: disabled
--------------------------------------------------
stream_udp:
          session_timeout: 30
--------------------------------------------------
stream_user:
          session_timeout: 30
--------------------------------------------------
telnet:
        ayt_attack_thresh: -1
          check_encrypted: disabled
        encrypted_traffic: disabled
                normalize: disabled
--------------------------------------------------
wizard:
--------------------------------------------------
pcap DAQ configured to inline.
--------------------------------------------------
host_cache
    memcap: 8388608 bytes
Commencing packet processing
++ [0] enp0s3:enp0s8
Instance 0 daq pool size: 256
Instance 0 daq batch size: 64

Let's see now what the "--talos" option shows us. The Snort reference manual is not very verbose on this. It simply says it "enables Talos tweak", whatever that means. Additionally, instead of using "--talos", you can use "--tweaks talos".

securitynik@snort3:~$ sudo snort -i enp0s3:enp0s8 -Q -c /usr/local/etc/snort/snort.lua \
--tweaks talos --pcap-list securitynik-sample.pcap -R local.rules -q

##### securitynik-sample.pcap #####
	[1:1:0] Nik Testing (alerts: 2825)
#####
--------------------------------------------------
rule profile (all, sorted by total_time)
#       gid   sid rev    checks matches alerts time (us) avg/check avg/match avg/non-match timeouts suspends
=       ===   === ===    ====== ======= ====== ========= ========= ========= ============= ======== ========
1         1     1   0      2908    2908   2825      1863         0         0             0        0        0

We see above information on our test rule. Not to worry, we will look at rules in the  next post where we feed the pig. Remember, rules gives the pig wings :-)

References: