Источник: https://github.com/AnaktaCTF/CTF/blob/main — steganography/network-steganography.md

Стеганография в сетевом трафике

Стеганография в сети – это способ сокрытия информации внутри сетевого трафика таким образом, чтобы сам факт передачи секретного сообщения оставался незамеченным.

В этой статье мы рассмотрим распространенные методы стеганографии в сети, включая сокрытие данных в протоколах TCP, ICMP и DNS, а также разберем практические примеры и задачи для освоения этих техник.

В CTF, задачи могут включать в себя: обнаружение скрытых данных в пакетах, извлечение сообщений из аномалий трафика, создание собственных стеганографических каналов для передачи данных, и многое другое.

Стеганография в заголовках TCP/IP:

  • Скрытие информации путем модификации различных полей в заголовках TCP и IP пакетов, таких как Sequence Numbers, Acknowledgment Numbers, TCP Options, IP Identification Field и Flags.

  • Этот метод позволяет незаметно передавать небольшие объемы данных, маскируясь под обычный сетевой трафик.

Стеганография в ICMP:

  • Использование ICMP (Internet Control Message Protocol) пакетов, в частности Echo Request и Echo Reply, для скрытой передачи данных.

  • Данные могут быть внедрены в поле Data ICMP пакета.

Стеганография в DNS:

  • Скрытие информации в DNS (Domain Name System) запросах и ответах.

  • Этот метод может включать в себя кодирование данных в доменных именах (DNS tunneling) или использование TXT записей для хранения скрытых сообщений.

Основы сетевых протоколов для стеганографии

Модель TCP/IP.

Модель TCP/IP – это набор протоколов, определяющих способ передачи данных в сети Интернет. Она состоит из четырех слоев:

  • Прикладной уровень (Application Layer): Предоставляет сетевые сервисы приложениям.

  • Транспортный уровень (Transport Layer): Обеспечивает надежную или ненадежную передачу данных между приложениями.

  • Сетевой уровень (Internet Layer): Отвечает за маршрутизацию пакетов данных между сетями.

  • Канальный уровень (Link Layer): Обеспечивает передачу данных между двумя непосредственно соединенными узлами.

Подробное рассмотрение протоколов, которые мы будем использовать:

TCP (Transmission Control Protocol): Протокол транспортного уровня, обеспечивающий надежную, упорядоченную и гарантированную доставку данных.

Важные поля для стеганографии:

 Sequence Number: Номер первого байта данных в данном сегменте.

 Acknowledgment Number: Номер следующего байта, который отправитель ожидает получить.

 Flags: Управляющие флаги (SYN, ACK, FIN, RST, PSH, URG).

 Options: Дополнительные параметры TCP соединения.

IP (Internet Protocol): Протокол сетевого уровня, отвечающий за маршрутизацию пакетов данных между сетями.

Важные поля для стеганографии:

 Identification: Идентификатор IP пакета. Используется для сборки фрагментированных пакетов.

 Flags: Управляющие флаги (Don’t Fragment, More Fragments).

 Fragment Offset: Смещение фрагмента относительно начала оригинального пакета.

 Options: Дополнительные параметры IP пакета.

ICMP (Internet Control Message Protocol): Протокол сетевого уровня, используемый для передачи сообщений об ошибках и служебной информации.

Важные поля для стеганографии:

 Type: Тип ICMP сообщения (например, Echo Request, Echo Reply).

 Code: Код ICMP сообщения (более детальное описание типа).

 Checksum: Контрольная сумма для проверки целостности сообщения.

 Data: Поле данных, используемое для передачи дополнительной информации.

DNS (Domain Name System): Система доменных имен, используемая для преобразования доменных имен в IP адреса.

Важные поля для стеганографии:

 Query Name: Доменное имя, которое запрашивается.

 Type: Тип записи DNS (например, A, TXT, CNAME).

 Class: Класс записи DNS (обычно IN – Internet).

 Data: Данные, связанные с записью DNS (например, IP адрес для A записи, текст для TXT записи).

Методы стеганографии в сетевом трафике

1. Стеганография в заголовках TCP/IP:

Использование Sequence Numbers:

 Описание метода: Sequence Number (номер последовательности) – это 32-битное поле в заголовке TCP, которое указывает на номер первого байта данных в данном сегменте.

Этот номер используется для упорядочивания сегментов TCP и обеспечения надежной доставки данных.

Для стеганографии можно использовать наименее значащие биты Sequence Number для скрытия данных. Например, можно кодировать каждый бит сообщения в один бит Sequence Number. Важно помнить, что изменение Sequence Number может повлиять на установленное TCP соединение, поэтому необходимо соблюдать осторожность.

Простой пример задачи:

Вам дан дамп сетевого трафика (PCAP файл). В трафике содержится TCP соединение. Проанализируйте Sequence Numbers TCP пакетов и извлеките скрытое сообщение.

Сообщение закодировано в наименее значащих битах Sequence Numbers.

1. Открытие и фильтрация PCAP файла в Wireshark:

• Запустите Wireshark.

• Откройте файл sequence_stegano.pcap (File -> Open).

• Примените фильтр tcp в строке фильтра Wireshark и нажмите Enter. Это покажет только TCP пакеты.

2. Идентификация пакетов с закодированным сообщением:

• Внимательно просмотрите список TCP пакетов.

• Ищите пакеты, в которых, во-первых, указан [PSH, ACK] (или [P, A]) - это означает, что пакет содержит данные. Во-вторых, у этих пакетов Sequence Number будет отличаться от обычных ACK пакетов (которые обычно просто подтверждают получение данных).

3. Извлечение Sequence Numbers:

• После того, как вы нашли пакеты с данными, запишите их Sequence Numbers. В Wireshark можно увидеть Sequence Number в столбце “Seq”. Или можно выбрать пакет и посмотреть детали в панели Packet Details (TCP -> Sequence number).

• Вам должно быть несколько пакетов, каждый из которых содержит часть сообщения.

В нашем случае это:

4200737474

2928584394

2798024358

2788084474

4134962918

4. Декодирование сообщения с помощью Python:

from scapy.all import *

def decode_seq_num(seq, message_length):
    """Декодирует сообщение из Sequence Number TCP пакета."""
    binary_message = ''
    for i in range(message_length):
        bit = (seq >> i) & 1
        binary_message += str(bit)

    message = ''.join([chr(int(binary_message[i:i+8], 2)) for i in range(0, len(binary_message), 8)])
    return message

sequence_numbers = [4200737474, 2928584394, 2798024358, 2788084474, 4134962918] message_parts = []
for seq in sequence_numbers:
    message_part = decode_seq_num(seq, 32)  # Decode 4 characters (32 bits)
    message_parts.append(message_part)

full_message = ''.join(message_parts).replace('\x00', '') #Remove \x00
print(f"Decoded Message: {full_message}")

Скрипт выведет декодированное сообщение (флаг)!

2. Стеганография в ICMP пакетах:

Простой пример задачи:

Нам нужно исследовать необычный ICMP-трафик. У вас есть дамп трафика icmp_mystery.pcap.

Известно, что в трафике может быть скрытое сообщение, зашифрованное XOR-шифром. Однако ключ шифрования не передается в явном виде в пакетах. Нам нужно его определить.

1. Открытие и фильтрация PCAP файла в Wireshark:

Теперь фильтруем по протоколу ICMP:

Аномалии, на которые следует обратить внимание:

• Необычно большой размер ICMP-пакетов.

• Повторяющиеся символы в поле данных, которые выглядят осмысленно.

В нашем случае, один пакет длиной 64 байта.

Просмотрим поле Data в этом пакете. Мы увидим зашифрованные данные.

Data: 545e5355694a5d404d7b614d617b7f627e774d7067664d74677c6f00000000000000000000000000000000000000000000000000000000000000000000000000

2. Анализ и взлом XOR-шифра (Python):

XOR-шифр очень прост. Если вы знаете часть открытого текста, можно восстановить ключ.

А мы знаем, что флаг начинается с FLAG{. Это нам поможет!

def decrypt_message(encrypted_bytes, key):
    """Расшифровывает сообщение с помощью XOR."""
    decrypted_message = "".join([chr(byte ^ key) for byte in encrypted_bytes])
    return decrypted_message

hex_data = "545e5355694a5d404d7b614d617b7f627e774d7067664d74677c6f00000000000000000000000000000000000000000000000000000000000000000000000000"  # Наши данные
encrypted_bytes = bytes.fromhex(hex_data)

known_plaintext = "FLAG{"
# Вычисляем ключ на основе известного начала
key = encrypted_bytes[0] ^ ord(known_plaintext[0]) # Вычисляем ключ по первому байту

# Расшифровываем все сообщение
decrypted_message = decrypt_message(encrypted_bytes, key)
print(f"Расшифрованное сообщение: {decrypted_message}")

Флаг получен: