Sending files through ICMP

DISCLAIMER: English isn’t my mother tongue so it’s possible that you’ll find some grammatical mistakes on the text, feel free to point them out on the comments so I could learn and improve. Thanks.

Today I want to talk about a technique that I heard on latest No cON Name by Juan Garrido and Pedro Laguna, both guys did a presentation about data exfiltration, that’s it: an unauthorized release of data from within a computer system, and one of the methods they explain for exfiltrate data was the ICMP tunneling.

Nowadays network administrators are aware of the security problems of anyone inside the network with the permissions to reach arbitrary ports outside the network, so they use firewalls that could block unauthorized connections and proxies that can inspect and log the authorized ones in order to seek for malicious activities. And that is true mainly for any TCP and UDP connections, but network administrators tend to underestimate other protocols less designed to transport arbitrary data as, for example ICMP. What harm could made an user pinging his own server? Well, let’s take a look and maybe you’ll get a surprise.

The ICMP is a layer 4 (transport) protocol designed to troubleshoot and debug computer networks, for example a router will respond an ICMP net unreachable message (type 3 code 0) if receives a packet with an IP destination address that isn’t on its routing table, another example could be the ICMP redirect message (type 5) that is sent by a router indicating the networks hosts that it is no longer the default gateway and that those hosts have to update their routing tables.

The most known ICMP messages are ICMP echo request and ICMP echo reply messages, used by the ping (Packet INternet Groper) application. The main usage of ping is to troubleshoot networking issues determining if the problems occur above or below the network layer, basically ping sends an ICMP echo request to a host and, if that host is configured to respond ICMP echoes, it will respond with an ICMP echo reply, this way you could determine if the layers below IP are working properly, sending a burst of them you could check how many packets gets lost on the path, measuring the time between you send an echo request and you receive an echo reply you could determine the latency of that link, and so on. Because of that troubleshooting versatility most networks administrators allow the pass of these packets.

An ICMP echo request & reply packets looks like:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7|8 9 0 1 2 3 4 5|6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|     Type      |     Code      |          Checksum             |
|           Identifier          |        Sequence Number        |
|     Data ...
  • Type field tells us what type of ICMP packet (obviously, duh), in our case we’re only interested on 8 (echo request) and 0 (echo reply).
  • Code field is used to determine subtypes of ICMP packets, in the echo request & reply types there aren’t any subtype (but you can find on, for example, type 3 -Destination unreachable- the codes 0 -destination network unreachable-, 1 -destination host unreachable-, 4 -Fragmentation required and DF flag set-, and so on)
  • Checksum is, as you could guess, a field with the checksum of the packet used to “ensure” the integrity of the packet through the link.
  • Identifier and sequence number fields are used to create “streams” of ICMP packets, so you could send a burst of ICMP echo request and determine which of then got lost over the wire (or the waves).
  • And finally the data field, that should contain an arbitrary array of bytes that the remote host must replicate on the ICMP echo reply (so we could determine that it received exactly the same data that we send).

So, as I said, the data field can be any arbitrary array of bytes, so we can “easily” break any file on tiny bits and send it through the network without any problem. A few time ago I wrote some kind of quick and dirty proof of concept in Python (maybe one day I will make it cleaner but, you know, procrastination :P) so you can to take a look at it if you want to know better how to send files over ICMP.

A bit of this post being sent through ICMP

But it doesn’t limit to send files, you also could build a tunnel to have full TCP connections over ICMP (you can check that isn’t something new).

For more information you could take a look at the RFC 792 (INTERNET CONTROL MESSAGE PROTOCOL).