# 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

<figure><img src="/files/ispcE8z1M9vY6G5Q9XK5" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/RiQYOzHFqGN5KcYJRm9n" alt=""><figcaption></figcaption></figure>

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

```bash
Bit 11: Reserved ← 0x0800 ← 0002048
Bit 10: Reserved ← 0x0400 ← 0001024
Bit 9:  Reserved ← 0x0200 ← 0000512
Bit 8:  NS (ECN) ← 0x0100 ← 0000256
Bit 7:  CWR ← 0x0080 ← 0000128
Bit 6:  ECE ← 0x0040 ← 0000064
Bit 5:  URG ← 0x0020 ← 0000032
Bit 4:  ACK ← 0x0010 ← 0000016
Bit 3:  PSH ← 0x0008 ← 0000008
Bit 2:  RST ← 0x0004 ← 0000004
Bit 1:  SYN ← 0x0002 ← 0000002
Bit 0:  FIN ← 0x0001 ← 0000001
```

For our covert channel, we are only interested in **bits 9, 10, and 11,** the **reserved bits**. For example:

* Bit 9 → Decimal `512` → Hex `0x0200`
* Bit 10 → Decimal `1024` → Hex `0x0400`

<figure><img src="/files/ymwZl2HjDehcc04D7fdC" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/FbyhOhbmZagFXU7xXgXF" alt=""><figcaption></figcaption></figure>

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:

1. we get the flag values after after filtering.
2. we convert them from strings to numerical values (hexadecimal).
3. for each flag value we do:
   1. is 10th bit set? if yes then left digit = 1, otherwise its 0.
   2. 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 0010 | 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

| 0000 0001 0010 | 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.

<figure><img src="/files/M9qoKF3LIQjNOacRtM5t" alt=""><figcaption></figcaption></figure>

`011000100111001001110101011011100110111001100101011100100111101101100011011010010110111001101110011000010110110101101111011011100101111101110010011011110110110001101100011100110101111101100001011100100110010101011111011101000110100001100101010111110110001001100101011100110111010001111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000`

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

<figure><img src="/files/4TlLCbV7b4ryqIskHGLt" alt=""><figcaption></figcaption></figure>

#### 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yousefoh.gitbook.io/docs/en/covert-channels-made-simple/reserved-bits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
