Отпечатки пальцев операционной системы с помощью пакетов (часть 1)

Опубликовано: 8 Апреля, 2023

Введение

Контекст. Это самое важное, что у вас есть, когда вы подходите к системе с наступательной или оборонительной точки зрения. Если вы приближаетесь к системе глазами злоумышленника, вам необходимо знать все, что вы можете об этой системе, чтобы вы могли использовать ее, эксфильтровать данные из нее и, в конечном итоге, замести следы при побеге. С другой стороны, если вы защищаете систему, то знание архитектуры этой системы позволит вам узнать, для чего она может быть уязвима, и является ли активность, которую вы наблюдаете, индикатором компрометации или просто шумом в сети. Контекст задает основу для каждого вашего действия. Именно из-за этого злоумышленники и защитники тратят так много времени, пытаясь получить этот контекст.

Если вы атакующий, вы называете это разведкой. Если вы защитник, вы называете это профилированием. В любом случае цель одна и та же; чтобы узнать все, что вы можете о системе. Это часто начинается с выяснения того, какая операционная система (ОС) работает на хосте. Существует множество способов определить эту информацию, но мой любимый метод включает снятие отпечатков ОС с пакетами. В этой серии статей я опишу активное и пассивное снятие отпечатков ОС, концепции, которые делают их правдоподобными, и приведу несколько примеров того, как это можно сделать вручную и автоматически.

RFC, разработчики и пакеты

Чтобы разные системы могли взаимодействовать друг с другом, важно, чтобы существовали стандарты. Эти стандарты регулируют работу различных протоколов, обеспечивающих сетевое взаимодействие, таких как IP, TCP и UDP. Каждый стандарт определен в документе «Запрос комментариев» (RFC), в котором объясняются правила реализации протокола. При наличии этих RFC совместимость систем становится проще простого.

Имея это в виду, нас интересует связь между этими RFC и разработчиками, которые их используют. Давайте посмотрим, например, на RFC 791, который представляет собой RFC для интернет-протокола (IP) и может быть расположен здесь.

Если вы прочитаете RFC, вы найдете информацию о поле в IP-пакете, которое называется Time to Live (TTL). Поле TTL используется для определения максимального времени, в течение которого пакет может оставаться в пути в сети, пока не будет отброшен. RFC содержит подробное описание того, что такое значение TTL, как оно работает и как устройства должны его использовать. Однако достаточно интересно, что RFC не определяет стандартизированное значение TTL. В результате это поле остается открытым для интерпретации разработчиками, создающими каждую программную реализацию протоколов IP. Эта неоднозначность означает, что разные операционные системы используют разные значения TTL по умолчанию, а это означает, что простой анализ пакетов может использоваться для определения того, какой общий тип операционной системы передал конкретный пакет.

Пример, который я только что привел, — лишь один из многих, которые позволяют проводить снятие отпечатков пальцев операционной системы. Некоторые из этих экземпляров сосредоточены на значениях по умолчанию для определенных полей и требуют только образца пакетного трафика от рассматриваемого хоста, в то время как другие сосредоточены на том, как хост может реагировать на определенные типы специально созданных пакетов, требуя от вас связи с хостом.. Разница между ними заключается в том, что вы выполняете пассивный или активный снятие отпечатков ОС, которые мы будем изучать отдельно.

Пассивный отпечаток ОС

Пассивное снятие отпечатков ОС — это проверка пассивно собранной выборки пакетов с хоста с целью определения платформы его операционной системы. Он называется пассивным, поскольку не требует связи с проверяемым хостом. Этот метод предпочитают те, кто находится на оборонительной стороне забора, потому что эти люди обычно рассматривают хосты с точки зрения системы обнаружения сетевых вторжений или брандмауэра. Обычно это означает наличие определенного уровня доступа для захвата пакетов, сгенерированных хостом, для проверки этих данных.

Сравнение хостов

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

Изображение 23258
Рисунок 1: Пакет от хоста А

Изображение 23259
Рисунок 2: Пакет от хоста B

Прежде чем мы начнем рассматривать различия в этих пакетах, давайте посмотрим, что у них общего. Во-первых, мы можем легко определить, что оба хоста отправляют TCP-пакет другому хосту. В пакете TCP установлен только флаг SYN, поэтому он должен быть первым пакетом в последовательности обмена данными. Оба хоста отправляют свои пакеты на порт назначения 80, поэтому мы предполагаем, что это попытка связи с веб-сервером.

Теперь мы можем начать рассматривать пару вещей, которые различаются между двумя пакетами. Первое, что бросается в глаза большинству людей, это то, что хост A упоминает неверную контрольную сумму. В данном случае это нормально для тестовой среды, в которой был захвачен пакет, поэтому его можно игнорировать. Помимо этого, мы можем различить пару процентных отклонений. Давайте пройдемся по этим различиям, а затем попробуем сделать некоторые выводы о хосте, который отправил каждый пакет.

Время жить

Первая разница в двух пакетах — это значение времени жизни (TTL). Мы обсуждали, что документация RFC определяет поле TTL как средство определения максимального времени, в течение которого пакет может оставаться в пути в сети, пока он не будет отброшен. RFC не определяет значение по умолчанию, поэтому разные операционные системы используют разные значения по умолчанию. В этом случае мы можем отметить, что пакет A использует TTL 128, а пакет B использует TTL 64. Помните, что эти пакеты были перехвачены непосредственно от источника передачи. Если бы вы перехватывали эти пакеты с точки зрения получателя, вы бы увидели разные числа в зависимости от того, сколько переходов маршрутизатора находится между источником и пунктом назначения. Например, вместо значения TTL, равного 128, вы можете увидеть значение 116. Как правило, можно с уверенностью предположить, что если вы видите число, близкое к 128 или 64, то значение TTL по умолчанию, скорее всего, было одним из этих двух.

Длина

Я упоминал ранее, что эти два пакета выполняют одну и ту же функцию. Это может привести к предположению, что они будут одинакового размера, но это не так. Пакет A сообщает о своей длине как 52 байта, тогда как пакет B сообщает о длине 60 байт. Это означает, что хост-источник, передающий пакет B, добавил к своему SYN-пакету дополнительные 8 байтов.

Источник этих дополнительных байтов можно найти в заголовке пакета TCP. Заголовок TCP имеет переменную длину. Это означает, что в соответствии со спецификацией каждый пакет, содержащий заголовок TCP, должен включать определенное количество обязательных полей, но может дополнительно включать несколько других полей, если они необходимы. Эти дополнительные поля называются опциями TCP.

В пакете А установлены три параметра TCP. Это параметры «Максимальный размер сегмента», «Масштаб окна» и «Разрешено TCP SACK». Есть также несколько байтов заполнения, которые составляют в общей сложности 12 байтов параметров TCP.

Изображение 23260
Рисунок 3: TCP-заголовок пакета A

В пакете B у нас есть те же параметры с добавлением параметра Timestamp (который также заменяет несколько байтов заполнения, которые мы видим в пакете A).

Изображение 23261
Рисунок 4: TCP-заголовок пакета B

Опция timestamp учитывает дополнительные 8 байтов данных в пакете, отправленном с хоста B. Оба пакета по-прежнему выполняют одну и ту же функцию, пакет от хоста B просто предоставляет немного больше информации о хосте, который его создал и передал.

Принятие решения

Теперь, когда мы указали на несколько различий между пакетами, мы можем попытаться определить исходную операционную систему каждой машины. Чтобы сузить круг вопросов, я скажу вам, что одно из них — устройство Windows, а другое — устройство Linux. Чтобы определить, какой пакет к какой ОС относится, вы можете либо развернуть обе операционные системы в тестовой среде и провести исследование самостоятельно, либо посмотреть на диаграмму, которую кто-то уже подготовил для вас.

Изображение 23262
Рисунок 5: Краткая диаграмма снятия отпечатков ОС

Приведенная выше диаграмма представляет собой очень краткую версию более подробной диаграммы, подготовленной Институтом SANS. Основываясь на этой диаграмме, мы можем определить, что хост A — это устройство Windows, а хост B — это устройство Linux.

Учитывая все вышесказанное, важно отметить, что пассивное снятие отпечатков пальцев не всегда является точной наукой. Мы склонны группировать эти значения по соответствующим семействам операционных систем (Windows, Linux и т. д.), хотя на самом деле устройство Fedora Linux может по умолчанию создавать пакеты другого размера, чем устройство SuSe Linux. Кроме того, многие из этих значений можно настраивать, изменяя файл конфигурации или системный реестр. Это означает, что, хотя устройство Windows обычно может иметь определенный размер окна приема TCP по умолчанию, простая модификация реестра может привести к такому поведению и обмануть наши попытки снять отпечатки пальцев с ОС.

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

Подведение итогов

В этой статье мы обсудили пассивное снятие отпечатков ОС и рассмотрели пример, в котором мы сравнили аналогичные пакеты, отправленные с устройств, использующих разные операционные системы. В следующей статье этой серии мы поговорим об активном снятии отпечатков ОС и о том, как ответы сетевых устройств на определенные типы пакетов могут помочь нам разобраться в их работающей операционной системе.