Reserved bits
Reserved bits are fields that are intentionally left unused, for now. They are placeholder bits in headers or somewhere within the structures. For example, TCP headers include reserved bits located directly after the header length field.
Although these bits are not meant to be used in normal operations, they can be used to transfer data covertly, By encoding information within them, potentially using various encoding schemes to avoid detection, In this scenario that we will be giving an example on, the data is hidden within the last two bits of the reserved field.
Example

Whenever the actor attempts to send data using the reserved bits, the reserved flag becomes set, which makes detection relatively easy at first glance. However, there’s a catch: not every bit transmitted will cause the flag to be set.
lets take the letter ‘T’ for example, if we convert it from ascii to binary we’ll get the following 01010100 , if the actor was to transfer this letter using 2 bits per packet, it would split as follows:
packet 1: 01 → reserved: Set
packet 2: 01 → reserved: Set
packet 3: 01 → reserved Set
packet 4: 00 → reserved: Not set
if we just filter for reserved: Set we would miss the packets containing 00 this is why we want a broader filtering approach, to capture all traffic associated with the suspected channel. because it might differ from a scenario to another.
in this case we specify source, destination, and TCP.
tcp && ip.src==10.0.0.2 && ip.dst==10.0.0.3
Here is how it would look like after filtering

now even the unset reserved flags are included. Next we want to export those bits for further analysis. But before that, let’s understand how the flags work
TCP flags
flags are made of 11 bits starting from 0, each bit represents a flag, explaining each one is out of the current scope. But here is a representation of each bit
For our covert channel, we are only interested in bits 9, 10, and 11, the reserved bits. For example:
Bit 9 → Decimal
512→ Hex0x0200Bit 10 → Decimal
1024→ Hex0x0400

So if we were to set SYN, ACK flags the value in hex would be:
0x0002 + 0x0010 = 0x0012.
Why does this help us? Because when we extract flags from packets, we receive them as hexadecimal values. This allows us to check specifically whether the reserved bits are set or not.
Data extraction

this is the tshark one-liner that extracts those two bits and prints them as raw binary:
tshark -r traffic.pcap -Y 'tcp && ip.src==10.0.0.2 && ip.dst==10.0.0.3' -T fields -e tcp.flags | gawk '{v=strtonum($1); printf "%d%d", and(v,0x0400)?1:0, and(v,0x0200)?1:0}'
here is what is happening in this one liner:
we get the flag values after after filtering.
we convert them from strings to numerical values (hexadecimal).
for each flag value we do:
is 10th bit set? if yes then left digit = 1, otherwise its 0.
is 9th bit set? if yes then right digit = 1, otherwise its 0.
Understanding the AND operation
but how do we check if its set or not? we use the AND operation for that.
Let us see what the AND operation does Closely to the following cases: 0x0402(10th reserved bit and SYN), and 0x0002(SYN). Both will have an AND operation done with 0x0400
Case 1: 0x0402
0100 0000 0000
0x0400
0100 0000 0000
TRUE → 1
in this case the result of the AND operation of the 10th index will result in 1. Regardless of the result of other indexes.
Case 2: 0x0002
0010 0000 0000
0x0200
0000 0000 0000
FALSE → 0
in this case the 9th bit will equal 0.
by applying this to each packet we get the final result
Output
the output will either be 1 or 0 for each index. when that is printed out we’ll get the whole block of data.

011000100111001001110101011011100110111001100101011100100111101101100011011010010110111001101110011000010110110101101111011011100101111101110010011011110110110001101100011100110101111101100001011100100110010101011111011101000110100001100101010111110110001001100101011100110111010001111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
we’ll take those bits, and convert them to text. and we’ll get the data.

Conclusion
Reserved bits may appear insignificant at first glance, but as demonstrated, they offer a channel for covert data transfer. By embedding information within just a couple of flag bits, an attacker can communicate across seemingly legitimate traffic, often slipping past basic filtering techniques. However, with proper understanding of TCP flag structure and extraction methods, such hidden channels can be uncovered and decoded.
Note: I have only seen this in CTFs, I am yet to see it applied in a real world scenario
Last updated
