Linux htb что это

Обновлено: 05.07.2024

Разделение, ограничение и управление трафиком - актуальная и сложная задача,
которую обычно возлагают на дорогостоящее специальное сетевое оборудование. Но
решить ее можно и с помощью подсистемы Linux-ядра Traffic Control, не
уступающей по возможностям Cisco IOS.

Допустим, существует офис некой компании X, и в нем числится около ста
сотрудников, каждый из которых может выходить в интернет через шлюз. Скорость
внешнего канала составляет 100 Мбит. Системный администратор справился с
настройкой шлюза в силу своих способностей – что и посчитал достаточным для
правильного функционирования сети. К чему это привело? К увольнению
недальновидного (или ленивого) админа.

Со временем большинство сотрудников начали жаловаться на "тормоза" интернета,
а другие, наоборот, заметили, что могут качать торренты в рабочее время на очень
внушительных скоростях. Говоря админским языком, в сети образовались заторы,
вызванные теми, кто в тот момент активно ее использовал. Стомегабитный канал
распределялся неравномерно между пользователями, и каждый мог занять его весь.
Остальным приходилось ждать.

Краткий сценарий

Решение проблемы: разделение канала между сотрудниками с ограничением
скорости! Сеть будет функционировать на "5+", если каждый сотрудник получит в
распоряжение отдельный канал, скорость которого будет составлять 1 Мбит. Тогда
отдельно взятый интернет-пользователь не сможет занять больше причитающейся ему
доли и отобрать часть канала у других. С точки зрения компании, это еще и
отличный способ экономии (после разделения канала оказывается, что его суммарная
пропускная способность даже излишне высока) и ведения статистики по трафику для
отдельно взятого сотрудника.

Обычно для разделения канала с ограничением скорости используются возможности
операционной системы IOS, на которой функционирует сетевое оборудование Cisco
(дешевые решения от других производителей, таких, как Dlink, Trendnet и Netgear,
вообще не обладают такой возможностью). Однако особой необходимости тратить
баснословные суммы на аппаратные шлюзы от Cisco нет. Ядро Linux уже более пяти
лет как содержит в себе код сложной и весьма функциональной подсистемы
управления трафиком Traffic Control, которая по некоторым параметрам даже
обходит IOS.

Подсистема Traffic Control

Подсистема Traffic Control поддерживает множество методов
классификации, приоритезации, разделения и ограничения трафика (как исходящего,
так и входящего). Она очень гибка в настройке, но сложна в понимании. Поэтому мы
уделим значительную часть статьи теоретическому материалу и лишь затем приступим
к решению задачи с помощью HTB – одной из наиболее гибких и популярных дисциплин
Traffic Control.

Подсистема управления трафиком Linux позволяет делать следующее:

  • Shaping. Шейпинг - ограничение трафика, задержка пакетов с
    целью создания желаемой скорости передачи. Может использоваться не только для
    "сужения" исходящего канала, но и для сглаживания бросков во время пиковых
    нагрузок.
  • Scheduling. Планирование – упорядочивание типов трафика в
    канале. Позволяет избегать задержек для критичных типов трафика (QoS).
  • Policing. Политика входящего трафика. Позволяет ограничить
    входящий трафик путем уничтожения превысивших лимит пакетов. Помогает бороться
    с DDoS.

Отметим, что ограничение без потерь возможно только в отношении исходящего
трафика. Стек протоколов TCP/IP не предусматривает возможности заставить
удаленную сторону слать пакеты медленнее (и это правильно).

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

  • Дисциплина обработки пакетов (qdisc) - очередь пакетов и
    закрепленный за ней алгоритм обработки.
  • Класс (class) - логический контейнер, который может
    содержать несколько подклассов или дисциплину.
  • Фильтр (filter) - механизм классификации трафика.

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

Linux действует таким же образом. Но формат представления очереди и алгоритм
ее обработки, в совокупности называемые дисциплиной обработки пакетов, в нем
заменяемы! По умолчанию используется дисциплина pfifo_fast, реализующая очередь
FIFO. Пользуясь утилитой tc, администратор может заменить ее на другую
дисциплину, которая будет переупорядочивать пакеты (планирование), задерживать
их на определенное время (шейпинг) или выполнять другие действия.

Дисциплины классов

Traffic Control не был бы столь гибким, если бы не позволял разбивать
трафик на классы с помощью классовой дисциплины и набора ее подклассов.
Схематически классовая дисциплина очень похожа на файловую систему, c тем лишь
исключением, что ее корень или классы (каталоги) могут содержать либо дисциплину
(файл), либо подклассы (подкаталоги). Одно из двух. Классовые дисциплины и
классы предназначены для построения дерева выбора. Сначала весь трафик
разбивается на несколько общих классов (например, трафик до Отдела-1, трафик до
специализированных внутренних серверов и т.д.), а затем каждый из них
разбивается на несколько подклассов (например, трафик до DNS-сервера Отдела-1),
за которыми уже могут быть закреплены дисциплины.

Чтобы управлять тем, дисциплиной какого класса будет обработан определенный
тип трафика, классовые дисциплины позволяют подключать к себе фильтры. Это дает
возможность "завернуть" определенный трафик в один из ее подклассов. Фильтры
используют классификаторы для идентификации пакетов нужного типа и как бы
говорят ядру: "Этот вид трафика должен обрабатываться с помощью дисциплины вот
этого класса". Существует несколько разных классификаторов. Самыми популярными
являются u32 и fw. Первый позволяет выделять пакеты по исходящим адресам и
адресам назначения, портам, парам "хост:порт", типам протокола и типу сервиса.
Второй классифицирует пакеты путем чтения маркировок, записанных брандмауэром
iptables/netfilter (цель MARK).

За каждым сетевым интерфейсом должны быть закреплены две особые дисциплины:
корневая дисциплина (root qdisc) и входящая дисциплина (ingress qdisc). В первую
помещается весь исходящий трафик (по умолчанию используется дисциплина
pfifo_fast). Во вторую - входящий.

Для идентификации дисциплин и классов используются дескрипторы. Они состоят
из старшего и младшего номеров. Первый - это произвольное число, однако все
классы, имеющие общего родителя, должны иметь одинаковый старший номер. Младший
номер используется либо для произвольной идентификации классов, либо для
указания на то, что объект является дисциплиной (номер 0). Специальный
дескриптор ffff:0 зарезервирован для входящей дисциплины.

Утилита tc

Для конфигурирования подсистемы управления трафиком предназначена утилита tc
из пакета iproute2. Она принимает набор команд в качестве аргументов, с помощью
которых можно создавать классы, привязывать к ним дисциплины и добавлять
фильтры. Синтаксис ее похож на синтаксис команды ipfw из операционной системы
FreeBSD, так что знакомые с ним быстро освоятся.

Для примера рассмотрим простейший вариант использования:

Эта команда устанавливает ограничение для всего исходящего трафика в 256
Кбит/с. Разберем подробнее все аргументы tc:

  • qdisc add - добавляем новую дисциплину (для удаления используй del).
  • dev eth0 - указываем устройство, к которому будет привязана дисциплина.
  • root - наша дисциплина корневая (будет обрабатываться весь трафик).
  • tbf - имя дисциплины.
  • rate 256kbit latency 50ms burst 1540 - параметры, специфичные для данной
    дисциплины: rate - ограничение скорости, latency - максимальный "возраст"
    пакета в очереди, burst - размер буфера.

Проще говоря, команда подключает дисциплину tbf в качестве корневой на
интерфейсе eth0 и задает ей несколько параметров. Token Bucket Filter (TBF) -
это бесклассовая дисциплина, которая передает поступающие пакеты с заданной
скоростью.

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

Формат указания скорости в утилите tc

mbps = 1024 kbps = 1024 * 1024 bps => Байт/с
mbit = 1024 kbit => Кбит/с
mb = 1024 kb = 1024 * 1024 b => Байт

Заменить стандартную корневую дисциплину на любую бесклассовую совсем
несложно, но на таком коне далеко не уедешь. Для создания разветвленной системы
управления трафиком нужны классовые дисциплины, классы, фильтры и целое дерево
дисциплин. Чтобы настроить все это, может понадобиться не один десяток команд.
Мы рассмотрим несколько вводных примеров, перед тем как перейти к обсуждению
дисциплины HTB.

Пример дерева дисциплин

Подключим дисциплину prio в качестве корневой и назначим ей имя (дескриптор)
"1:0":

Результат этой команды: дисциплина prio, подключенная в качестве корня, и три
класса (1:1, 1:2 и 1:3) внутри нее, к каждому из которых подключена дисциплина
FIFO.

Мы вольны заменить любую из дисциплин, подключенных к классам, чем и
воспользуемся для подключения дисциплины sfq с дескриптором "10:0" к классу
"1:1":

Это обеспечит справедливое разделение канала между интерактивными
приложениями (они имеют наивысший приоритет). Чтобы остальные приложения, такие
как менеджеры закачек и torrent-клиенты (которые обычно шлют пакеты с меньшим
приоритетом в поле TOS), не мешали интерактивным, ограничим для них скорость:

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

Теперь сделаем так, чтобы весь SSH-трафик имел наивысший приоритет. Для этого
закрепим за корневой дисциплиной prio фильтр, который будет перенаправлять
пакеты с портом назначения 22 в дисциплину класса "1:1".

Рассмотрим подробнее механизм подключения фильтров.

  • filter add - Добавляем фильтр.
  • dev eth0 - Указываем устройство.
  • parent 1:0 - Дескриптор родителя.
  • protocol ip - Протокол, с которым будет работать фильтр.
  • prio 1 - Присваиваем классифицированному трафику приоритет 1 (наивысший).
  • u32 - Используемый классификатор.
  • match ip dport 22 0xffff - Параметры классификатора. В данном случае
    указание отбирать пакеты с портом назначения 22.
  • flowid 1:1 - Отфильтрованные пакеты должны иметь класс "1:1" и
    обрабатываться с помощью его дисциплины.

Это все. Мы получили разветвленную систему управления трафиком, выполнив
всего пять команд.

Классовая дисциплина HTB

Еще в первый релиз системы Traffic Control была включена классовая
дисциплина CBQ (Class-Based Queue), предназначенная для реализации сложных
систем управления и ограничения трафика. CBQ завоевала большую популярность
благодаря своей гибкости, но была очень сложна, запутана и обладала рядом
ограничений (тут и необходимость заранее указывать максимальную пропускную
способность канала, и неэффективный алгоритм шейпинга).

Поэтому в скором времени появилась более эффективная и простая в
использовании альтернатива под названием HTB (Hierarchical Token
Bucket). Классовая дисциплина HTB предназначена для разделения полосы
пропускания между различными видами трафика, каждому из которых может быть
предоставлена полоса гарантированной ширины. Она не обладает гибкостью CBQ, но
гораздо более проста в настройке и лишена ее недостатков. Именно на HTB сегодня
принято строить сложные и эффективные системы ограничения трафика.

Рассмотрим применение HTB на примере, представленном в начале статьи, но
более усложненном. Допустим, у нас есть шлюз на Linux, интерфейс eth1 которого
смотрит наружу, а eth0 - во внутреннюю сеть. Ширина канала - 100 Мбит. Задача:
разделить канал между сотрудниками компании так, чтобы директор и сотрудники
IT-отдела могли выходить в интернет без скоростных ограничений, маркетологи
получили ограничение в 2 Мбит/c каждый, менеджеры - 1 Мбит/c, секретари - 512
Кбит/c, а все остальные - 256 Кбит/c.

Есть два варианта решения. Первый: составить огромную таблицу IP-адресов и
создать специальные правила ограничений для каждого адреса (с точки зрения
системы HTB это будет выглядеть как огромный набор классов и фильтров, по одному
на каждый адрес). Второй: разбить всех потребителей канала на мета-группы,
каждую из которых выделить в отдельную подсеть (директор и IT-отдел -
172.16.1.0, маркетологи - 172.16.2.0, менеджеры - 172.16.3.0, секретари -
172.16.4.0, остальные - 172.16.5.0). Для каждой подсети назначить суммарное для
всех ее членов ограничение со справедливым разделением канала.

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

Для начала создадим работоспособную систему, основанную только на втором
варианте решения задачи. Подключим дисциплину HTB в качестве корневой:

Опция "default 15" говорит о том, что весь неклассифицированный фильтрами
трафик должен быть обработан с помощью дисциплин класса "1:15". Создадим
корневой класс, под который будет попадать весь трафик (это нужно для реализации
заимствования):

Создадим в нем пять подклассов для пяти наших подсетей. Директору и IT-отделу
выделим 30-мегабитный канал с возможностью его расширения (заимствования) вплоть
до 100 Мбит в случаях, когда остальные каналы не заняты:

Для маркетологов выделим 20-мегабитный канал:

Менеджерам – 10 Мбит/с:

Секретарям – 5 Мбит/с:

И – 40 Мбит/с на всех остальных:

По умолчанию к вновь созданным классам подключены дисциплины, реализующие
очередь FIFO. Это нам не подходит. Чтобы канал равномерно распределялся между
всеми участниками подсети, мы должны подключить к ним дисциплину sfq:

Теперь подключим фильтры, которые будут классифицировать трафик:

Для "всех остальных" фильтр не нужен, потому как мы уже указали дефолтовый
класс неклассифицированного трафика.

Все, система будет работать, но не обеспечит жесткого ограничения для каждого
пользователя (если, например, в определенный момент времени интернетом будет
пользоваться только один менеджер, ему достанутся все 10 Мбит, отведенные для
всех менеджеров). Жесткое ограничение можно реализовать, если вместо дисциплин
подключить к классам другие классы HTB, по одному на каждого пользователя, и
создать соответствующие фильтры.

Для примера, установим ограничение в 256 Кбит/с для пользователя,
находящегося в подсети "все остальные". Сначала добавим к "классу-подсети" новый
"класс-пользователь":

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

Под катом описано как шейпировать трафик в Linux и что для этого нужно знать.
Осуществлять шейпирование трафика будем посредством утилиты tc из пакета iproute2.
Знания без которых нельзя осознать всю полноту управления трафиком в Linux:
Шейпировать можно только исходящий из интерфейса трафик. (в связи с чем возникает проблема с nat, о ней мы поговорим позже). Предположим, что имеется роутер между «интернетом» и абонентом. В роутер воткнуто две сетевые карты: eth0 смотрит на абонента, а eth1 в мир. Для ограничения «скорости скачивания» правила шейпирования описываем на eth0, для ограничения «отдачи» — на eth1.
Необходимо понимать разницу между rate и ceil. Rate — гарантированная полоса пропуская, Ceil — максимальная полоса которую может получить данный класс, rate не может быть больше ceil
Параметры rate и ceil для корневого класса должны совпадать. Таким образом мы определяем общую полосу пропускания.
Сумма Rate'ов классов-потомков, не должна превышать Rate родительского класса. Конечно можно не выполнять этот пункт, но тогда могут возникнуть проблемы с предоставлением «гарантированной полосы пропускания».
Идентификаторы классов указаны в шестнадцатеричной системе, и должны находиться в пределах от 2 до 2^16
Для промежуточных классов необязательно создавать дисциплины и фильтры.
Идентификаторы классов в пределах интерфейса должны быть уникальны.

В простом варианте изложения алгоритм нарезки трафика выглядит так:
1. Создаем корневую дисциплину для интерфейса и указываем класс куда будет попадать не классифицированный трафик.
2. Создаем корневой класс и определяем ширину канала.
3. Создаем дочерний класс для шейпирования абонента.
4. Создаем дисциплину шейпирования для класса абонента.
5. Создаем фильтра позволяющие классифицировать трафик абонента.

Получение htbinit
debian:

Создаем класс для не классифицированного трафика
debian:

Создаем общий клиентский класс. Пускай его ID будет равно «D» и всего для абонентов мы выделим 10 Мбит.
debian:

Теперь можно заняться абонентами.
Что бы ограничить скорость скачивания в 512 КБит абоненту Василию нужно:
Создать класс для абонента Василия. Пускай ID клиентов будут начинаться с 255. Весьма полезно, если потребуется создать какой либо «системный» класс.
debian:

Название файла генерируется таким образом:
1. Интерфейс к которому принадлежит класс.
2. Разделитель "-"(минус)
3. ID корневого класса
4. Разделитель ":"(двоеточие)
5. ID родительского класса
6. Разделитель ":"(двоеточие)
7. ID клиентского класса
8. Разделитель "."(точка)
9. Мнемоническая составляющая названия файла
Пункты 5 и 6 могут отсутствовать, в зависимость от выбранной Вами стратегии шейпирования.


Под­клю­чать­ся к машинам с HTB рекомен­дует­ся толь­ко через VPN. Не делай это­го с компь­юте­ров, где есть важ­ные для тебя дан­ные, так как ты ока­жешь­ся в общей сети с дру­гими учас­тни­ками.

Разведка. Сканирование портов

До­бав­ляем IP-адрес машины в / etc/ hosts :

И ска­ниру­ем пор­ты.

Справка: сканирование портов

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

На­ибо­лее извес­тный инс­тру­мент для ска­ниро­вания — это Nmap. Улуч­шить резуль­таты его работы ты можешь при помощи сле­дующе­го скрип­та.

ports = $( nmap -p- --min-rate = 500 $1 | grep ^[ 0- 9] | cut -d '/ ' -f 1 | tr '\ n' ', ' | sed s/, $/ / )

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A ).

Результат работы скрипта

Ре­зуль­тат работы скрип­та

На­ходим три откры­тых пор­та: 21 (FTP-сер­вер vsftpd 3.0.3), 22 (служ­ба SSH 8.2p1) и 80 (веб‑сер­вер gunicorn).

Справка: брутфорс учеток

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

Пос­мотрим, не дос­тупно ли что‑то на FTP ано­ним­ным поль­зовате­лям.

Попытка подключения к FTP как anonymous

По­пыт­ка под­клю­чения к FTP как anonymous

Ни­чего не получи­лось, поэто­му нам нуж­но «про­бивать» веб.

Точка входа. Сканирование веб-контента

По­ищем, нет ли чего‑нибудь инте­рес­ного на сай­те. Наша цель — опре­делить век­тор даль­нейшей ата­ки, но по дороге нуж­но собирать и дру­гую информа­цию: име­на поль­зовате­лей, исполь­зуемые тех­нологии и про­чее.

На сай­те нас встре­чает какая‑то ста­тис­тика, а так­же есть сле­дующие стра­ницы:

  • Security Snapchat — показы­вает про­токо­лы и количес­тво сетевых пакетов;
  • IP Config — на этой стра­нице отоб­ража­ется информа­ция о сетевых интерфей­сах;
  • Network Status — показа­ны кон­фигура­ции сети.

Да­вай перей­дем к стра­нице Security Snapchat. Нам пре­дос­тавле­на воз­можность что‑то ска­чать, сде­лаем это.

Скачивание PCAP-файла с Security Snapchat

Ска­чива­ние PCAP-фай­ла с Security Snapchat

От­крыв файл (я для это­го исполь­зовал Wireshark), обна­ружим, что он пуст. Видимо ста­тис­тика по сетевым пакетам, которая отоб­ража­ется на стра­нице, соб­рана имен­но по это­му фай­лу.

Окно Wireshark

Ок­но Wireshark

Те­перь прос­каниру­ем содер­жимое дирек­тории / data/ , к при­меру с помощью ffuf, которо­му в качес­тве парамет­ров нуж­но передать спи­сок для перебо­ра (опция -w ) и URL (опция -u ). Мес­то, куда будут под­став­лять­ся сло­ва из спис­ка, пометим пос­ледова­тель­ностью FUZZ . Так как инте­рес­ны адре­са, которые вер­нут код 200, ука­жем это в парамет­ре -mc .

Результат перебора с помощью ffuf

Ре­зуль­тат перебо­ра с помощью ffuf

За­ходя на раз­ные стра­ницы, мы видим чис­ло пакетов в том или ином дам­пе тра­фика. Так мож­но опре­делить, что если раз­мер отве­та равен 17 144 бай­там, то соот­ветс­тву­ющий дамп будет пуст. Наша теория под­твер­дилась пос­ле того, как мы откры­ли стра­ницу номер 22, раз­мер которой сос­тавля­ет 17 154 бай­та. С нее мы можем ска­чать непус­той дамп тра­фика.

Загрузка файлов в Burp History

Заг­рузка фай­лов в Burp History

Продолжение доступно только участникам

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее


Под­клю­чать­ся к машинам с HTB рекомен­дует­ся толь­ко через VPN. Не делай это­го с компь­юте­ров, где есть важ­ные для тебя дан­ные, так как ты ока­жешь­ся в общей сети с дру­гими учас­тни­ками.

Разведка. Сканирование портов

До­бав­ляем IP-адрес машины в / etc/ hosts :

И ска­ниру­ем пор­ты.

Справка: сканирование портов

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

На­ибо­лее извес­тный инс­тру­мент для ска­ниро­вания — это Nmap. Улуч­шить резуль­таты его работы ты можешь при помощи сле­дующе­го скрип­та.

ports = $( nmap -p- --min-rate = 500 $1 | grep ^[ 0- 9] | cut -d '/ ' -f 1 | tr '\ n' ', ' | sed s/, $/ / )

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A ).

Результат работы скрипта

Ре­зуль­тат работы скрип­та

Мы наш­ли мно­го откры­тых пор­тов, давай прой­дем­ся по поряд­ку:

В ито­ге мы получа­ем очень важ­ную информа­цию. Во‑пер­вых, мы можем работать со служ­бой FTP без авто­риза­ции, а во‑вто­рых, SQL Server дал нам име­на домена ( LICORDEBELLOTA ) и текущей машины ( PIVOTAPI ).

Да­вай ска­чаем все фай­лы с FTP-сер­вера для даль­нейше­го ана­лиза. Сде­лаем это с помощью wget :

В докумен­тах ничего важ­ного для прод­вижения не наш­лось, но тема инте­рес­ная — они опи­сыва­ют спо­собы экс­плу­ата­ции раз­личных уяз­вимос­тей. Но, как отме­чает­ся в любом кур­се OSINT (раз­ведка на осно­ве откры­тых источни­ков), если мы смог­ли получить какие‑либо докумен­ты, нас могут заин­тересо­вать метадан­ные, а имен­но атри­буты «соз­датель» и «вла­делец». Из них иног­да мож­но узнать име­на, под­ходящие в качес­тве логинов. Смот­реть эти дан­ные мож­но раз­ными метода­ми, я вос­поль­зуюсь exiftool (уста­нав­лива­ется коман­дой sudo apt install exiftool ).

Свойства документа notes1.pdf

Свой­ства докумен­та notes1.pdf

Соз­дав прос­той кон­вей­ер на Bash, получим из всех докумен­тов поля Creator и Author .

Владельцы и создатели файлов

Вла­дель­цы и соз­датели фай­лов

От­кинув сом­нитель­ные записи, мы можем сос­тавить спи­сок из пяти воз­можных имен поль­зовате­лей: saif , byron , cairo , Kaorz , alex .

Точка входа. ASRep Roasting

Так как на хос­те работа­ет Kerberos, мы можем про­верить, сущес­тву­ет ли какая‑то учет­ная запись. В этом нам поможет ата­ка ASRep Roasting. Смысл ее в том, что мы посыла­ем на сер­вер аутен­тифика­ции ано­ним­ный зап­рос для пре­дос­тавле­ния опре­делен­ному поль­зовате­лю дос­тупа к какой‑либо услу­ге. Сер­вер в ответ:

  • пре­дос­тавля­ет хеш;
  • от­веча­ет, что у дан­ного поль­зовате­ля не выс­тавлен флаг UAF Don't Require PreAuth ;
  • го­ворит, что такого поль­зовате­ля нет в базе Kerberos.

Вы­пол­нить ата­ку мы можем с помощью скрип­та GetNPUsers, вхо­дяще­го в сос­тав пакета скрип­тов impacket. Зада­ем скрип­ту сле­дующие парамет­ры: кон­трол­лер домена ( -dc-ip ), спо­соб аутен­тифика­ции Kerberos ( -k ), опция «без пароля» ( -no-pass ), спи­сок поль­зовате­лей ( -usersfile ) и целевой хост в фор­мате домен/ хост .

GetNPUsers. py -dc-ip 10. 10. 10. 240 -no-pass -k -usersfile users. txt LICORDEBELLOTA/ pivotapi. htb

Результат работы скрипта

Ре­зуль­тат работы скрип­та

Нам говорят, что, кро­ме поль­зовате­ля Kaorz , в базе Kerberos боль­ше никого нет, при­чем для учет­ной записи Kaorz сер­вер аутен­тифика­ции вер­нул нам хеш! Давай раз­берем­ся, что это за хеши и почему их раз­дают кому попало.

Де­ло в том, что, ког­да кли­ент посыла­ет сооб­щение c иден­тифика­тором поль­зовате­ля на сер­вер аутен­тифика­ции и зап­рашива­ет дос­туп к услу­ге для какого‑то поль­зовате­ля, сер­вер аутен­тифика­ции смот­рит, есть ли поль­зователь в базе Kerberos, пос­ле чего про­веря­ет его учет­ные дан­ные. Если учет­ные дан­ные невер­ны, сер­вер отве­чает сооб­щени­ем UAF Don’t Require PreAuth .

Но есть одно огра­ниче­ние: у учет­ной записи поль­зовате­ля может быть акти­виро­ван флаг DONT_REQ_PREAUTH , который озна­чает, что для дан­ной учет­ной записи не тре­бует­ся пред­варитель­ная про­вер­ка под­линнос­ти Kerberos. Для это­го поль­зовате­ля учет­ные дан­ные не про­веря­ются и сер­вер аутен­тифика­ции генери­рует сек­ретный ключ, хешируя пароль поль­зовате­ля, най­ден­ный в базе дан­ных. Получа­ется, мы можем проб­рутить хеш и узнать пароль поль­зовате­ля!

Бру­тить хеш будем по сло­варю прог­раммой hashcat. При запус­ке нам нуж­но передать номер типа хеша (параметр -m ), поэто­му сна­чала узна­ем его, зап­росив справ­ку и отфиль­тро­вав толь­ко нуж­ный нам тип.

Получение номера типа хеша

По­луче­ние номера типа хеша

Ис­комый номер — 18200. Теперь запус­каем перебор, при этом в парамет­рах ука­зыва­ем перебор по сло­варю ( -a 0 ), тип хеша krb5asrep (-m 18200`), файл с хешем и сло­варь.

/ wordlists/ rockyou. txt

Результат перебора хеша

Ре­зуль­тат перебо­ра хеша

Очень быс­тро находим иско­мый пароль учет­ной записи Kaorz . Так как у нас появи­лись учет­ные дан­ные, нуж­но поп­робовать с ними под­клю­чить­ся ко всем дос­тупным ресур­сам. FTP учет­ных дан­ных не тре­бует, поэто­му про­верим SMB. Для это­го я обыч­но исполь­зую ути­литу smbmap.

Доступные ресурсы SMB

Дос­тупные ресур­сы SMB

В выводе получим спи­сок дос­тупных ресур­сов SMB и раз­решения для каж­дого. Что­бы дол­го не ходить по дирек­тори­ям и не искать инте­рес­ные фай­лы, есть удоб­ная воз­можность вывес­ти все содер­жимое ресур­сов рекур­сивно. Для это­го в smbmap нуж­но ука­зать опцию -R . Про­лис­тав спи­сок, обра­щаем вни­мание на каталог HelpDesk , который содер­жит исполня­емый файл и два фай­ла msg , то есть какие‑то сооб­щения.

Содержимое каталога HelpDesk

Со­дер­жимое катало­га HelpDesk

Что­бы заполу­чить фай­лы, можем запус­тить любой кли­ент SMB. Я буду исполь­зовать smbclient, пос­коль­ку он тоже вхо­дит в набор impacket.

smbclient. py LicorDeBellota/ Kaorz: Roper4155@10. 10. 10. 240

Загрузка файлов с SMB

Заг­рузка фай­лов с SMB

Точка опоры

Конвертация MSG

Файл .msg содер­жит элек­трон­ное пись­мо в фор­мате Microsoft Outlook и вклю­чает дан­ные отпра­вите­ля и получа­теля, тему и текст пись­ма. Так­же в виде фай­ла .msg может быть сох­ранена информа­ция о встре­че или ином событии из кален­даря Outlook, дан­ные кон­такта из адресной кни­ги, све­дения о задаче. Его мож­но кон­верти­ровать в обыч­ный тек­сто­вый фор­мат с помощью ути­литы msgconvert. Но сна­чала ее сле­дует уста­новить.

sudo apt install libemail- outlook- message- perl libemail- sender- perl Со­дер­жимое сооб­щения Server MSSQL Со­дер­жимое сооб­щения WinRM Service

В пер­вом сооб­щении говорит­ся, что в 2010-е годы была уста­нов­лена база Oracle, но в 2020 году решили перей­ти на MS SQL. При этом най­ден­ное при­ложе­ние Reset-Service. exe было соз­дано для рес­тарта служ­бы Oracle. Что здесь очень важ­но — это фун­кция логина, то есть при­ложе­ние работа­ет с учет­ными дан­ными.

Во вто­ром сооб­щении упо­мина­ется бло­киров­ка служ­бы WinRM и исхо­дяще­го тра­фика по про­токо­лам TCP, UDP и ICMP.

Анализ приложения, использующего вызов CMD

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

Спи­сок импорти­руемых фун­кций

Об­ратим вни­мание на фун­кцию ShellExecuteEx , которая дол­жна выпол­нять коман­ды в коман­дной стро­ке. Еще здесь мно­го фун­кций для работы с фай­лами ( DeleteFile , CreateFile , GetTempPathW и про­чие). Что­бы наг­лядно отсле­дить работу с фай­лами и запуск команд, акти­виру­ем Process Monitor. Пос­ле запус­ка соз­дадим филь­тр, который будет отсле­живать толь­ко наш целевой про­цесс.

Фильтр Process Monitor

Филь­тр Process Monitor

Ког­да все будет готово, запус­тим исполня­емый файл и прос­мотрим вывод Process Monitor.

События в Process Monitor

Со­бытия в Process Monitor

В событи­ях мы видим соз­дание фай­лов .tmp и запись (ско­рее все­го, копиро­вание) скрип­та .bat. Далее соз­дает­ся про­цесс коман­дно­го интер­пре­тато­ра cmd. exe . А раз он запус­кает­ся, то мы можем вос­поль­зовать­ся CMDWatcher. Эта ути­лита будет при­оста­нав­ливать про­цесс и показы­вать аргу­мен­ты при запус­ке CMD в любых про­цес­сах. Запус­тим CMDWatcher, а потом ана­лизи­руемое при­ложе­ние. Мы уви­дим, как запус­кает­ся при­ложе­ние, а затем — как акти­виру­ется сце­нарий bat.

Со­бытие запус­ка при­ложе­ния Restart-OracleService.exe Со­бытие запус­ка фай­ла bat

Прой­дем в дирек­торию с запус­каемым скрип­том и уви­дим в ней сам скрипт и файл с рас­ширени­ем tmp.

Содержимое каталога /AppData/Local/Temp/

Со­дер­жимое катало­га /AppData/Local/Temp/

Заг­лянем в скрипт. В начале видим про­вер­ку на запуск от име­ни опре­делен­ного поль­зовате­ля. Сра­зу сох­раня­ем себе его имя — при­годит­ся! Затем дан­ные записы­вают­ся в файл C:\ programdata\ oracle. txt . Кодиров­ка напоми­нает Base64.

Содержимое скрипта

Со­дер­жимое скрип­та

Пос­ле записи соз­дает­ся еще один файл — C:\ programdata\ monta. ps1 , он содер­жит код на PowerShell. Этот код счи­тыва­ет дан­ные из фай­ла C:\ programdata\ oracle. txt , декоди­рует их из Base64 и записы­вает в C:\ programdata\ restart-service. exe . Затем уда­ляют­ся и файл с дан­ными Base64, и скрипт на PowerShell и запус­кает­ся новосоз­данный исполня­емый файл restart-service. exe . Пос­ле выпол­нения он уда­ляет­ся.

Содержимое скрипта

Со­дер­жимое скрип­та

Да­вай получим этот исполня­емый файл для даль­нейше­го ана­лиза. Для это­го нем­ного модер­низиру­ем наш бат­ник: в начале скрип­та убе­рем про­вер­ку поль­зовате­лей, а в кон­це — любые уда­ления фай­лов (коман­да del ), убе­рем так­же запуск соз­дающе­гося исполня­емо­го фай­ла.

Мо­дер­низиро­ван­ный bat-скрипт (начало) Мо­дер­низиро­ван­ный bat-скрипт (конец)

За­пус­тим изме­нен­ный скрипт, пос­ле чего про­верим каталог C:\ programdata , там нас будет ждать файл с дан­ными, скрипт на PowerShell и целевая прог­рамма.

Содержимое каталога C:\programdata

Со­дер­жимое катало­га C:\programdata

Анализ приложения со скрытыми функциями

Ис­полня­емый файл откры­ваем в IDA Pro, что­бы пос­мотреть импорти­руемые фун­кции. Но там не было ничего инте­рес­ного, а для ста­тичес­кого ана­лиза файл велико­ват. Имен­но по этой при­чине я решил исполь­зовать при­ложе­ние API Monitor. Оно может отоб­ражать все вызовы API-фун­кций вмес­те с переда­ваемы­ми в них аргу­мен­тами.

Пос­ле запус­ка API Monitor нуж­но ука­зать целевой исполня­емый файл, для чего выбира­ем Monitor New Process. В раз­деле спра­ва уви­дим все выз­ванные при­ложе­нием фун­кции.

Стар­товое окно при­ложе­ния API Monitor Вы­бор исполня­емо­го фай­ла Ре­зуль­тат ана­лиза фай­ла

Час­то вызыва­ется GetProcAddress . Дело в том, что DLL может заг­ружать­ся при­ложе­нием не толь­ко ста­тичес­ки (при запус­ке), но и динами­чес­ки (во вре­мя выпол­нения) с помощью фун­кции LoadLibrary . А для получе­ния адре­са фун­кции в заг­ружен­ной DLL как раз исполь­зует­ся фун­кция GetProcAddress , которая в качес­тве парамет­ра получа­ет имя импорти­руемой фун­кции. Эта тех­ника усложня­ет ста­тичес­кий ана­лиз, а имен­но скры­вает важ­ные фун­кции из таб­лицы импорта.

Да­вай узна­ем, какие фун­кции хотел спря­тать раз­работ­чик. Для это­го необ­ходимо уста­новить филь­тр, что­бы в выводе при­сутс­тво­вали толь­ко фун­кции GetProcAddress . В кон­текс­тном меню выбира­ем Include → API Name.

Ус­танов­ка филь­тра От­филь­тро­ван­ный спи­сок фун­кций API

Сра­зу видим мно­жес­тво фун­кций для работы с реес­тром, но это пока ничего не говорит. Что­бы сло­жить целос­тную кар­тину, прос­мотрим абсо­лют­но все заг­ружа­емые фун­кции (это зай­мет 5–10 минут). Во вре­мя ана­лиза оста­нав­лива­емся на CreateProcessWithLogonW . Это важ­ная фун­кция!

Отфильтрованный список API-функций

От­филь­тро­ван­ный спи­сок API-фун­кций

Она соз­дает новый про­цесс и его пер­вичный глав­ный поток. Новый про­цесс затем запус­кает задан­ный исполня­емый файл в кон­тек­сте сис­темы безопас­ности опре­делен­ного поль­зовате­ля. Дело в том, что эта фун­кция при­нима­ет учет­ные дан­ные поль­зовате­ля в качес­тве аргу­мен­тов. Давай най­дем ее вызов, что­бы получить эти парамет­ры. Для это­го выбира­ем в окне Display пункт Add Filter, а затем ука­зыва­ем усло­вие API Name is CreateProcessWithLogonW .

Соз­дание филь­тра Со­бытие вызова фун­кции CreateProcessWithLogonW

Продолжение доступно только участникам

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Читайте также: