C2: sliver
Вся информация предоставлена в образовательных или исследовательских целях
В этом посте мы познакомимся с C2 sliver, научимся использовать его для проведения фишинговых атак и рассмотрим его возможности для постэксплуатации
Для начала немного вводной информации
Что такое C2?
C2 (Command&Control) - это сервер, через который операторы могут управлять разными устройствами. Операторы могут посылать разные команды на эти устройства, создавать/удалять файлы и делать прочие действия. В целом, звучит довольно безобидно. Но обычно C2 используют специалисты по тестированию или злоумышленники - это более стабильная, удобная и незаметная альтернатива обычным реверс-шеллам. Чаще всего, когда говорят про C2, вспоминают Cobalt Strike. Но есть куда более близкая альтернатива которой на самом деле многие из нас уже пользовались - Metasploit (и meterpreter). В целом, от C2 обычно требуется следующее:
- Управление агентами - загрузка и выгрузка файлов, запуск процессов и прочие операции
- Удаление/регистрация новых агентов. Обычно агенты выводятся графом, списком или табличкой. Оператор может выбрать нужного и дальше работать с ним
- (Опционально) Чтобы с агентами могли работать сразу несколько операторов
- (Опционально) Ведение логов операции для отчёта
Чем выделяется sliver?
Sliver - это кросс-платформенный фреймворк для эмуляции кибер-угроз и красных команд с открытым исходным кодом, который может быть использован организациями любого размера для проведения тестирования безопасности. Импланты Sliver поддерживают C2 через Mutual TLS (mTLS), WireGuard, HTTP(S) и DNS и динамически компилируются с двоичными ключами асимметричного шифрования.
Сервер и клиент поддерживают MacOS, Windows и Linux. Импланты поддерживают MacOS, Windows и Linux.
Врочем, это вы могли прочитать из сами в описании sliver на гитхабе. Если раскладывать по фактам, то можно отметить следующее:
- Кросс-платформенные импланты - можно контроллировать как Windows, так и Linux (ещё в списке есть MacOS, но его я не проверял)
- Поддерживает много разных протоколов, некоторые из которых хорошо смешиваются с трафиком, например HTTP(s) и DNS
- Старается следовать OPSEC
- Бесплатный и Open Source
C2Matrix позволяет дополнить эту информацию:
- Sliver использовался в реальных атаках
- Поддержка нескольких операторов - можно использовать вместе с другими людьми
- Поддерживает расширение через BOF (Beacon Object File). Значит можно будет использовать расширения (BOF) для Cobalt Strike
- Implant, сервер и клиент написаны на Golang - то есть пейлоады будут большими по размеру
- Активно обновляется, версия v1.6.0 уже давно в бете, намечается много полезного функционала
- Нет GUI
Про OPSEC:
Когда вы играете за красную команду (или пентестите), то вашими "противниками" выступают СЗИ и SOC компании. Для того, чтобы защитить вашу инфраструктуру от них (а ещё от не-особо-этичных-хакеров) и не спалиться существует OPSEC. В контексте использования C2, OPSEC часто воспринимают как процедуры и рекомендации, которые помогут не насолить себе. Например, "не заливать mimikatz.exe на хост".
Кроме защиты от защитников, данные клиента нужно ещё защитить от реальных злоумышленников. Если ваш крякнутый кобальт сольёт весь "лут" или передаст управление имплантами третьим лицам и в результате этого произойдёт инцидент...
Установка
Скачать и поставить sliver можно одной строчкой (которую я скопировал прямо из доков):
curl https://sliver.sh/install|sudo bash
Но хотелось бы напомнить про безопасность (ИБ, всё же). Лучше вначале загрузить этот шелл скрипт в файл, а потом запустить руками. А перед запуском можно спокойно посмотреть, что он там такого делает:
curl https://sliver.sh/install > sliver-installer.sh vim sliver-installer.sh sh ./sliver-installer.sh
Инсталлятор сливера ставит одновременно и сервер и клиента. Возможно вам не нужен сервер - тогда можно просто скачать клиента из релизов на гитхабе: https://github.com/BishopFox/sliver/releases
Создаём listener и beacon
Запустим сервис sliver (который отвечает за серверную часть и позволит другим операторам подключаться) и запустим клиента sliver:
Для того чтобы отдавать команды агентам и получать от них результат выполнения, нужно запустить "listener". Listener слушает определённый порт и ожидает подключения по одному из доступных протоколов. Я буду использовать протокол mtls на порту по умолчанию для этого протокола (8888):
Теперь сгенерируем пейлоад. Мы будем использовать "beacon" - такой пейлоад менее заметен. Beacon будет стучаться на сервер с определённым интервалом - поэтому не ожидайте от него такой же отзывчивости как от reverse-shell:
Кроме "beacon" в sliver есть вид пейлоада "session". Такой пейлоад реагирует на команды без задержки, поэтому с ним удобнее работать. Но в результате генерируется большое количество сетевого трафика и нас будет легче обнаружить
Обычный "beacon" можно заставить создать нам сессию. Для этого используется командаinteractive
Закинем пейлоад на тестовый стенд и посмотрим результат:
Управление имплантом
Немного поиграем с базовыми возможностями импланта. Сперва нужно выбрать имплант с которым мы будем взаимодействовать.
Можно не писать полный uuid импланта, только начало. Но если у вас будет два uuid которые начинаются одинаково, sliver выберет первый из них и не предупредит - поэтому тут нужно быть внимательным
Посмотрим информацию о привилегиях процесса:
Сейчас beacon долго отвечает, поэтому я изменю его настройки и сделаю интервал отстука в 10 секунд, а jitter в 0:
Тут стоит заметить несколько особенностей скачивания:
1. Если указывать путь через обратный слеш, их надо писать два, для экранирования
2. Если файл указан через обратный слеш, то имя скачанного файла будет содержать полный путь
3. Можно скачивать используя пути как в Linux (кстати, cmd.exe и powershell.exe тоже поддерживают такую запись). В таком случае регистр папок и файлов не будет иметь значения.
Если нужно получить stdout от процесса, то нужно указать флаг-o. Кроме того, у процессов есть таймаут на выполнение, если запускать их с флагом-o. Если файл работает долго (LaZagne, seatbelt, winPEAS), лучше заранее выставить большой таймаут.
Результат выполнения предыдущих задач можно посмотреть ещё раз (работает только в beacon):
В целом, весь нужный функционал работает без проблем
Стейджеры
Пейлоады sliver достаточно объёмные - могут достигать 15Мб. Кроме того, загрузка пейлоада напрямую чревата дектектом от AV. В таких случаях лучше использовать стейджеры.
Стейджер это небольшой код, который загружает с сервера полный пейлоад и исполняет его в памяти. В результате - минимальный след не диске, а за счёт простоты стейджера, его намного легче обфусцировать (или вообще написать самому).
Стейджеры намного проще встраивать в различные типы файлов, например в ".doc" или ".hta".
Это не значит что полноценный пейлоад в .doc положить не получится. Но документ станет большого размера и его будет легче обнаружить.
Перед тем как использовать стейджер, надо сгенерировать пейлоад который он будет отдавать. Пейлоад должен быть в формате шелкода и мы должны сохранить его особым образом - в профиль. Делается это следующим образом:
Теперь запустим листенер стейджера. Он будет отдавать пейлоад стейджеру:
Для этого указываем протокол (тут используется другой формат, не как в генерации пейлоада) и профиль который listener будет выдавать.
Сгенерируем сам стейджер. Для примера, сделаем стейджер в PowerShell:
Теперь нужно добавить немного кода чтобы запустить этот шеллкод. Я воспользуюсь приведённым тут.
Создаём макрос Word
Теперь к более частой задаче. Создадим макрос для Word и положим его в ".doc" документ. В целом, действия аналогичны тому, что мы делали с PowerShell.
Многие загрузчики шеллкода (например из Cobalt Strike) требуют 32 битный шеллкод. Поэтому в этом примере я генерирую 32-битные.
Шаг с созданием профиля и запуском stage-listener я опущу - в целом то же самое, но для 32 битной архитектуры.
Возьмём часть макроса от Cobalt Strike (или msfvenom, они аналогичны) и склеим их вместе:
Armory
Sliver предоставляет различные возможности для расширения, и даже содержит свой "пакетный" менеджер. Через него можно поставить разные полезные инструменты, которые будут выполняться через пейлоад. Можно поставить сразу всё:
armory install all
Armory располагается на github, можно добавить свой пакет через issues:
https://github.com/sliverarmory/armory
Пост-эксплуатация
Рассмотрим возможности sliver для пост-эксплуатации:
Получение учётных данных
Сам по себе sliver предоставляет не так много возможностей получить учётные данные. Одна из них - получить дамп процесса lsass.exe через procdump:
1. Получаем список активных процессов и находим lsass.exe
2. Создаём дамп lsass.exe - для незаметности лучше сохранить сразу себе, а не на подконтрольное устройство
3. Используем pypykatz на своём хосте для анализа дампа
Перемещение между хостами
Из встроенных - только psexec, при этом нельзя указать список IP, нельзя указать креды. Используется текущая сессия. Однако в armory есть sharpmapexec - https://github.com/cube0x0/SharpMapExec
Tools of the Trade
Благодаря команде `execute-assembly`, sliver способен запускать очень много полезных инструментов. Alias'ы из armory так и работают - об этом прямо заявляется в документации.
Много полезных инструментов уже есть в armory и хорошо работают: rubeus, seatbelt. Часть (на данный момент) ещё не добавили: mimikatz, chisel.
И, конечно, можно просто загрузить что-то прямо на диск (что в большинстве не тренировочных сред будет съедено Windows Defender'ом):
Кстати, анализ в реальном времени Windows Defender'а можно выключить:execute -o powershell -c 'Set-MpPreference -DisableRealtimeMonitoring $true'
Хранилище лута
В sliver есть хранилище для лута - туда можно складывать пароли, API ключи, файлы. На мой взгляд, им не совсем удобно пользоваться - каждый пароль нужно запрашивать отдельно, нет варианта хэш. И самое главное - оно не пополняется автоматически, как это происходит в Cobalt Strike с hashdump/logonpasswords. Это неудобно когда работаешь с другими людьми, но в целом не слишком мешает.
Так происходит добавление элемента в лут:
Добавим немного автоматизации: reactions
В sliver есть встроенный механизм автоматизации рутинных действий. К сожалению, пока что он достаточно сыроват, но уже может немного упростить работу.
Он называется reactions. На данный момент триггеров для реакций не так много:
Добавляется реакция достаточно просто: указываем событие на которое хотим реагировать и список команд которые надо выполнить в этом случае:
У реакций на данный момент есть достаточно много огграничений:
- Нет гибкого языка (циклы, ветвления)
- Нет событий для обработки beacon
- Нет возможности подставлять параметры из переменных (логин и пароль из лута например)
Однако это не значит что sliver сложно автоматизировать. На самом деле, как раз наоборот, sliver отлично подходит для создания своих скриптов! Для этого нужно использовать кастомный клиент. Возможно об этом я напишу в следующий раз, а пока вот скрин чтобы полюбоваться:
Мультиплеер
В sliver удобно добавлять новых операторов, но для этого нужно включить multiplayer. Если вы устанавливали sliver через one-liner (как в документации), то он у вас по умолчанию включен.
Сгенерируем конфиг для оператора:
sudo /root/sliver-server operator --name test -s /tmp/test.cfg --lhost 127.0.0.1
Теперь оператор сможет его импортировать и использовать:
sliver import /tmp/test.cfg
Однако sliver очень просто обнаруживается - по умолчанию висит на порту 31337. Используется SSL сертификат с достаточно узнаваемыми Issuer, Subject:
Такое легко находится даже через Shodan, так что сервер может легко попасть в TI feed или блэклист:
Прячем сервер
Вариант 1 - SSH тунель
Простой и надёжный вариант - закрыть порт 31337 и дать возможность операторам подключаться через SSH тунель. Сервер с SSH вызывает куда меньше подозрений чем с открытым 31337 портом
Закрываем доступ к 31337 порту извне:
sudo iptables -I INPUT -p tcp --dport 31337 -j DROP sudo iptables -I INPUT -s 127.0.0.1 -p tcp --dport 31337 -j ACCEPT
Не забывайте что iptables сбросится при перезагрузке. Правила нужно сохранить или вводить заново каждый раз
Либо перевешиваем его на 127.0.0.1 через конфиг сервера. Если вы устанавливали sliver через one-liner, то этот конфиг будет в /root/.sliver/configs/server.json:
Теперь остаётся запустить ssh сервер и создать пользователя для туннеля:
systemctl start ssh useradd sshtunnel -m -d /home/sshtunnel -s /bin/true
Теперь операторы могут прокинуть туннель:
ssh -L 31337:127.0.0.1:31337 sshtunnel@ip
Однако, в этом случае операторам нужно будет выставить lhost в 127.0.0.1 (в конфиге или при генерации):
Вариант 2 - Меняем порт и сертификат
Другой вариант - изменить порт sliver и создать/сгенерировать более незаметный сертификат. Такой вариант хорош тем что операторам не придётся подключаться через SSH тунель.
Сертификаты лежат в /root/.sliver/crt:
Лучше сразу заменить сразу все сертификаты. Ключ должен использовать Elliptic Curves (EC) - sliver умеет читать только их.
Генерить такой ключ и сертификат можно так:
openssl ecparam -name prime256v1 -genkey -noout -out key.pem openssl req -new -x509 -key key.pem -out cert.pem -days 365 -nodes
Перезагружаем сервис sliver (systemctl restart sliver) и смотрим на результат:
Issuer "operators" пропал, но избавиться от строчки "multiplayer" сложнее. Для этого нужно пропатчить sliver, вот это место: https://github.com/BishopFox/sliver/blob/040863b75721d9a6c21d24bd0926d1d85c91ab7d/server/transport/mtls.go#L54
Для сборки sliver v1.5.42 нужен go v1.20.7, поставим его:
go install golang.org/dl/go1.20.7@latest go1.20.7 download
git clone https://github.com/BishopFox/sliver/ cd sliver git checkout v1.5.42 sed -i 's/"multiplayer"/"Test Blog"/g' server/transport/mtls.go sed -i 's/= go$/= go1.20.7/g' Makefile ./go-assets.sh make linux
Кстати, довольно многие меняют порт, но забывают убрать SSL Subject "multiplayer" :)
Ныряем в исходники
Частая задача - обойти обнаружение пейлоада. Можно поиграть со стейджером и сделать его более незаметным - это надёжный вариант, про который достаточно много написано. Мы пойдём другим путём и изменим код самого агента :)
За генерацию агента отвечает sliver/server/generate, а точнее - renderSliverGoCode()
Код самого агента лежит в implant. В коде используются шаблоны Go (tmpl), вида {{.SomeVariable}}
В целом кода довольно много, в нашей обзорной статье просто изменим поведение функции регистрации - добавим домен к хостнейму (так будет удобнее искать нужный имплант), а также задержку в 10 секунд между получением хостнейма и пользователя.
Я буду изменять файл sliver/implant/sliver/sliver.go
Зачем мы добавляем эту задержку? В целом, от EDR или антивируса такой трюк сейчас не спасёт, но при желании тут можно добавить различные проверки и вставки, проверить среду исполнения. Это так же может быть полезно чтобы ограничить скоуп - например запретить пейлоаду исполнятся на компьютерах которые не входят в определённый домен.
После перекомпилирования и запуска пейлоада:
Итоги
Sliver предоставляет стабильный базовый функционал и хорошие возможности для расширения и автоматизации. Для некоторых будет минусом отсутвие GUI, но лично меня больше расстроило отсутствие нормальных логов и возможностей для написания отчётов
Спасибо за внимание к заметке, буду рад вашим дополнениям :)