A data diode is a network device that only allows data to travel in one direction, they are used primarily in high security applications like nuclear plants, industrial automation, and armies all over the world. There reason they aren't more widely used, the sacrifice for their high security is that normal transport protocols don't work over data diodes, as they require a bidirectional connection.
And here is where everything becomes muddy, because to overcome this limitation some data diodes use a secondary channel from the isolated side to the untrusted side to send flow control information back so TCP connection can pass through. This makes them potentially vulnerable to a covert channel attack, but there's almost no information on vulnerabilities, attacks, or test tools.
So I wrote leaky diode a test tool to check if they are resistant to a couple of a very simple attacks.
The attacks described in this post require a compromised host on the isolated side, and have a very low throughput (aroud 1 Bytes/min), so they can't realistically be used to leak more than a few KB of data.
Regardless of the limitations there're still many fields where even such small leaks would be catastrophic, and would love to be able to test their diodes so lets dive in.
Close delay uses the delay between the start of a connection and the time it's closed by the server to encode the secret bits.
- 1 (CLIENT) Open a connection to the server.
- 2 (CLIENT) Send a request for one of the secret bits and a threshold delay, then continue sending junk data to keep the connection alive.
- 3 (SERVER) After receiving a request, close the connection inmediately if the value of the secret bit is 0, or wait threshold delay before closing the connection if the value is 1.
- 4 (CLIENT) If the delay between sending the request to the server and the server closing the connection is greater than threshold/2 then the bit value is 1, and 0 otherwise.
This attack works well in almost all circunstances, as it doesn't require much bandwith and is not affected by network lattency or buffers in the data diodes. The drawback is that uses so many connections tha can be easily detected.
Flow modulation uses the flow control mechanisms of TCP to transmit data using the throughput of a connection as the carrier.
- 1 (CLIENT) Connect with the server and set the tx rates to signal low and high bits. (i.e- 60KB/sec for low 300KB/sec for high bits)
- 2 (CLIENT) Send a request for one of the secret's bits, and start sending random data at a rate greater than the max encoding rate.
- 3 (SERVER) On reception of a request start throttling the connection to the to the speed that encodes the value of the requested bit/bits. (as provided in step 1)
- 4 (CLIENT) Wait until the data rate stabilizes/settles and then sample it to obtain the bit value.
- 5 (CLIENT) Go to step 1 until all the secret bits have been read.
This attack is harder to detect than close delay as it uses a single connection and not thousands to exfiltrate the data, the data sent can also be made to mimic another protocol like http to make it even harder to detect. And with enough care a finely tunned tool could use very close tx rates for high and low values, so it's indistinguishable from a legitimate connection.
The drawback is that it's vulnerable to network congestion, QoS, and large TCP stack buffers that can make it inconsistent.
Lower level attacks
If you have privileges to directly manipulate the stack, there are few more possible attacks that may work depending on the diode:
- Using the ACK delay since the reception of a packet.
- Only sending ACK on even or odd sequence numbers, to encode low/high bits.
- Manipulating the window size.
Some of these are harder to implement and easier to defend against by the diode, but are great candidades to embed into the OS. Just to be clear I haven't tested any of them.
If you have a diode you want to test, download leaky diode
On the isolated side launch the server:
$leaky_server public_ip port 'secret string to leak'
and on the untrusted side one of:
$leaky_client server_ip server_port --mode flow --partial
$leaky_client server_ip server_port --mode close --partial
Then wait for a few minutes until the first bytes start to arrive, or if you are impacient add --verbose argument to show notifications on each bit sent/received.
Thank you for reading, and share the results!!!