Exfiltrate Data using the old ping utility trick

Exfiltrate Data using the old ping utility trick

Date: 2013-09-10 08:28:31

We are back with a great blogpost. This time about data exfiltration using ping, packed together as a simple backdoor-like code. The technique may work in generell for linux and windows as well, however the main target and interest was Android.

During the article we will provide examples demonstrating how to implement a client/server architecture that will enable a remote server to exchange data with an Android device via a custom application that need no permissions to run. Example code for the client and server side is provided as a package as well.

During the research it was recognized that the ping utility was already exposed here as a data exfiltration vector on Android and in generel it is public knowledge as shown as well here (quite cool collection of data exfiltration on liners on linux systems). However, we found a different way of communicating, which ends up in the ability to receive bigger data packages on the side of Android.

ICMP Echo Request

The Internet Control Message Protocol(ICMP) is most known by normal users via the utility ping or traceroute, found on basically every Operating System today. If ping is executed it will send an icmp packet with the flags(icmptype and icmpcode) set for an “ICMP Echo Request”, if the remote host wants to acknowledge this, it will respond with an “ICMP Echo Reply”. The protocol itself is a rich suite for information gathering and testing of remote systems. ICMP Backdoors are nothing new, one of the first public implementations is ICMP Backdoor. Our implementation is not using a custom client tool, but the original ping utility as it is supposed to work on a device with a “No permissions app”.

Vulnerable versions

Devices running Android versions prior to version 3.0 allow any user to use the ping utility, which comes with any Android OS version. As of July 8, 2013, Google estimates the following Android version distribution on active devices that contacted the Google Play service:

Version Codename API Distribution
1.6 Donut 4 0.1%
2.1 Eclair 7 1.4%
2.2 Froyo 8 3.1%
2.3.3 - 2.3.7 Gingerbread 10 34.1%
3.2 Honeycomb 13 0.1%
4.0.3 - 4.0.4 Ice Cream Sandwich 15 23.3%
4.1.x Jelly Bean 16 32.3%
4.2.x Jelly Bean 17 5.6%

According to Google, roughly 40% of Android devices run a version prior to version 3.0

Sending and Receiving data

Sending data

The ping command line utility allows a user to measure response times from a remote server. Besides that, ping also allows the user to choose a pattern to send inside the ICMP packet, for network testing purposes, using the flag -p as documented in man pages:

-p pattern

You may specify up to 16 ”pad” bytes to fill out the packet you send. This is useful for diagnosing data-dependent problems in a network. For example, -p ff will cause the sent packet to be filled with all ones.

So, from the client point of view, one can use this flag to send data to a remote server.

Receiving data

Although the client can send data to a server, the usual default server OS behavior when receiving ping requests is to send a ping reply back with the same content.

$ ping -p 11223355 localhost PATTERN: 0x11223355 PING localhost (127.0.0.1) 56(84) bytes of data. 79 bytes from localhost (127.0.0.1): icmp_req=4 ttl=64 time=0.484 ms wrong data byte #11 should be 0x55 but was 0x44 #8 11 22 33 44 55 66 77 88 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa #40 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 11223355 – client defined pattern (up to 16 bytes), sent on the echo request. 1122334455667788aa ... - server defined ICMP data, received on the echo reply.

Example Implementation

Attached with this document there is a sample Android project implementing a simple client/server protocol that allows for the server to request the download of a file, upload a file to the device and execute a remote command on the device and get the result.

The control flow is summarized on the following table:

Source Destination ICMP Custom Proto (in ICMP data field)
Standard KeepAlive
Client Server Echo Request (data size 9*) KeepAlive (pattern 0×1)
Server Client Echo Reply (data size 9) KeepAlive Response (data 0×2)
Receive file from server
Client Server Echo Request (data size 9) KeepAlive (pattern 0×1)
Server Client Echo Reply (data size 9) ReceiveFile (from server) Command (data 0×5)
Client Server Echo Request (data size 1024) ReceiveData (pattern 0×3)
Server Client Echo Reply (data size 1024) Send File Name (PingData**)
Client Server Echo Request (data size 1024) ReceiveData (pattern 0×3)
Server Client Echo Reply (data size 1024) Send File Content (PingData**)
……………………………………… (repeat until EOF)
Client Server Echo Request (data size 1024) ReceiveData (pattern 0×3)
Server Client Echo Reply (data size 1024) Send File Content (PingData**)
Send file to server
Client Server Echo Request (data size 9) KeepAlive (pattern 0×1)
Server Client Echo Reply (data size 9) SendFile (to server) Command (data 0×6)
Client Server Echo Request (data size 1024) ReceiveData (pattern 0×3)
Server Client Echo Reply (data size 1024) Send File Name (PingData**)
Client Server Echo Request (data size 24) SendData (pattern filecontents)
……………………………………… (repeat until EOF)***
Client Server Echo Request (data size <=24) SendData (pattern filecontents)
Execute command in client
Client Server Echo Request (data size 9) KeepAlive (pattern 0×1)
Server Client Echo Reply (data size 9) Execute (in client) Command (data 0×7)
Client Server Echo Request (data size 1024) ReceiveData (pattern 0×3)
Server Client Echo Reply (data size 1024) Send Command line (PingData**)
Client Server Echo Request (data size 24) SendData (pattern command result)
……………………………………… (repeat until EOF)***
Client Server Echo Request (data size <=24) SendData (pattern command result)
* the first 8 data bytes in the ICMP data field are used by ping for timestamps.
** a PingData packet is a packet that consists in a 2 byte header with data size followed by the data itself. The reason for this is that an echo reply must have at least the same size of the request regardless of the actual data size we want to transmit.t
*** Any valid server echo reply works in this case, for example, an usual echo reply packet. The client is only interested in sending the data back to the server.

Improvements

The previous example shows how one can use the standard ping utility to communicate to a remote server. It provides a simple protocol to achieve its proposed goals.

There a several improvements, in a real world scenario, that could be taken into account. Given this, I will highlight three possible improvements.

  • 1. Solidify and expand the communications protocol and features
  • 2. Add compression. The upstream from the client is 16 bytes per packet and the downstream is theoretically 64kb (in the example 1kb is used)
  • 3. Add encryption. Private key encryption is a must to hide traffic contents.

Several Considerations

Attached Code

The attached code can be seen as a test-toolkit. It is a proof of concept only to show it is possible to transfer even more data through the ping channel back on the Android device. The package includes the following:

Btw., the serverside could have been implemented with hping as well, but it was more fun to do it in python with raw sockets.

APK_Source   – the sourcecode to compile with Eclipse

PingTunnel-server  – the python code and shellscripts for your linux box