![](https://habrastorage.org/getpro/habr/upload_files/ae5/b9a/295/ae5b9a295fabcd069e0f522c88a6443f.jpg)
На кибербитве Standoff 11 в виртуальном государстве F впервые представили атомную промышленность. Задачей атакующих (red team) было реализовать недопустимые события на виртуальной АЭС, а защитников (blue team) — расследовать атаку с помощью продуктов Positive Technologies. Как все прошло? Заглядываем в ретроспективу событий, сохранившихся в SOC, за который на Standoff отвечал наш соорганизатор Innostage. Атаку шаг за шагом распутывает Данил Лобачев, специалист группы обнаружения атак на конечных устройствах экспертного центра безопасности Positive Technologies (PT Expert Security Center).
В атомной промышленности мы выделили основные отраслевые элементы и этапы — от добычи урановой руды до захоронения отходов. По сценарию кибербитвы для атак доступны АЭС (включая электроподстанцию) и завод по обогащению урана.
![](https://habrastorage.org/getpro/habr/upload_files/fb9/cb9/58b/fb9cb958b60092ff70492db7fb365131.jpg)
![Атомная промышленность на макете Standoff 11 Атомная промышленность на макете Standoff 11](https://habrastorage.org/getpro/habr/upload_files/599/f2a/c3c/599f2ac3c27027b17cd32b914a690920.jpg)
Во второй день противостояния на виртуальном заводе перестали работать несколько центрифуг. Атакующим удалось проникнуть во внутреннюю сеть предприятия и отправить контроллеру соответствующую команду. В реальной жизни изменение скорости вращения центрифуг может привести к остановке обогащения урана и откатить буквально все до ноля. Это просто недопустимо для бизнеса. К тому же при неправильном изменении частоты вращения центрифуга может разрушиться. На восстановление обогащения ушло бы несколько месяцев.
Кстати, в реальном мире такое уже случалось: вирус Stuxnet отбросил ядерную программу Ирана на два года назад.
Реализация недопустимого события
Центрифуга для обогащения урана управляется программируемым логическим контроллером (ПЛК) SIMATIC S7. Семнадцатого мая «синие» зафиксировали остановку контроллера с помощью системы глубокого анализа технологического трафика — PT Industrial Security Incident Manager (PT ISIM). Команда остановки была отправлена с узла, имеющего IP-адрес 10.156.64.197; запомним его для расследования.
![Инциденты, обнаруженные PT ISIM и отфильтрованные по адресу назначения Инциденты, обнаруженные PT ISIM и отфильтрованные по адресу назначения](https://habrastorage.org/getpro/habr/upload_files/0bc/8b2/392/0bc8b23925a2a5b8d43f562106256958.png)
Так как взаимодействие с ПЛК происходит по 102-му порту, можно обратиться к системе поведенческого анализа сетевого трафика — PT Network Attack Discovery (PT NAD) — и посмотреть, зафиксировала ли она такую активность. Для этого необходимо отфильтровать трафик по времени и известным параметрам: по IP-адресу источника и назначения, а также по порту источника.
![Сессии в интерфейсе PT NAD, отфильтрованные по времени, адресам источника и назначения Сессии в интерфейсе PT NAD, отфильтрованные по времени, адресам источника и назначения](https://habrastorage.org/getpro/habr/upload_files/6af/c15/779/6afc15779dc75e74b9e354e53b5a4291.png)
Видим несколько сессий, подходящих под временной отрезок: вероятно, команда красных несколько раз пыталась совершить сие злодеяние. Также в колонке «Домен отправителя» отображается имя узла, с которого проведена атака; эту информацию запоминаем.
PT NAD позволяет скачать дамп сессии для более глубокого анализа. Сделаем это.
![Отправка команды для остановки ПЛК, обнаруженная при анализе дампа трафика с помощью Wireshark Отправка команды для остановки ПЛК, обнаруженная при анализе дампа трафика с помощью Wireshark](https://habrastorage.org/getpro/habr/upload_files/b41/9b5/8ec/b419b58ec014d4bbf3dd7387a29e0040.png)
В скачанном дампе видно, что атакующий посылает пакет с кодом 0x29: это означает остановку контроллера.
Итак, нам известны доменное имя узла, с которого совершалась атака, порт и время инцидента. Негусто. Обратимся к MaxPatrol SIEM с имеющимися вводными. Отсортируем события фильтром event_src.host = "bpreston.nuclear.stf" and src.port = "65492" and dst.port = "102" and dst.ip = "10.156.62.3". Теперь мы узнаем, что команда остановки отправлена пользователем ladmin с помощью процесса rec.exe. Но что это за процесс и как он попал на узел? Разберемся.
![Открытие соединения с dst.port = 102, инициированное процессом rec.exe (событие в интерфейсе MaxPatrol SIEM) Открытие соединения с dst.port = 102, инициированное процессом rec.exe (событие в интерфейсе MaxPatrol SIEM)](https://habrastorage.org/getpro/habr/upload_files/302/620/02b/30262002b7303ef95b413b390b73cf1c.png)
Можно посмотреть, как был запущен процесс, — отфильтруем события запросом event_src.host = "bpreston.nuclear.stf" and object.process.name = "rec.exe" and msgid in [1, 4688]. Оказывается, что использовался агент Zabbix (довольно подозрительно o_O).
![Запуск процесса rec.exe с помощью zabbix_agent.exe Запуск процесса rec.exe с помощью zabbix_agent.exe](https://habrastorage.org/getpro/habr/upload_files/618/84e/1ea/61884e1ea6ae224bd973f2ecafd3b351.png)
Пробуем поискать запуск zabbix_agentd.exe и находим интересное описание в поле, предназначенном для хранения метаинформации. Делаем вывод, что этот процесс не является легитимным агентом Zabbix, а был подложен в папку вместо настоящего.
![Подозрительное описание процесса в событии запуска zabbix_agentd.exe Подозрительное описание процесса в событии запуска zabbix_agentd.exe](https://habrastorage.org/getpro/habr/upload_files/8e9/088/88b/8e908888bd5c6db47be8e92c32b9f415.png)
К примеру, метаинформация легитимного агента Zabbix представлена ниже.
![Запуск легитимного агента Zabbix Запуск легитимного агента Zabbix](https://habrastorage.org/getpro/habr/upload_files/167/a20/7d6/167a207d6d75c2a66cad630e4957d1bb.png)
Посмотрим, какой вердикт вынесет сетевая песочница PT Sandbox после проверки zabbix_agentd.exe.
![Поведенческий анализ подмененного zabbix_agentd.exe с помощью сетевой песочницы PT Sandbox Поведенческий анализ подмененного zabbix_agentd.exe с помощью сетевой песочницы PT Sandbox](https://habrastorage.org/getpro/habr/upload_files/3c6/82a/f82/3c682af82bbebeed352b32263915e9ce.png)
Но что еще интересного делал подмененный агент Zabbix? Применим запрос event_src.host = "bpreston.nuclear.stf" AND object.process.chain contains "zabbix_agentd.exe" для того, чтобы увидеть, в каких цепочках запуска процессов находится название подставного агента. И тут же натыкаемся на события с созданием пользователя ladmin с помощью исполняемого файла net.exe.
![Создание пользователя ladmin с помощью процесса net.exe. Событие содержит обогащенное поле object.process.chain Создание пользователя ladmin с помощью процесса net.exe. Событие содержит обогащенное поле object.process.chain](https://habrastorage.org/getpro/habr/upload_files/37d/8c6/3c2/37d8c63c2664133017a8f846c7013508.png)
Кстати, смотреть цепочку запущенных процессов удобно с помощью плагина SiemMonkey. Наш коллега Константин Грищенко в рамках участия в открытом сообществе Security Experts Community выложил в открытый доступ свои наработки по автоматизации рутинных задач специалистов SOC и оформил их в виде плагина для браузера Google Chrome.
![Цепочка запущенных процессов, построенная с помощью браузерного плагина для MaxPatrol SIEM — SiemMonkey Цепочка запущенных процессов, построенная с помощью браузерного плагина для MaxPatrol SIEM — SiemMonkey](https://habrastorage.org/getpro/habr/upload_files/f2c/213/c30/f2c213c308544ebb2b9a08e694bf008f.png)
Эта активность также попала в цепочку нескольких корреляционных правил.
![](https://habrastorage.org/getpro/habr/upload_files/36c/4f3/fb9/36c4f3fb9497c6c2d6793d5ab5c4d6f0.png)
![](https://habrastorage.org/getpro/habr/upload_files/abc/ab3/3b3/abcab33b3bca7bcf4f7f65518233c8fb.png)
![Срабатывания корреляционных правил на активность процесса net.exe Срабатывания корреляционных правил на активность процесса net.exe](https://habrastorage.org/getpro/habr/upload_files/b9a/0ea/8e3/b9a0ea8e3d016737b6613196a227d795.png)
Незадолго до этих событий с процессом zabbix_agentd.exe взаимодействовал пользователь r_humphrey. Предположим, что до создания учетной записи ladmin атакующие использовали r_humphrey.
![Запуск легитимного zabbix_agent.exe пользователем r_humphrey Запуск легитимного zabbix_agent.exe пользователем r_humphrey](https://habrastorage.org/getpro/habr/upload_files/a2c/8af/14e/a2c8af14e92ea4419d9864a426e20c4f.png)
Как пользователь попал на узел bpreston.nuclear.stf? Отсортируем события по этой сессии и зададим в запросе только события входа в систему: event_src.host = "bpreston.nuclear.stf" and (subject.account.session_id = "11812950" or object.account.session_id = "11812950") and msgid = "4624".
![Вход пользователя r_humphrey в систему на узле bpreston.nuclear.stf Вход пользователя r_humphrey в систему на узле bpreston.nuclear.stf](https://habrastorage.org/getpro/habr/upload_files/a82/471/2ec/a824712ec0c13197a0f8199a680c9f35.png)
Как оказалось, пользователь пришел с сервера RDG. Посмотрим логи. Так как мы знаем время подключения, можно поискать на сервере события установки соединения по порту RDP с адресом назначения bpreston.nuclear.stf. Это необходимо для того, чтобы узнать номер сессии, в которую совершались действия.
![Срабатывание правила корреляции на туннелирование трафика с помощью процесса rec.exe на узле rdg.nuclear.stf Срабатывание правила корреляции на туннелирование трафика с помощью процесса rec.exe на узле rdg.nuclear.stf](https://habrastorage.org/getpro/habr/upload_files/c1a/5a2/602/c1a5a260281ca635bff9727cb4f2b2c0.png)
Получаем номер сессии, а также замечаем срабатывание правила корреляции на активность файла rec.exe, который мы видели ранее на узле bpreston. Запуск бинаря rec.exe осуществлялся с помощью файла telemetry.exe.
![Запуск rec.exe процессом telemetry.exe на узле rdg.nuclear.stf Запуск rec.exe процессом telemetry.exe на узле rdg.nuclear.stf](https://habrastorage.org/getpro/habr/upload_files/bed/2f3/b76/bed2f3b768b393bcba5b42e23fad647f.png)
Изучаем данные о запуске telemetry.exe и видим уже знакомую ситуацию: у файла говорящая метаинформация.
![Старт sliver-stager.exe, замаскированного под telemetry.exe Старт sliver-stager.exe, замаскированного под telemetry.exe](https://habrastorage.org/getpro/habr/upload_files/901/4b1/564/9014b15641a525978db597ad9d90a256.png)
Проверяем хеш файла в базе VirusTotal, чтобы убедиться наверняка.
![Анализ хеша sliver-stager.exe в базе VirusTotal Анализ хеша sliver-stager.exe в базе VirusTotal](https://habrastorage.org/getpro/habr/upload_files/a93/731/783/a937317833dfec33cc4dca9a80d7b74c.png)
Осталось узнать, как атакующие получили доступ к RDG-серверу. Изучаем события входа в рамках этой сессии. Под учеткой r_humphrey «красные» пришли с устройства fhays.
![Вход на rdg.nuclear.stf с узла fhays.nuclear.stf пользователем r_humphrey Вход на rdg.nuclear.stf с узла fhays.nuclear.stf пользователем r_humphrey](https://habrastorage.org/getpro/habr/upload_files/334/417/dce/334417dce25c14b47cd6adcb0885443b.png)
Посмотрев события с fhays.nuclear.stf, в который раз замечаем соединение через файл rec.exe. Но здесь мы видим, что запустил его пользователь f_hays, а не r_humphrey.
![Срабатывание на сетевое обращение, инициированное файлом rec.exe по протоколу RDP с fhays.nuclear.stf на RDG-сервер Срабатывание на сетевое обращение, инициированное файлом rec.exe по протоколу RDP с fhays.nuclear.stf на RDG-сервер](https://habrastorage.org/getpro/habr/upload_files/dd7/b9c/16a/dd7b9c16a7371c6e847664c7bd35eca8.png)
Смотрим сработавшие правила корреляции, которые укладываются в наши временные рамки. Находим использование mimikatz.exe с параметрами sekurlsa::logonpasswords full (видимо, отсюда «красные» и получили креды r_humphrey).
![Срабатывание правила корреляции на активность утилиты Mimikatz Срабатывание правила корреляции на активность утилиты Mimikatz](https://habrastorage.org/getpro/habr/upload_files/46d/db1/fbf/46ddb1fbf0d4ed176801973059fbfa4d.png)
Сгруппируем события по названиям сработавших корреляционных правил, чтобы увидеть, чего можно ждать от этой сессии.
![Сгруппированные сработавшие правила корреляции в рамках одной сессии Сгруппированные сработавшие правила корреляции в рамках одной сессии](https://habrastorage.org/getpro/habr/upload_files/6fb/852/e47/6fb852e47e899f6720d66378cebc31ee.png)
Тут целый букет правил. Самыми интересными, на первый взгляд, кажутся срабатывания на Sliver, Cobalt Strike, SharpHound. И куда же без документов с макросами! Попробуем узнать, откуда на устройстве появился Sliver (aka telemetry.exe).
![Срабатывание правила корреляции на активность Sliver Срабатывание правила корреляции на активность Sliver](https://habrastorage.org/getpro/habr/upload_files/2d5/9f1/20e/2d59f120e0e92eaa56d24f847a463592.png)
Применим запрос для поиска события о создании файла telemetry.exe: (event_src.host = "fhays.nuclear.stf") and body contains "telemetry.exe" and msgid = "11". Цепочка продолжается, так как мы узнали, что файл создан с помощью a01.exe.
![Создание файла Sliver (telemetry.exe) с помощью процесса a01.exe Создание файла Sliver (telemetry.exe) с помощью процесса a01.exe](https://habrastorage.org/getpro/habr/upload_files/657/d3b/5f0/657d3b5f05b09ddfef17ade62d41ded6.png)
Узнаем, как был создан a01.exe. Видим легитимный netsh.exe, который по умолчанию не может создавать файлы: значит, он не тот, каким кажется.
![Создание процесса a01.exe с помощью netsh.exe Создание процесса a01.exe с помощью netsh.exe](https://habrastorage.org/getpro/habr/upload_files/d68/684/354/d68684354c2fb3e23070c1e36b0d39ef.png)
Посмотрим сработавшие корреляционные правила, в которых subject.process.name = "netsh.exe". В процесс с помощью pp3.exe были загружены библиотеки PowerShell.
![Срабатывание правила корреляции на загрузку модулей PowerShell в легитимный процесс netsh.exe Срабатывание правила корреляции на загрузку модулей PowerShell в легитимный процесс netsh.exe](https://habrastorage.org/getpro/habr/upload_files/a26/c78/5a7/a26c785a73634c7bf22e2c3675eff58c.png)
О такой активности говорят события с msgid = "8".
![Загрузка библиотек в netsh.exe Загрузка библиотек в netsh.exe](https://habrastorage.org/getpro/habr/upload_files/9c5/dbd/2b9/9c5dbd2b96fd66b9151abd5c45006456.png)
Откуда взялся pp3.exe? Для этого вновь воспользуемся SiemMonkey. Замечаем, что процесс создан с помощью закодированной PowerShell (pid 2924) команды, которая запущена документом FBI_Request.doc.
![Цепочка запуска процессов, построенная в интерфейсе плагина SiemMonkey Цепочка запуска процессов, построенная в интерфейсе плагина SiemMonkey](https://habrastorage.org/getpro/habr/upload_files/2a3/89f/a62/2a389fa62d086ece17454f2a577cae37.png)
На активность процесса PowerShell сработали сразу несколько правил.
![Корреляционные правила, сработавшие на запуск PowerShell с закодированной командой Корреляционные правила, сработавшие на запуск PowerShell с закодированной командой](https://habrastorage.org/getpro/habr/upload_files/04e/248/493/04e248493afad0f2cd8353e2dbce203e.png)
В одном из срабатываний видим, что атакующие пытались подделать URL, с которого была загружена полезная нагрузка. Хорошая попытка, но название компании Innostage пишется с двумя n.
![Загрузка payload с замаскированного под легитимный сервера Загрузка payload с замаскированного под легитимный сервера](https://habrastorage.org/getpro/habr/upload_files/52f/705/232/52f705232c759815e6782b90acff28b9.png)
Обратимся к PT NAD для поиска информации об этой сессии: файл загрузили с помощью PoshRat, который был внутри макроса письма.
![Срабатывание правила PT NAD на загрузку файла Срабатывание правила PT NAD на загрузку файла](https://habrastorage.org/getpro/habr/upload_files/63f/3de/766/63f3de766a2a40bbeebb241f3ebba193.png)
![Срабатывание правила корреляции на запуск вредоносного документа fbi_request, с которого началась атака Срабатывание правила корреляции на запуск вредоносного документа fbi_request, с которого началась атака](https://habrastorage.org/getpro/habr/upload_files/6c9/ba3/536/6c9ba35366df8e9d60e8f471ab29c885.png)
Проверяем документ в PT Sandbox. Видим, что письмо рассылалось на множество адресов, в этот список попал пользователь f_hays.
![Результаты анализа зараженного документа в интерфейсе PT Sandbox Результаты анализа зараженного документа в интерфейсе PT Sandbox](https://habrastorage.org/getpro/habr/upload_files/f84/57a/c4d/f8457ac4d80affc1277d694201e69c0a.png)
![Цепочка атаки на Standoff 11 Цепочка атаки на Standoff 11](https://habrastorage.org/getpro/habr/upload_files/6f9/83e/c3e/6f983ec3efe85c402ccb849891866512.png)
Цепочка событий, произошедших на кибербитве Standoff, наглядно демонстрирует, что даже самые защищенные системы и критическая инфраструктура подвержены уязвимостям. Атака началась с обычного фишингового письма. После того как пользователь открыл зараженный документ, «красным» удалось переместиться через несколько устройств. В итоге они получили доступ к узлу оператора ПЛК, с которого остановили центрифугу для обогащения урана.
Как защититься? Выстроить регулярное обучение сотрудников как минимум азам кибербезопасности, а также проводить регулярные киберучения. Все это делает атаку невыгодной для злоумышленников и существенно повышает шансы компании на успешное противостояние киберугрозам.
Комментарии (2)
lumen_xp
04.09.2023 11:02+3Не мог пройти мимо. На промышленных АЭС мощностью в ГВт нет центрифуг для обогащения урана. На фабриках в РФ и в первом контуре АЭС как правило иностранное оборудование в системах автоматизации не применяется. Ну и никто не отменял аппаратные системы защит, реле безопасности и SIL3. В общем, проблема чаще надуманная и распиаренная для зарабатывания денег. Реальные масштабные инциденты происходят отнюдь не по вине плохой работы ИБ.
AndreyDmitriev
Эм, хотелось бы заметить, что в грамотно спроектированной системе банальный останов рядового ПЛК в общем случае не должен приводить к необратимой поломке оборудования, так что заголовок чуть громче чем надо. Так можно и промышленную хлеборезку остановить. Stuxnet был устроен куда как хитрее, я лет десять назад внимательно изучал все документы, до которых смог дотянуться, и пришёл к выводу, что там без инсайда не обошлось и у хакеров, которые реализовали MITM атаку, просто была в распоряжении центрифуга с ПЛК, и они точно знали "куда бить" (насколько я помню, там было несколько версий вируса, одна из которых закрывала все выпускные клапаны так, что в центрифуге давление возрастало до недопустимого с пятикратным превышением, а другая раскручивала её до недопустимой скорости). Соответственно надо точно знать, какой функциональный блок и какие переменные ПЛК за что отвечают. Ходили слухи, что вроде как у Каддафи была эта игрушка в сборе, ну и в ходе той катавасии, ну вы поняли... В данном же примере был просто выполнен жёсткий останов ПЛК. Современные ПЛК тесно интегрированы с цепями безопасности и в общем случае хороший системный инженер должен предусмотреть сценарий, когда ПЛК встанет колом и внешняя по отношению к нему автоматика должна мягко разрулить эту ситуацию. Это безотносительно центрифуг, скажем если ПЛК управляет механизмами в опасной зоне, и там могут находиться люди, то останов основного процессора ПЛК (одноплатника по большому счёту, не знаю что там у Сименса, а у B&R, скажем, обычный Intel Atom камушек на 300-400 МГц стоит) не должен приводить к фатальным последствиям, поэтому там много чего продублировано. Просто надо дотошно рассмотреть все возможные точки отказа, на одну из которых и надавили в данном случае (безотносительно того, что фишинговое письмо не должно пробивать до низкоуровнего протокола). В нашей компании служба безопасности раз в квартал рассылает фишинговые письма (очень аутентичные) и смотрят, сколько их накликают.
А так - спасибо, я вот честно говоря не знал, что Сименсовский ПЛК можно просто остановить, отправив ему функциональный код 0х29 в S7COMM заголовке. Доки реверс инжиниринга говорят мне, что там также можно через 0х04/0х05 читать и писать переменные в памяти - вот это уже значительно интереснее.