Friday, February 5, 2021

Snort3 on Ubuntu 20 - Feeding and testing the pig - rules and PulledPork

Now that we have installed and configured Snort3, as well as learned a little about it, let's now looking at feeding the pig ... giving it rules ... and then testing those rules before we perform our housekeeping.

Let's create the directories for us to store our rules and block lists.

securitynik@snort3:~$ sudo mkdir /usr/local/etc/rules
securitynik@snort3:~$ sudo mkdir /usr/local/etc/so_rules/
securitynik@snort3:~$ sudo mkdir /usr/local/etc/lists/

Next let's created some required files.

securitynik@snort3:~$ sudo touch /usr/local/etc/rules/snort.rules
securitynik@snort3:~$ sudo touch /usr/local/etc/rules/local.rules
securitynik@snort3:~$ sudo touch /usr/local/etc/lists/default.blocklist

securitynik@snort3:~$ sudo mkdir /usr/local/etc/pulledpork

... and our directory to store our logs

securitynik@snort3:~$ sudo mkdir /var/log/snort

With those in place, let's create three sample rule to test the traffic in our PCAP file, using the Snort 2.x method of creating rules.

securitynik@snort3:~$ sudo gedit /usr/local/etc/rules/local.rules &

securitynik@snort3:~$ sudo cat /usr/local/etc/rules/local.rules 
alert tcp any any -> any any (msg:"SecurityNik Testing TCP"; sid:40000001;)
alert icmp any any -> any any (msg:"SecurityNik ICMP"; sid:40000002;)
alert udp any any -> any any (msg:"SecurityNik Testing UDP"; sid:40000003;) 

When this rule file is passed as input to Snort3, we see the first three alerts and notice we are once again leveraging the "--talos" tweaks.

securitynik@snort3:~$ sudo snort -c /usr/local/etc/snort/snort.lua \
-R /usr/local/etc/rules/local.rules -r securitynik-sample.pcap -k none\
 -A "alert_full" -q -n 3 --talos
[**] [1:40000003:0]  <securitynik-sample.pcap> "SecurityNik Testing UDP" [**]
[Priority: 0] 
02/01-14:23:06.999138 10.0.2.15:40793 -> 64.71.255.198:53
UDP TTL:64 TOS:0x0 ID:55133 IpLen:20 DgmLen:86 DF
Len: 58

[**] [1:40000003:0]  <securitynik-sample.pcap> "SecurityNik Testing UDP" [**]
[Priority: 0] 
02/01-14:23:07.017818 64.71.255.198:53 -> 10.0.2.15:40793
UDP TTL:64 TOS:0x0 ID:47115 IpLen:20 DgmLen:198
Len: 170

[**] [1:40000001:0]  <securitynik-sample.pcap> "SecurityNik Testing TCP" [**]
[Priority: 0] 
02/01-14:23:07.020863 10.0.2.15:33244 -> 35.232.111.17:80
TCP TTL:64 TOS:0x0 ID:53105 IpLen:20 DgmLen:60 DF
******S* Seq: 0x31F1E987  Ack: 0x0  Win: 0xFAF0  TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK  TS: 3340894439 0 NOP WS: 7

[**] [1:1:0]  <securitynik-sample.pcap> "Nik Testing" [**]
[Priority: 0] 
02/01-14:23:07.020863 10.0.2.15:33244 -> 35.232.111.17:80
TCP TTL:64 TOS:0x0 ID:53105 IpLen:20 DgmLen:60 DF
******S* Seq: 0x31F1E987  Ack: 0x0  Win: 0xFAF0  TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK  TS: 3340894439 0 NOP WS: 7

--------------------------------------------------
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         140000003   0         2       2      2        10         5         5             0        0        0
2         140000001   0         1       1      1         4         4         4             0        0        0
3         1       1   0         1       1      1         0         0         0             0        0        0

Let's rewrite the above rules, using the Snort3 format adding some additional components and then run this against two different PCAPs.

alert http
(
	msg:"Looking for SecurityNik HTTP - wget and ragel traffic!"; 	# Message I would like the user to see
	flow:established, to_server;					# Monitor traffic for which 3-way handshake is completed and direction is from client to server
	http_method;							# Focus on the buffer containing the HTTP Method
	content:"|47 45 54|", offset 0, depth 3;			# Look for the hex bytes representing GET starting at offset 0 and span 3 bytes
	http_uri:path;	                                                # Look at the buffer containing the URI path
	content:"/files/ragel/ragel-6.10.tar.gz", distance 0, within 30; # Look for this content
	pcre:"/ragel\-\d{1,3}\.\d{1,3}\.tar\.gz/i"; # Use a regular expression pattern to look for the file above
 	http_header:field User-Agent;					# Look into the User Agent field in the HTTP Header
	content:"wget/1.20.3", nocase;					# Check to see if the user agent contains wget
	regex:"/wget\/\d{1,2}\.\d{2}\.{1,2}/i";				# My understanding is regex allows us to take advantage of Hyperscan. Notice above I used pcre instead.
	http_header:field Host;						# Look at the host field in the HTTP Header
	content:"www|2e|colm|2e|net", nocase; 				# Look for the hostname www.colm.net
	reference:URL, "www.securitynik.com";
	classtype:suspicious-filename-detect;				
	priority:1; 							# Give the rule a priority of 1. Max value 31
	rev: 5;								# Everytime the rule is updated the revision number should change
	sid:4;								# Every rule should have an ID
)




alert dns
(
	msg:"Looking for SecurityNik DNS traffic!";			# Message
	id:11471;							# Value in the IP ID Field
	content:"www|0B|securitynik|03|com", nocase;			# Content to search for. A mix of string and hex
	classtype:misc-attack;
	priority:4;
	rev: 3;
	sid:5;
)


 alert icmp
(
	msg:"Looking for SecurityNik ICMP traffic!";
	id:38446;			
	itype:8;							# ICMP Type
	icode:0;							# ICMP Code
	content:"|30 31 32 33 34 35 36 37|";				# Search for hex pattern
	classtype:malware-cnc;
	priority:20;
	rev: 2;	
	sid:6;
)

First run against securitynik-sample.pcap.

securitynik@snort3:~$ sudo snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules -r securitynik-sample.pcap -k none -A cmg  -q --talos | more
02/01-14:56:37.512330 [**] [1:4:5]  <securitynik-sample.pcap> "Looking for SecurityNik HTTP - wget and rage
l traffic!" [**] [Classification: A suspicious filename was detected] [Priority: 1] {TCP} 10.0.2.15:33478 -
> 192.155.89.46:80

http_inspect.http_method[3]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
47 45 54                                          GET
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_version[8]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
48 54 54 50 2F 31 2E 31                           HTTP/1.1 
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_uri[30]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
2F 66 69 6C 65 73 2F 72  61 67 65 6C 2F 72 61 67  /files/r agel/rag
65 6C 2D 36 2E 31 30 2E  74 61 72 2E 67 7A        el-6.10. tar.gz
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_header[119]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
55 73 65 72 2D 41 67 65  6E 74 3A 20 57 67 65 74  User-Age nt: Wget
2F 31 2E 32 30 2E 33 20  28 6C 69 6E 75 78 2D 67  /1.20.3  (linux-g
6E 75 29 0D 0A 41 63 63  65 70 74 3A 20 2A 2F 2A  nu)..Acc ept: */*
0D 0A 41 63 63 65 70 74  2D 45 6E 63 6F 64 69 6E  ..Accept -Encodin
67 3A 20 69 64 65 6E 74  69 74 79 0D 0A 48 6F 73  g: ident ity..Hos
74 3A 20 77 77 77 2E 63  6F 6C 6D 2E 6E 65 74 0D  t: www.c olm.net.
0A 43 6F 6E 6E 65 63 74  69 6F 6E 3A 20 4B 65 65  .Connect ion: Kee
70 2D 41 6C 69 76 65                             p-Alive
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

--------------------------------------------------
rule profile (all, sorted by total_time)
#       gid   sid rev    checks matches alerts time (us) avg/check avg/match avg/non-match timeouts suspend
s
=       ===   === ===    ====== ======= ====== ========= ========= ========= ============= ======== =======
=
1         1     4   5         1       1      1       905       905       905             0        0        
0

Running it against the securitynik-other-sample.pcap.

securitynik@snort3:~$ sudo snort -c /usr/local/etc/snort/snort.lua \
 -R /usr/local/etc/rules/local.rules -r securitynik-other-sample.pcap \
 -k none -A cmg  -q --talos | more
02/02-13:39:01.871758 [**] [1:5:3]  <securitynik-other-sample.pcap> "Looking for SecurityNik DNS traffic!" 
[**] [Classification: Misc Attack] [Priority: 4] {UDP} 10.0.2.15:59456 -> 64.71.255.198:53
08:00:27:2A:BA:15 -> 52:54:00:12:35:02 type:0x800 len:0x5A
10.0.2.15:59456 -> 64.71.255.198:53 UDP TTL:64 TOS:0x0 ID:11471 IpLen:20 DgmLen:76 DF
Len: 48

dns.raw[48]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
28 B8 01 00 00 01 00 00  00 00 00 01 03 77 77 77  (....... .....www
0B 73 65 63 75 72 69 74  79 6E 69 6B 03 63 6F 6D  .securit ynik.com
00 00 01 00 01 00 00 29  02 00 00 00 00 00 00 00  .......) ........
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

02/02-13:39:57.839673 [**] [1:6:2]  <securitynik-other-sample.pcap> "Looking for SecurityNik ICMP traffic!"
 [**] [Classification: Known malware command and control traffic] [Priority: 20] {ICMP} 10.0.2.15 -> 172.21
7.164.211
08:00:27:2A:BA:15 -> 52:54:00:12:35:02 type:0x800 len:0x62
10.0.2.15 -> 172.217.164.211 ICMP TTL:64 TOS:0x0 ID:38446 IpLen:20 DgmLen:84 DF
Type:8  Code:0  ID:1   Seq:1  ECHO

snort.raw[56]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
7D 9C 19 60 00 00 00 00  C6 CF 0C 00 00 00 00 00  }..`.... ........
10 11 12 13 14 15 16 17  18 19 1A 1B 1C 1D 1E 1F  ........ ........
20 21 22 23 24 25 26 27  28 29 2A 2B 2C 2D 2E 2F   !"#$%&' ()*+,-./
30 31 32 33 34 35 36 37                           01234567 
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

--------------------------------------------------
rule profile (all, sorted by total_time)
#       gid   sid rev    checks matches alerts time (us) avg/check avg/match avg/non-match timeouts suspend
s
=       ===   === ===    ====== ======= ====== ========= ========= ========= ============= ======== =======
=
1         1     6   2         2       1      1        59        29        58             1        0        
0
2         1     5   3         4       1      1        15         3        12             1        0        
0

Before configuring PulledPork, maybe you wish to see output from snort in CSV format.

securitynik@snort3:~$ sudo snort -c /usr/local/etc/snort/snort.lua \
-R /usr/local/etc/rules/local.rules -r securitynik-sample.pcap -k none -A csv -q | more
[sudo] password for securitynik: 
02/01-14:56:37.512330, 1206, TCP, stream_tcp, 119, C2S, 10.0.2.15:33478, 192.155.89.46:80, 1:4:5, allow

securitynik@snort3:~$ sudo snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules -r securitynik-other-sample.pcap -k none -A csv -q | more
02/02-13:39:01.871758, 214, UDP, raw, 76, C2S, 10.0.2.15:59456, 64.71.255.198:53, 1:5:3, allow
02/02-13:39:57.839673, 255, ICMP, raw, 84, C2S, 10.0.2.15:0, 172.217.164.211:0, 1:6:2, allow

At this point, we know our Snort3 installation is working with our local rules. Now let's feed the pig via Pulledpork.

First up, preprequisites

If you wish, you can register at snort.org to get an OINK code. Once you have that, you can gain access to the registered rules. If not, you can use the community rules.

Next install the software preprequieistes. 

securitynik@snort3:~$ cd ~/snort-files/
securitynik@snort3:~$ sudo apt-get install -y libcrypt-ssleay-perl liblwp-useragent-determined-perl

Next up, clone Pulledpork, copy the pulledpork.pl file to /usr/local/bin and make it executable. Then copy the config file (pulledpork.conf) to /usr/local/etc/pulledpork.

securitynik@snort3:~/snort-files$ git clone https://github.com/shirkdog/pulledpork.git

securitynik@snort3:~/snort-files$ cd pulledpork/
securitynik@snort3:~/snort-files/pulledpork$ sudo cp pulledpork.pl /usr/local/bin/ -v
'pulledpork.pl' -> '/usr/local/bin/pulledpork.pl'
securitynik@snort3:~/snort-files/pulledpork$ sudo chmod +x /usr/local/bin/pulledpork.pl 
securitynik@snort3:~/snort-files/pulledpork$ sudo cp etc/*.conf /usr/local/etc/pulledpork/

Verifying that pulledpork is configured and working properly.

securitynik@snort3:~/snort-files/pulledpork$ pulledpork.pl -V
PulledPork v0.8.0 - The only positive thing to come out of 2020...well this and take-out liquor!

Let's now modify the pulledpork.conf file. As always, before modifying a config file, I like to make a copy of it.

securitynik@snort3:~/snort-files/pulledpork$ sudo cp /usr/local/etc/pulledpork/pulledpork.conf /usr/local/etc/pulledpork/pulledpork.conf.ORIG

Change line 19 from ...

19. rule_url=https://www.snort.org/reg-rules/|snortrules-snapshot.tar.gz|<oinkcode>

... to

19. rule_url=https://www.snort.org/reg-rules/|snortrules-snapshot.tar.gz|4aabb98....bd138aFF

If you have an OINK code, change line 21 from ...

 21. rule_url=https://snort.org/downloads/community/|community-rules.tar.gz|Community

... to below by commenting (#) out this line. Note if you do not have an OINK code for line 19, you should leave this to get the community rules while commenting out line 19. If you do have an OINK code, comment this as the community rules are part of the registered rules.

21. #rule_url=https://snort.org/downloads/community/|community-rules.tar.gz|Community

Change line 72 from ...

72. rule_path=/usr/local/etc/snort/rules/snort.rules

... to reflect the path of the files we created above.

72. rule_path=/usr/local/etc/rules/snort.rules

Change line 87 from ...

87. local_rules=/usr/local/etc/snort/rules/local.rules

... to

87. local_rules=/usr/local/etc/rules/local.rules

Change line 94 from ...

94. sid_msg_version=1

... to

94. sid_msg_version=2

Change line 110 from ...

110. sorule_path=/usr/local/lib/snort_dynamicrules/

... to

110. sorule_path=/usr/local/etc/so_rules/

Change line 117 from ...

117. config_path=/usr/local/etc/snort/snort.conf

... to

117. config_path=/usr/local/etc/snort/snort.lua

Change line 134 from ...

134. distro=FreeBSD-12

... to

134. distro=Ubuntu-18-4

Change line 142 from ...

142. block_list=/usr/local/etc/snort/rules/iplists/default.blocklist

... to

142. block_list=/usr/local/etc/lists/default.blocklist

Change line 151 from ...

151. IPRVersion=/usr/local/etc/snort/rules/iplists

... to

151. IPRVersion=/usr/local/etc/lists


Change line 186 from ...

186. pid_path=/var/run/snort_eth0.pid

... to

186. pid_path=/var/log/snort/snort.pid

Changed the snort version on line 196 from ...

# snort_version=2.9.0.0

... to

snort_version=3.0.0.0

Finally, lets uncomment line 209, changing it from ...

# ips_policy=security

... to

ips_policy=security

With those steps completed, let's run PulledPork

securitynik@snort3:~$ sudo pulledpork.pl -c /usr/local/etc/pulledpork/pulledpork.conf -PEl

    https://github.com/shirkdog/pulledpork
      _____ ____
     `----,\    )
      `--==\\  /    PulledPork v0.8.0 - The only positive thing to come out of 2020...well this and take-out liquor!
       `--==\\/
     .-~~~~-.Y|\\_  Copyright (C) 2009-2021 JJ Cummings, Michael Shirk
  @_/        /  66\_  and the PulledPork Team!
    |    \   \   _(")
     \   /-| ||'--'  Rules give me wings!
      \_\  \_\\
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Checking latest MD5 for snortrules-snapshot-3000.tar.gz....
Rules tarball download of snortrules-snapshot-3000.tar.gz....
        They Match
        Done!
IP Blocklist download of https://snort.org/downloads/ip-block-list....
Reading IP List...
Prepping rules from snortrules-snapshot-3000.tar.gz for work....
        Done!
....

Rule Stats...
        New:-------15151
        Deleted:---0
        Enabled Rules:----15151
        Dropped Rules:----0
        Disabled Rules:---0
        Total Rules:------15151
IP Blocklist Stats...
        Total IPs:-----816

Done
Please review /var/log/sid_changes.log for additional details
Fly Piggy Fly!

Run snort again against one of our PCAPs using the new rules information. 

securitynik@snort3:~$ snort -c /usr/local/etc/snort/snort.lua --tweaks talos --pcap-list securitynik-sample.pcap -R /usr/local/etc/rules/snort.rules
--------------------------------------------------
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:
Loading talos.lua:
Finished talos.lua:
        ssh
        hosts
        ....
Loading rule args:
Loading /usr/local/etc/rules/snort.rules:
Finished /usr/local/etc/rules/snort.rules:
Finished rule args:
--------------------------------------------------
rule counts
       total rules loaded: 15151
               text rules: 15151
            option chains: 15151
            chain headers: 332
--------------------------------------------------
port rule counts
             tcp     udp    icmp      ip
     any     222       9       7       3
     src    5852      24       0       0
     dst    8852     191       0       0
    both       2       3       0       0
   total   14928     227       7       3
--------------------------------------------------
ips policies rule stats
              id  loaded  shared enabled    file
               0   15151       0   15151    /usr/local/etc/snort/snort.lua
--------------------------------------------------


....

Appid Statistics
--------------------------------------------------
detected apps and services
              Application: Flows      Clients    Users      Payloads   Misc       Incompat.  Failed
                  unknown: 323        0          0          0          0          0          0
--------------------------------------------------
Summary Statistics
--------------------------------------------------
timing
                  runtime: 00:00:00
                  seconds: 0.667893
                 pkts/sec: 21044
                Mbits/sec: 124
--------------------------------------------------
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 34937   2       235       0      0       716         3         0             3        0        0
2         1 53975   2       321       0      0       290         0         0             0        0        0
3         1 37730   5       321       0      0       262         0         0             0        0        0
4         1 37731   5       353       0      0        94         0         0             0        0        0
5         1 55704   2        34       0      0        78         2         0             2        0        0
6         1 53264   1        26       0      0        61         2         0             2        0        0
7         1 47030   1         5       0      0         7         1         0             1        0        0
8         1 32005   8         1       0      0         4         4         0             4        0        0
9         1 32406   3         1       0      0         3         3         0             3        0        0
10        1 32405   3         1       0      0         2         2         0             2        0        0
o")~   Snort exiting

Ok, now we have fed the pig and it gave it enough wings to fly. Let's wrap up this 4 part series with some important house keeping activities. See you in the next post.


References:

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://www.youtube.com/watch?v=PYP0YH2PVuo&list=PLpPXZRVU-dX33VNUeqWrMmBNf5FeKVmi-&index=2

https://github.com/shirkdog/pulledpork

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/004/026/original/Snort_3_GA_on_OracleLinux_8.pdf

https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/000/131/original/Snort_3_on_openSUSE_Leap_42.3.pdf

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



No comments:

Post a Comment