Wednesday, November 14, 2007

Analyzing Protocol Hopping Covert Channel Tool

I enjoy analyzing covert channels, although my skills are far inferior to someone like Steven Murdoch. However, today via Packetstorm I learned of Protocol Hopping Covert Channel Tool by Steffen Wendzel. He wrote a text file describing his thoughts behind the tool called Protocol Hopping Covert Channels. Quoting the paper:

This paper describes a new way to implement covert channels. This is done by changing the protocol of the tunnel while the tunnel exists and even change the protocol on a randomized way without restarting the tunnel or reconnecting to the tunnel. A simple proof of concept tool called 'phcct' (protocol hopping covert channel tool) also known as 'takushi' (what is japanese for taxi) is available on my website http://www.doomed-reality.org. phcct implements only one (the easiest) version of such a randomized protocol hopping covert channel.

As soon as I read this I thought "this is so different from normal traffic, it will be easy to identify." I know that is true for manual inspection of traffic. I am not sure how automated tools would deal with it. The paper continues:

Do not forget the reason why doing this: It is to be stealth [sic]. Even if _one_ of the protocols you are using is recorded, the monitoring system will not collect ALL packets of ALL protocols in a network. This simply is a too huge amount of data. And yes, it makes the forensic analysis of network traffic much harder if there are multiple protocols used for a covert channel.

Apparently the author does not know about NSM or Sguil. Assuming you are performing this protocol hopping from a host on an enterprise network to a host on the Internet, a NSM sensor monitoring your Internet gateway will see and record this traffic.

I decided to give the author's proof of concept tool, phcct, a try. I compiled it statically on my Ubuntu laptop.

$ gcc -O -o phcct_s -fstack-protector-all -W -Wall -Wshadow -g
-ggdb *.c -lpthread -static

Next I copied the binary to a VM running a Ubuntu 7.10 as a live CD/.iso. I used this static version because I noticed the Ubuntu live CD did not have the required libraries to compile from source, but run as a statically compiled binary it worked fine.

Now I started phcct on each workstation and hit return once each side was running. My laptop is neely, 192.168.2.101.

root@neely:~/phcct# ./phcct_s -a 192.168.2.115
starting phcct (a.k.a. takushi) ...
please press return if the peer is setup up.
connecting ...
connected via http
connected via ftp-data
connected via plain proto
waiting for local connection on port 9999 ...

My VM is ubuntu, 192.168.2.115.

root@ubuntu:/home/analyst# ./phcct_s -a 192.168.2.101
starting phcct (a.k.a. takushi) ...
please press return if the peer is setup up.
connecting ...
connected via http
connected via ftp-data
connected via plain proto
waiting for local connection on port 9999 ...

Once each side of the tunnel was activated, I used Netcat on each system to connect to port 9999 on localhost. First, neely:

richard@neely:~$ nc -v localhost 9999
localhost [127.0.0.1] 9999 (?) open

Second, ubuntu:

analyst@ubuntu:~$ nc -v localhost 9999
localhost [127.0.0.1] 9999 (?) open

Now I was ready to send traffic. For example, I typed this on neely:

This is traffic from neely to ubuntu.

and it appeared on ubuntu:

This is traffic from neely to ubuntu.

Then I did the reverse. I repeated this cycle four times, for a total of five exchanges or ten total messages. When done I exited each Netcat session.

During this process I captured the traffic using Tshark. You can download it here.

I prefer to start the analysis by looking at session data. Here is what Argus 2.x thought of the traffic.

$ ra -nn -L0 -A -r ph.1.arg -s saddr daddr sport dport proto pkts bytes
SrcAddr DstAddr Sport Dport Type SrcPkt DstPkt SAppBytes DAppBytes
192.168.2.115 192.168.2.101.43598 2510 tcp 6 4 96 0
192.168.2.115 192.168.2.101.43198 80 tcp 5 3 281 0
192.168.2.115 192.168.2.101.52158 20 tcp 6 4 96 0
192.168.2.101 192.168.2.115.49586 80 tcp 4 4 281 0
192.168.2.101 192.168.2.115.45106 20 tcp 3 3 0 0
192.168.2.101 192.168.2.115.50200 2510 tcp 7 7 192 0

You can see the tool using destination ports 2510, 80 and 20. There are six sessions although one of them is empty. The five active sessions correspond to our five conversations.

Let's look at the traffic on each using Tcpflow. In the ls output I omit the first few fields for space purposes.

taosecurity:/home/analyst$ tcpflow -r ph.1.lpc
taosecurity:/home/analyst$ ls -al 192*
281 Nov 14 13:59 192.168.002.101.49586-192.168.002.115.00080
192 Nov 14 13:59 192.168.002.101.50200-192.168.002.115.02510
281 Nov 14 13:59 192.168.002.115.43198-192.168.002.101.00080
96 Nov 14 13:59 192.168.002.115.43598-192.168.002.101.02510
96 Nov 14 13:59 192.168.002.115.52158-192.168.002.101.00020

Notice the file sizes match the byte counts seen above. Here are the contents of each. Note the use of cat -tev to

taosecurity:/home/analyst$ cat -tev 192.168.002.101.49586-192.168.002.115.00080
GET / HTTP/1.1^M$
Host: google.de^M$
User-Agent: Mozilla/5.0^M$
Accept: text/xml^M$
Accept-Language: en-us;q=0.5,en;q=0.3^M$
Accept-Encoding: gzip,deflate^M$
Accept-Charset: ISO-8859-1,utf-8^M$
Keep-Alive: 300^M$
Connection: keep-alive^M$
Cookie: GPC=2FW=0:This is traffic from neely to ubuntu.$
^M$
^M$
taosecurity:/home/analyst$ cat -tev 192.168.002.101.50200-192.168.002.115.02510
^A^B^C0 FW=0:This is traffic from neely to ubuntu.$
^A^B^C1 FW=0:This is traffic from neely to ubuntu.$
^A^B^C3 FW=0:This is traffic from neely to ubuntu.$
^A^B^C4 FW=0:This is traffic from neely to ubuntu.$

taosecurity:/home/analyst$ cat -tev 192.168.002.115.43198-192.168.002.101.00080
GET / HTTP/1.1^M$
Host: google.de^M$
User-Agent: Mozilla/5.0^M$
Accept: text/xml^M$
Accept-Language: en-us;q=0.5,en;q=0.3^M$
Accept-Encoding: gzip,deflate^M$
Accept-Charset: ISO-8859-1,utf-8^M$
Keep-Alive: 300^M$
Connection: keep-alive^M$
Cookie: GPC=4FW=0:This is traffic from ubuntu to neely.$
^M$
^M$

taosecurity:/home/analyst$ cat -tev 192.168.002.115.43598-192.168.002.101.02510
^A^B^C0 FW=0:This is traffic from ubuntu to neely.$
^A^B^C1 FW=0:This is traffic from ubuntu to neely.$

taosecurity:/home/analyst$ cat -tev 192.168.002.115.52158-192.168.002.101.00020
^A^B^C2 FW=0:This is traffic from ubuntu to neely.$
^A^B^C3 FW=0:This is traffic from ubuntu to neely.$

At the end of the day we have messages exchanged using one real protocol (HTTP, with payload in the cookie field) and two pseudo-protocols (raw traffic on port 2510 TCP and attempted simulated FTP data traffic). The FTP data traffic isn't simulated properly because the SYN segments go to port 20 TCP.

$ tcpdump -n -t -r ph.1.lpc port 20
reading from file ph.1.lpc, link-type EN10MB (Ethernet)
IP 192.168.2.115.52158 > 192.168.2.101.20:
S 2100176842:2100176842(0) win 5840
IP 192.168.2.101.20 > 192.168.2.115.52158:
S 3955486862:3955486862(0) ack 2100176843 win 5792
IP 192.168.2.115.52158 > 192.168.2.101.20: . ack 1 win 183

IP 192.168.2.101.45106 > 192.168.2.115.20:
S 3970907263:3970907263(0) win 5840
IP 192.168.2.115.20 > 192.168.2.101.45106:
S 671130558:671130558(0) ack 3970907264
IP 192.168.2.101.45106 > 192.168.2.115.20: . ack 1 win 1460
IP 192.168.2.115.52158 > 192.168.2.101.20: P 1:49(48) ack 1 win 183
IP 192.168.2.101.20 > 192.168.2.115.52158: . ack 49 win 1448
IP 192.168.2.115.52158 > 192.168.2.101.20: P 49:97(48) ack 1 win 183
IP 192.168.2.101.20 > 192.168.2.115.52158: . ack 97 win 1448
IP 192.168.2.115.52158 > 192.168.2.101.20: F 97:97(0) ack 1 win 183
IP 192.168.2.115.20 > 192.168.2.101.45106: F 1:1(0) ack 1 win 181
IP 192.168.2.101.45106 > 192.168.2.115.20: F 1:1(0) ack 2 win 1460
IP 192.168.2.101.20 > 192.168.2.115.52158: F 1:1(0) ack 98 win 1448
IP 192.168.2.115.20 > 192.168.2.101.45106: . ack 2 win 181
IP 192.168.2.115.52158 > 192.168.2.101.20: . ack 2 win 183

Real active FTP data traffic comes from port 20 TCP.

Can this technique be improved? Sure. Is it tough to analyze? Possibly. If you use a packet-by-packet approach, you can see what's happening. For example, here are a few packets containing payloads. Notice the use of the Tshark display filter using the -R switch.

richard@neely:~$ tshark -r ph.1.lpc -x -R 'tcp.len >= 20'
19 62.570303 192.168.2.101 50200 192.168.2.115 2510 TCP 50200 > 2510
[PSH, ACK] Seq=1 Ack=1 Win=5840 Len=48 TSV=4768072 TSER=3038481

0000 00 13 02 4c 30 2d 00 13 02 4c 30 2d 08 00 45 00 ...L0-...L0-..E.
0010 00 64 24 88 40 00 40 06 8f e3 c0 a8 02 65 c0 a8 .d$.@.@......e..
0020 02 73 c4 18 09 ce eb e8 a2 75 28 9d e1 d0 80 18 .s.......u(.....
0030 05 b4 e3 5b 00 00 01 01 08 0a 00 48 c1 48 00 2e ...[.......H.H..
0040 5d 11 01 02 03 30 20 46 57 3d 30 3a 54 68 69 73 ]....0 FW=0:This
0050 20 69 73 20 74 72 61 66 66 69 63 20 66 72 6f 6d is traffic from
0060 20 6e 65 65 6c 79 20 74 6f 20 75 62 75 6e 74 75 neely to ubuntu
0070 2e 0a ..

21 70.543503 192.168.2.115 43598 192.168.2.101 2510 TCP 43598 > 2510
[PSH, ACK] Seq=1 Ack=1 Win=5856 Len=48 TSV=3055661 TSER=4752430

0000 00 13 02 4c 30 2d 00 13 02 4c 30 2d 08 00 45 00 ...L0-...L0-..E.
0010 00 64 13 0f 40 00 40 06 a1 5c c0 a8 02 73 c0 a8 .d..@.@..\...s..
0020 02 65 aa 4e 09 ce 7d 50 49 4a eb ba 86 09 80 18 .e.N..}PIJ......
0030 00 b7 70 7a 00 00 01 01 08 0a 00 2e a0 2d 00 48 ..pz.........-.H
0040 84 2e 01 02 03 30 20 46 57 3d 30 3a 54 68 69 73 .....0 FW=0:This
0050 20 69 73 20 74 72 61 66 66 69 63 20 66 72 6f 6d is traffic from
0060 20 75 62 75 6e 74 75 20 74 6f 20 6e 65 65 6c 79 ubuntu to neely
0070 2e 0a ..

23 84.876175 192.168.2.101 50200 192.168.2.115 2510 TCP 50200 > 2510
[PSH, ACK] Seq=49 Ack=1 Win=5840 Len=48 TSV=4773648 TSER=3053597

0000 00 13 02 4c 30 2d 00 13 02 4c 30 2d 08 00 45 00 ...L0-...L0-..E.
0010 00 64 24 89 40 00 40 06 8f e2 c0 a8 02 65 c0 a8 .d$.@.@......e..
0020 02 73 c4 18 09 ce eb e8 a2 a5 28 9d e1 d0 80 18 .s........(.....
0030 05 b4 92 56 00 00 01 01 08 0a 00 48 d7 10 00 2e ...V.......H....
0040 98 1d 01 02 03 31 20 46 57 3d 30 3a 54 68 69 73 .....1 FW=0:This
0050 20 69 73 20 74 72 61 66 66 69 63 20 66 72 6f 6d is traffic from
0060 20 6e 65 65 6c 79 20 74 6f 20 75 62 75 6e 74 75 neely to ubuntu
0070 2e 0a ..

25 88.388511 192.168.2.115 43598 192.168.2.101 2510 TCP 43598 > 2510
[PSH, ACK] Seq=49 Ack=1 Win=5856 Len=48 TSV=3060172 TSER=4770065

0000 00 13 02 4c 30 2d 00 13 02 4c 30 2d 08 00 45 00 ...L0-...L0-..E.
0010 00 64 13 10 40 00 40 06 a1 5b c0 a8 02 73 c0 a8 .d..@.@..[...s..
0020 02 65 aa 4e 09 ce 7d 50 49 7a eb ba 86 09 80 18 .e.N..}PIz......
0030 00 b7 19 c7 00 00 01 01 08 0a 00 2e b1 cc 00 48 ...............H
0040 c9 11 01 02 03 31 20 46 57 3d 30 3a 54 68 69 73 .....1 FW=0:This
0050 20 69 73 20 74 72 61 66 66 69 63 20 66 72 6f 6d is traffic from
0060 20 75 62 75 6e 74 75 20 74 6f 20 6e 65 65 6c 79 ubuntu to neely
0070 2e 0a ..

27 97.214303 192.168.2.101 49586 192.168.2.115 80 HTTP GET / HTTP/1.1

0000 00 13 02 4c 30 2d 00 13 02 4c 30 2d 08 00 45 00 ...L0-...L0-..E.
0010 01 4d e2 06 40 00 40 06 d1 7b c0 a8 02 65 c0 a8 .M..@.@..{...e..
0020 02 73 c1 b2 00 50 ec 6f 64 f6 27 b7 a8 06 80 18 .s...P.od.'.....
0030 05 b4 16 d2 00 00 01 01 08 0a 00 48 e3 1d 00 2e ...........H....
0040 5d 0f 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 ].GET / HTTP/1.1
0050 0d 0a 48 6f 73 74 3a 20 67 6f 6f 67 6c 65 2e 64 ..Host: google.d
0060 65 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d e..User-Agent: M
0070 6f 7a 69 6c 6c 61 2f 35 2e 30 0d 0a 41 63 63 65 ozilla/5.0..Acce
0080 70 74 3a 20 74 65 78 74 2f 78 6d 6c 0d 0a 41 63 pt: text/xml..Ac
0090 63 65 70 74 2d 4c 61 6e 67 75 61 67 65 3a 20 65 cept-Language: e
00a0 6e 2d 75 73 3b 71 3d 30 2e 35 2c 65 6e 3b 71 3d n-us;q=0.5,en;q=
00b0 30 2e 33 0d 0a 41 63 63 65 70 74 2d 45 6e 63 6f 0.3..Accept-Enco
00c0 64 69 6e 67 3a 20 67 7a 69 70 2c 64 65 66 6c 61 ding: gzip,defla
00d0 74 65 0d 0a 41 63 63 65 70 74 2d 43 68 61 72 73 te..Accept-Chars
00e0 65 74 3a 20 49 53 4f 2d 38 38 35 39 2d 31 2c 75 et: ISO-8859-1,u
00f0 74 66 2d 38 0d 0a 4b 65 65 70 2d 41 6c 69 76 65 tf-8..Keep-Alive
0100 3a 20 33 30 30 0d 0a 43 6f 6e 6e 65 63 74 69 6f : 300..Connectio
0110 6e 3a 20 6b 65 65 70 2d 61 6c 69 76 65 0d 0a 43 n: keep-alive..C
0120 6f 6f 6b 69 65 3a 20 47 50 43 3d 32 46 57 3d 30 ookie: GPC=2FW=0
0130 3a 54 68 69 73 20 69 73 20 74 72 61 66 66 69 63 :This is traffic
0140 20 66 72 6f 6d 20 6e 65 65 6c 79 20 74 6f 20 75 from neely to u
0150 62 75 6e 74 75 2e 0a 0d 0a 0d 0a buntu......

This tool demonstrates the importance of a few NSM concepts. First, intruders are unpredictable. (Remember I use the term "intruder" to mean anyone doing something you don't like on your network, i.e., any policy violater. Second, by collecting everything and investigating once you have indicators, you can find activity not observed by existing inspection and blocking systems. Third, there is no substitute for full content. Statistics are nice, sessions are better, but only full content reveals what's really happening. Even session tools can be fooled or misguided, or at least have their output subject to misinterpretation.

I expect to see additional iterations of this tool and technique.

9 comments:

dre said...

I read the paper yesterday... but your analysis and demonstration of concepts is excellent!

Covert channels don't have to do this sort of thing... gray-world cooking with covert channels, ncovert, nushu, and my "call home through call home" ideas could easily be implemented so that these sorts of detection schemes would not work. It gets worse when you start talking about man-in-the-browser covert channels.

Jonathan Leffler said...

The discussion is interesting - thanks.

FYI: there's a space in the link to the logged traffic.

Richard Bejtlich said...

Jonathan, fixed -- thanks.

jbmoore said...

Richard,

If the message had been encrypted and then sent via covert channel, the analysis would be inconclusive. All you'd know is that encrypted packets were sent using the covert channel. While you are pointing out the logical flaw in the tool's author's assumption, it wouldn't take much to correct the flaw and obscure the conversation making a definitive analysis almost impossible. As a proof of concept it's a pretty nice demonstration. And you did a nice demonstration of the power of NSM.

Thank you,

John

Richard Bejtlich said...

John,

Oh sure, I agree. That's why I said "I expect to see additional iterations of this tool and technique." Encryption is already on the way.

Anonymous said...

Great demo Richard !
Laurent G.

Shannon said...

While full content is nice for some environments, how would you propose someone in an environment where a steady >400 mbit flow of traffic capture full flows?

Richard Bejtlich said...

Shannon,

Is this a trick question? Build or buy a box that can handle it. If you don't think it can be done a visit to the vendor expo at ISS World will be enlightening.

Steffen Wendzel said...

Hi, I am the author of the PHCC paper. I've just added your comment about the FTP port 20 bug in the paper (I also fixed the typo you found). Poorly I currently don't have the time to fix this tool since I am busy working on another research project and some books.

Nevertheless I still think PHCC are very hard to detect using encryption (I don't plan to add encryption to this explicity called "simple" proof of concept code) and an improved micro protocol message ID field (see updated part of the paper). I also think that collecting _all_ data in a network is a too huge amount of data propably nobody will take care about (which company will pay the forensics that will investigate the garbage data?)

But you're right: The detection of the PHCC implemented by phcct is easy to detect but it wasn't the target to do something different in this proof of concept code.

Anyway, I am happy to see that you invested the time to understand the concept of a PHCC and read the paper!

regards
Steffen Wendzel