Covert Timing Channel
Information carried by when a message is sent rather than what it contains. Every payload passes inspection, and the message is in the gaps.
A covert timing channel encodes information in the intervals between messages instead of in the messages. It defeats every control that looks at content, because there is nothing wrong with the content, and it is invisible to anyone who never plots the gaps.
What it is
The transmitter and the receiver agree on a way to read time. The simplest and most common on a periodic bus is inter-frame gap modulation: a node that normally publishes every 20 ms instead schedules the next frame at 20 ms plus or minus a fixed nudge, and the sign of the nudge is one bit. Others modulate whether a message is sent at all in a given slot, or the order in which two messages are emitted, or the delay before answering a request.
The bit stream then needs framing, and covert channels borrow it from wherever is convenient. Asynchronous serial framing is a favourite: a space start bit, eight data bits least significant first, a mark stop bit, and a run of mark idle between repeats. The message is usually repeated, both because the channel is lossy and because the receiver has no way to ask for a retransmission.
| Property | Consequence |
|---|---|
| Capacity | one bit per message, so a 20 ms cycle carries 50 bit/s, plenty for a key and hopeless for a file |
| Robustness | limited by the medium's own jitter and by queueing; the nudge has to exceed it |
| Detectability | invisible to payload inspection, obvious to anyone who baselines inter-arrival times |
Why it matters
It is the standard answer to a monitored data path. On a vehicle bus, an aftermarket module can pass a session key to an accomplice node while every frame it emits carries a plausible, in-range, correctly-checksummed status payload. In a datacentre the same trick moves data between virtual machines that share nothing but a scheduler. The defensive lesson is that a content inspection is a partial control, and the corresponding forensic lesson is that a timestamp column is evidence.
How to work it
- Baseline every identifier or flow on its inter-arrival series, not on its contents: count, mean interval, standard deviation, and the shape of the histogram.
- Look for a distribution with two humps of comparable weight. Then rule out the boring explanations before getting excited, because most of them are boring: a message published twice per cycle gives two alternating gaps forever, a soft timer that occasionally slips a whole tick gives one narrow hump and a small satellite, and a low-priority identifier on a loaded bus is simply late a lot.
- Read each gap as a symbol against the local median and look at the raw bit sequence. A repeating period and long runs of one value are framing, not data.
- Expect errors. Thresholding one pass typically misplaces around one bit in a hundred, which is enough to fail any integrity check in the message. Find the repeat period, fold the sequence and vote each position.
Pitfalls
- The widest distribution is usually innocent. Ranking identifiers by jitter puts scheduling artefacts and arbitration delay above the real channel.
- A channel on a low-priority identifier of a busy bus is drowned by queueing delay, so real ones sit on high-priority traffic where latency is bounded.
- Modulating the absolute schedule and modulating the interval are different encodings. The first makes consecutive gaps a difference of symbols, the second makes each gap a symbol directly, and confusing them yields a plausible-looking bit stream that decodes to nothing.
- Capture-side buffering destroys the channel. If the timestamps are not from the wire, there is nothing to recover.