Win32/Industroyer – сложная вредоносная программа, предназначенная для нарушения рабочих процессов в промышленных системах управления (ICS), в частности, на электрических подстанциях.
Создателей Win32/Industroyer отличает высокая квалификация и глубокое понимание промышленных систем управления и протоколов связи в электроэнергетике. Маловероятно, чтобы кто-либо мог написать и протестировать подобное ПО без доступа к специализированному оборудованию, которое используется в целевой среде.
![](https://habrastorage.org/r/w1560/web/de2/0db/39c/de20db39cea24c0e803a07e4dca18785.png)
Авторы вредоносной программы реализовали поддержку четырех промышленных протоколов, описанных в следующих стандартах:
В дополнение к этому авторы Industroyer разработали инструмент для выполнения DoS-атак (denial-of-service – отказ в обслуживании), нацеленных на определенные устройства релейной защиты, в частности, линейку Siemens SIPROTEC.
Возможности Win32/Industroyer впечатляют. Если сравнить его с инструментами, которые использовались в атаках на украинскую энергосистему в 2015 году и привели к массовым отключениям электроэнергии 23 декабря 2015 года (BlackEnergy, KillDisk и другие компоненты, включая легитимное ПО для удаленного доступа), можно утверждать, что за Industroyer стоит кибергруппа более высокого уровня. Авторы создали вредоносную программу, которая позволяет напрямую управлять выключателями и прерывателями цепи в сети электрических подстанций. По некоторым признакам мы предполагаем, что Industroyer может быть связан со сбоем энергоснабжения в Киеве в декабре 2016 года. Тем не менее, на момент написания отчета это не было подтверждено, и расследование продолжается. Вектор заражения пока не установлен.
Industroyer состоит из нескольких модулей, описание и анализ которых представлены в следующих разделах отчета. Прежде чем перейти к деталям, предлагаем упрощенную схему, которая показывает связь между компонентами вредоносной программы.
![](https://habrastorage.org/r/w1560/web/fc2/a5b/e1c/fc2a5be1c362441ba833accc6bacd6fd.png)
Рисунок 1. Упрощенная схема компонентов Win32/Industroyer.
Некоторые компоненты (включая стиратель данных) аналогичны по своей концепции инструментам, использовавшимся в атаках BlackEnergy на украинские энергокомпании в 2015 году. Тем не менее, мы не видим связи между прошлыми атаками и кодом нового вредоносного ПО.
Главный компонент Industroyer – основной бэкдор – используется атакующими для управления остальными компонентами программы.
Как и положено бэкдору, этот компонент довольно прост. Он подключается к удаленному C&C-серверу через HTTPS и получает команды от атакующих. Все изученные образцы жестко запрограммированы на использование одного и того же адреса прокси, расположенного в локальной сети. Таким образом, бэкдор явно предназначен для работы в определенной организации. Также стоит упомянуть, что большинство C&C-серверов бэкдора используют Tor.
Возможно, наиболее интересная особенность бэкдора в том, что атакующие могут задать конкретный час, когда малварь будет активна. Например, можно модифицировать бэкдор таким образом, чтобы он обращался к C&C-серверу в нерабочее время. Это усложняет обнаружение, основанное только на проверке сетевого трафика. Тем не менее, все образцы, изученные до настоящего времени, работали круглосуточно.
![](https://habrastorage.org/r/w1560/web/862/1cd/fa5/8621cdfa5ac2424583b14ca5383e9a1c.png)
Рисунок 2. Декомпилированный код основного бэкдора с возможностью задать время.
После подключения к удаленному C&C-серверу основной бэкдор отправляет в POST-запрос следующие данные:
Жестко запрограммированный ID используется атакующими в качестве идентификатора зараженной машины. Среди всех изученных образцов мы обнаружили следующие значения ID:
Основной бэкдор поддерживает следующие команды:
![](https://habrastorage.org/r/w1560/web/08f/6b4/35d/08f6b435d85b48cb8a956e3d0f2336ae.png)
Получив права администратора, атакующие могут обновить установленный бэкдор до более привилегированной версии, которая выполняется как Windows service program. Для этого им нужно выбрать существующий некритический процесс Windows и заменить параметр реестра
Функциональность основного бэкдора, который работает как служба Windows, идентична описанной. Но есть два небольших различия: название версии бэкдора (1.1s вместо 1.1e) и обфускация кода. Код этой версии бэкдора смешан с ненужными командами ассемблера.
![](https://habrastorage.org/r/w1560/web/cbd/c8a/fcf/cbdc8afcf348495d82ff210ac7651d38.png)
Рисунок 3. Обфусцированный ассемблерный код основного бэкдора, работающего как служба Windows.
Дополнительный бэкдор обеспечивает альтернативный механизм устойчивости, что позволяет атакующим восстановить доступ к целевой сети, если основной бэкдор будет обнаружен и/или деактивирован.
Бэкдор представляет собой троянизированную версию приложения Windows Notepad. Это полнофункциональное приложение, но вирусописатели добавили в него вредоносный код, который выполняется при каждом запуске. Далее, получив права администратора, атакующие могут вручную заменить вредоносный Notepad легитимным.
Добавленный вредоносный код сильно обфусцирован. После расшифровки он подключается к удаленному C&C-серверу (отличается от C&C основного бэкдора) и загружает полезную нагрузку. Она имеет формат шелл-кода, который загружается непосредственно в память и выполняется. Кроме того, добавленный код расшифровывает исходный код Windows Notepad, хранящийся в конце файла, и затем передает ему выполнение – так приложение работает должным образом.
![](https://habrastorage.org/r/w1560/web/d7e/308/504/d7e30850437b46c48f42db0db53124c5.png)
Рисунок 4. Сравнение оригинального бинарного кода Notepad (слева) и бэкдора.
Компонент представляет собой отдельный исполняемый файл, предназначенный для запуска полезной нагрузки и компонента стирателя данных.
Компонент запуска содержит определенное время и дату. В изученных образцах было задано две даты: 17 и 20 декабря 2016 года. Как только одна из двух дат наступает, компонент создает два потока. Первый пытается загрузить вредоносную DLL, второй ждет один или два часа (в зависимости от версии компонента), а затем пытается загрузить компонент стирателя данных. Оба потока имеют высший приоритет
Имя вредоносной DLL добавляется атакующими через параметр командной строки, предоставленный в одной из команд основного бэкдора («Выполнить shell-команду»). Имя файла стирателя данных – всегда
Каждый аргумент командной строки обозначает следующее:
•
•
•
•
Полезная нагрузка и компонент стирателя данных – стандартные файлы DLL Windows. Чтобы быть загруженными компонентом запуска, они должны экспортировать функцию
![](https://habrastorage.org/r/w1560/web/3b3/96c/99f/3b396c99f2ae4ba3a1d6659a5cf8b2cd.png)
Рисунок 5. Пример вредоносной DLL с внутренним именем
Вредоносная DLL с именем файла
Компонент 101 частично реализует протокол, описанный в стандарте IEC 101. Он способен связываться с RTU и любым другим устройством, поддерживающим этот протокол.
После выполнения компонент 101 анализирует конфигурацию, хранящуюся в INI-файле. Конфигурация может содержать несколько записей: имя процесса, имена устройств Windows (обычно COM-порты), количество диапазонов и значения диапазонов для адресов информационных объектов (Information Object Address – IOA). IOA – номер, который идентифицирует конкретный элемент данных в устройстве. На рис. 6 показан файл конфигурации компонента 101 с двумя определенными диапазонами IOA: 10-15 и 20-25.
![](https://habrastorage.org/r/w1560/web/734/bbf/ac9/734bbfac96e5475aa9df58a689c5a7dc.png)
Рисунок 6. Пример конфигурации компонента 101.
Имя процесса, указанного в конфигурации, принадлежит приложению, которое, как предполагают атакующие, работает в системе жертвы. Это должно быть приложение, которое машина использует для коммуникаций с RTU через последовательное соединение. Компонент 101 пытается завершить этот процесс и обращается к указанному устройству, используя функции Windows API
Компонент выполняет итерацию по всем диапазонам IOA. Для каждого IOA он создает пакеты команд выбора и исполнения с однопозиционной (
![](https://habrastorage.org/r/w1560/web/caa/4a3/ae1/caa4a3ae16924b2c9479a1f2bd76655a.png)
Рисунок 7. Пример разобранного пакета полезной нагрузки в Kaitai Struct WebIDE.
DLL с именем файла
![](https://habrastorage.org/r/w1560/web/abe/26e/ea4/abe26eea4cc64ef59b44936fdfaa8271.png)
Рис. 8. Образец файла DLL конфигурации компонента 104.
После исполнения DLL компонента 104 произведет попытку прочитать файл конфигурации. Путь к файлу конфигурации берется из компонента загрузчика.
Конфигурация содержит раздел
Наш анализ этого компонента показывает следующие возможные параметры конфигурации:
![](https://habrastorage.org/r/w1560/web/300/e8c/cd8/300e8ccd888447d78a02658cf68913df.png)
После прочтения файла конфигурации компонент 104 создает процесс для каждого фрагмента
Основная идея использования компонента 104 относительно проста. Он связывается с указанным IP и начинает передачу пакетов с адресом ASDU, прописанным в его конфигурации. Цель этого обмена данных — связаться с IOA однопозиционного типа команд. В файле конфигурации атакующий может определить свойство
Первый такой режим
![](https://habrastorage.org/r/w1560/web/e7d/ce5/63f/e7dce563f4894f82a0d518b908cd697d.png)
Рис. 9. Пример декодированного в Wireshark пакета компонента 104.
Как только все возможные IOA из определенного диапазона опрошены, компонент 104 переходит ко второму этапу режима
На рис. 10 показан файл лога, который выдал компонент 104 во время нашего анализа. Из него мы видим, что компонент опросил IOA от 10 до 15 и, когда IOA однопозиционного типа были обнаружены, начал их использование в цикле. В конфигурации опция
![](https://habrastorage.org/r/w1560/web/e08/2f4/4d0/e082f44d003f4ce5a993208432d2e164.png)
Рис. 10. Пример логов компонента 104.
Второй режим
Третий режим
Кроме способности писать в лог, компонент 104 может выводить отладочную информацию в консоль, как это показано на рис. 11.
![](https://habrastorage.org/r/w1560/web/982/22a/bce/98222abce31a41bfa47f503346642f69.png)
Рис. 11. Вывод на консоль компонента 104.
В отличие от компонентов 101 и 104, существует в виде отдельного вредоносного инструмента, состоящего из исполняемого файла под названием
После исполнения DLL компонента 61850 пробует прочесть файл конфигурации, чей путь предоставляется компонентом запуска. Отдельная версия по умолчанию берет конфигурацию из
Если файл конфигурации не находится, компонент 61850 нумерует все подключенные адаптеры сети для определения их масок подсети TCP/IP. Затем компонент нумерует все возможные IP-адреса для каждой из масок подсети и пробует подключиться к порту 102 каждого адреса. Таким образом, компонент умеет автоматически обнаруживать подходящие устройства в сети.
В другом случае, если файл конфигурации найден и содержит целевые адреса IP, компонент подключается к порту 102 по этим адресам и найденным автоматически.
Как только этот компонент подключается к целевому хосту, он передает пакет запроса на подключение при помощи транспортного протокола, ориентированного на соединение, как показано на рис. 12.
![](https://habrastorage.org/r/w1560/web/c7a/dc4/80a/c7adc480a820488b898a0f69e1070777.png)
Рис. 12 Декодированный пакет запроса на подключение в Wireshark.
Если целевое устройство отвечает должным образом, компонент 61850 передает пакет
Затем этот компонент 61850 нумерует компоненты, обнаруженные на предыдущем этапе, и отправляет предметно-ориентированные запросы
![](https://habrastorage.org/r/w1560/web/e30/e4a/c37/e30e4ac37f6f4cc4a9bcda3d8f49295f.png)
Рис. 13. Декодированный запрос MMS
Затем компонент 61850 парсит информацию, полученную в ответ на эти запросы, и ищет переменные, которые содержат следующие строковые последовательности:
Последовательность CSW — это название логического узла, который используется для управления прерывателями цепи и выключателями.
Для переменных, которые содержат последовательности Model или stVal, компонент 61850 передает дополнительный MMS запрос
Компонент 61850 создаст файл с логами его работы, содержащий IP-адреса, MMS домены, названные переменные и состояние узлов (открытые или закрытые) его целей.
Компонент OPC DA внедряет клиент для протокола, описанного в спецификации OPC Data Access. OPC (OLE for Process Control) — это стандарт ПО и спецификация, основанная на технологиях Microsoft, таких как OLE, COM и DCOM. Часть, относящаяся к доступу к данным (DA) спецификации OPC, позволяет производить обмен данными в реальном времени между распространяемыми компонентами по принципу модели «клиент-сервер».
Этот компонент существует в качестве отдельного вредоносного инструмента с именем файла
![](https://habrastorage.org/r/w1560/web/c0d/485/fea/c0d485fea69e443b9e28c33ad825ffb0.png)
Рис. 14. Таблица PE показывает внутреннее имя DLL компонента OPC DA.
Компонент OPC DA не требует какого-либо файла с конфигурацией. После исполнения атакующим он номерует все OPC-серверы при помощи метода
Следующий компонент использует интерфейс
Имена элементов дают основание предполагать, что атакующих интересует элементы OPC, предоставленные серверами OPC, которые относятся к решениям ABB, такие как линейка MicroSCADA. На рис. 15 показан образец элементов OPC, который содержат имена с похожими строковыми последовательностями. Этот список элементов OPC получен инструментом списков объектов процесса OPC от ABB.
![](https://habrastorage.org/r/w1560/web/d31/188/46d/d3118846d12b4ba5bded2db19c03dab6.png)
Рис. 15. Пример имен элементов OPC в поле IN, полученным при помощи инструмента списков объектов процесса OPC.
Атакующие используют строку
![](https://habrastorage.org/r/w1560/web/aed/9a6/08d/aed9a608d94842db9f58205322681539.png)
Рис. 16. Дизассемблированный код компонента OPC DA, который использует строку
На финальном этапе компонент OPC DA пробует изменить состояние обнаруженных элементов OPC при помощи интерфейса
![](https://habrastorage.org/r/w1560/web/0b5/06e/29c/0b506e29c27a4d529233e369e9f2a0b8.png)
Рис. 17. Дизассемблированный код компонента OPC DA, который использует интерфейс
Компонент прописывает имя сервера OPC, состояние имени элемента OPC, код качества и значение в лог-файле. Записанные значения разделяются следующими строками заголовка:
Компонент стирателя данных (Data Wiper) — это деструктивный компонент, который используется на финальном этапе атаки. Хакеры используют этот компонент, чтобы замести следы и усложнить процесс восстановления.
Имя файла этого компонента
После исполнения компонент пробует пронумеровать все ключи в реестре, который перечисляет службы Windows.
Он пытается установить значение реестра
Следующий этап — удаление содержимого файла. Компонент нумерует файлы с определенными расширениями на всех приводах, подключенных к компьютеру, от C:\ до Z:\. Нужно отметить, что во время нумерации компонент пропускает файлы, расположенные в подкаталоге, которые содержат слово
Компонент подменяет содержимое файла бессмысленной информацией, получаемой из содержимого новой выделенной памяти. Чтобы исполнить эту операцию должным образом, компонент пробует переписать файлы дважды. Первая попытка происходит, когда файл обнаруживается на приводе. Если первая попытка безуспешна, компонент совершает вторую попытку, но перед этим завершает все процессы, кроме включенных в список критических системных процессов. Список процессов показан на рис. 18.
Чтобы ускорить процесс стирания, компонент переписывает только часть содержимого файла в его начале. Объем информации, который будет переписан, зависит от размера файла. Наименьший объем информации будет переписан у файлов размером 1 Mb (4096 байтов) и меньше. Наибольший объем информации будет переписан у файлов размером 10 Mb (32768 байтов) и меньше.
Наконец, этот компонент пробует завершить все процессы, включая системные, кроме собственного. Это приведет к тому, что система перестанет отвечать и в итоге выйдет из строя.
![](https://habrastorage.org/r/w1560/web/23c/99b/b73/23c99bb7341e478780f33ff963e05704.png)
Рис. 18. Список процессов, которые не завершаются во время второй попытки.
Маски имен файлов, которые переписывает компонент стирателя:
Этот список содержит расширения имен файлов, которые используются в стандартной среде, такие как бинарники Windows (.exe/.dll), архивы (.7z /.tar/.rar/.zip), файлы бэкапа (.bak/.bk/.bkp), файлы сервера Microsoft SQL (.mdf/.ldf) и различные файлы конфигурации (.ini/.xml). Вдобавок компонент стирает файлы, которые могут использоваться в промышленных системах управления, например, написанные при помощи языка описания конфигурации подстанций (.scl/.cid/.scd), а также файлы и расширения, которые используются продуктами ABB.
Например, файл под названием
Арсенал атакующих включает сканер портов, который может быть использован для составления карты сети и поиска компьютеров, относящихся к их атаке. Что интересно, вместо использования уже существующего ПО, хакеры создали собственный сканер портов. Как видно из рис. 19, они могут назначить диапазон IP-адресов и диапазон портов сети, которые будут просканированы этим инструментом.
![](https://habrastorage.org/r/w1560/web/e8f/b8f/b98/e8fb8fb9806f4767a388a85935b10076.png)
Рис. 19. Пример использования сканера портов.
Еще один инструмент из арсенала хакеров — инструмент отказа в обслуживании (DoS), нацеленный на устройства Siemens SIPROTEC. Инструмент эксплуатирует уязвимость CVE-2015-5374, чтобы вызвать зависание устройства. Как только эта уязвимость будет использована, устройство перестанет отвечать на какие-либо команды до тех пор, пока не будет перезагружено вручную.
Чтобы использовать эту уязвимость, атакующие жестко запрограммировали в DoS-инструменте IP-адреса устройств. При использовании инструмент посылает специально созданные пакеты на порт 50000 на целевой IP-адрес при помощи UDP (User Datagram Protocol). Пакет UDP содержит всего 18 байтов.
![](https://habrastorage.org/r/w1560/web/b9f/c88/4eb/b9fc884eb5144046a0d6fae250008e01.png)
Рис. 20. Содержимое пакета UDP, задействованного при использовании уязвимости CVE-2015-5374.
Расследование отключения электроэнергии в Киеве в декабре 2016 года пока не завершено. На данный момент нет подтверждений тому, что Industroyer стал прямой причиной сбоя. Тем не менее, мы считаем эту версию вполне вероятной, поскольку вредоносная программа позволяет напрямую управлять выключателями и прерывателями цепи в сети электрических подстанций при помощи протоколов ICS, а также содержит метку времени активации 17 декабря 2016 года – в день отключения электроэнергии.
Мы можем с уверенностью сказать, что семейство Win32/Industroyer — это продвинутая и сложная вредоносная программа, нацеленная на промышленные системы управления. Проблема в том, что малварь – лишь инструмент в руках еще более продвинутых и высококвалифицированных злоумышленников. Кибергруппа, стоящая за Industroyer, может адаптировать программу для любой подобной среды.
Широко распространенные промышленные протоколы, которые использует Industroyer, создавались десятилетия назад без учета вопросов безопасности. Таким образом, любое вмешательство хакеров в работу промышленной сети, где применяются эти протоколы, заведомо приведет к серьезным последствиям.
Хеши SHA-1:
IP-адреса C&C серверов:
Внимание! Большинство серверов с этими IP-адресами были частью сети Tor, что означает, что использование индикаторов может дать ложноположительное совпадение.
Задать дополнительные вопросы или передать образцы вредоносного ПО, имеющие отношение к Win32/Industroyer, можно по электронной почте threatintel@eset.com.
Создателей Win32/Industroyer отличает высокая квалификация и глубокое понимание промышленных систем управления и протоколов связи в электроэнергетике. Маловероятно, чтобы кто-либо мог написать и протестировать подобное ПО без доступа к специализированному оборудованию, которое используется в целевой среде.
![](https://habrastorage.org/web/de2/0db/39c/de20db39cea24c0e803a07e4dca18785.png)
Авторы вредоносной программы реализовали поддержку четырех промышленных протоколов, описанных в следующих стандартах:
- IEC 60870-5-101 (IEC 101)
- IEC 60870-5-104 (IEC 104)
- IEC 61850
- OLE for Process Control Data Access (OPC DA)
В дополнение к этому авторы Industroyer разработали инструмент для выполнения DoS-атак (denial-of-service – отказ в обслуживании), нацеленных на определенные устройства релейной защиты, в частности, линейку Siemens SIPROTEC.
Возможности Win32/Industroyer впечатляют. Если сравнить его с инструментами, которые использовались в атаках на украинскую энергосистему в 2015 году и привели к массовым отключениям электроэнергии 23 декабря 2015 года (BlackEnergy, KillDisk и другие компоненты, включая легитимное ПО для удаленного доступа), можно утверждать, что за Industroyer стоит кибергруппа более высокого уровня. Авторы создали вредоносную программу, которая позволяет напрямую управлять выключателями и прерывателями цепи в сети электрических подстанций. По некоторым признакам мы предполагаем, что Industroyer может быть связан со сбоем энергоснабжения в Киеве в декабре 2016 года. Тем не менее, на момент написания отчета это не было подтверждено, и расследование продолжается. Вектор заражения пока не установлен.
Industroyer состоит из нескольких модулей, описание и анализ которых представлены в следующих разделах отчета. Прежде чем перейти к деталям, предлагаем упрощенную схему, которая показывает связь между компонентами вредоносной программы.
![](https://habrastorage.org/web/fc2/a5b/e1c/fc2a5be1c362441ba833accc6bacd6fd.png)
Рисунок 1. Упрощенная схема компонентов Win32/Industroyer.
Некоторые компоненты (включая стиратель данных) аналогичны по своей концепции инструментам, использовавшимся в атаках BlackEnergy на украинские энергокомпании в 2015 году. Тем не менее, мы не видим связи между прошлыми атаками и кодом нового вредоносного ПО.
Основной бэкдор
Главный компонент Industroyer – основной бэкдор – используется атакующими для управления остальными компонентами программы.
Как и положено бэкдору, этот компонент довольно прост. Он подключается к удаленному C&C-серверу через HTTPS и получает команды от атакующих. Все изученные образцы жестко запрограммированы на использование одного и того же адреса прокси, расположенного в локальной сети. Таким образом, бэкдор явно предназначен для работы в определенной организации. Также стоит упомянуть, что большинство C&C-серверов бэкдора используют Tor.
Возможно, наиболее интересная особенность бэкдора в том, что атакующие могут задать конкретный час, когда малварь будет активна. Например, можно модифицировать бэкдор таким образом, чтобы он обращался к C&C-серверу в нерабочее время. Это усложняет обнаружение, основанное только на проверке сетевого трафика. Тем не менее, все образцы, изученные до настоящего времени, работали круглосуточно.
![](https://habrastorage.org/web/862/1cd/fa5/8621cdfa5ac2424583b14ca5383e9a1c.png)
Рисунок 2. Декомпилированный код основного бэкдора с возможностью задать время.
После подключения к удаленному C&C-серверу основной бэкдор отправляет в POST-запрос следующие данные:
- строка GUID (глобально-уникальный идентификатор) для текущего профиля оборудования, полученная при помощи функции
GetCurrentHwProfile
- версия вредоносного ПО – 1.1e
- жестко запрограммированный ID образца
- результат любой ранее полученной команды
Жестко запрограммированный ID используется атакующими в качестве идентификатора зараженной машины. Среди всех изученных образцов мы обнаружили следующие значения ID:
- DEF
- DEF-C
- DEF-WS
- DEF-EP
- DC-2-TEMP
- DC-2
- CES-McA-TEMP
- CES
- SRV_WSUS
- SRV_DC-2
- SCE-WSUS01
Основной бэкдор поддерживает следующие команды:
![](https://habrastorage.org/web/08f/6b4/35d/08f6b435d85b48cb8a956e3d0f2336ae.png)
Получив права администратора, атакующие могут обновить установленный бэкдор до более привилегированной версии, которая выполняется как Windows service program. Для этого им нужно выбрать существующий некритический процесс Windows и заменить параметр реестра
ImagePath
на путь к новому бинарному файлу бэкдора.Функциональность основного бэкдора, который работает как служба Windows, идентична описанной. Но есть два небольших различия: название версии бэкдора (1.1s вместо 1.1e) и обфускация кода. Код этой версии бэкдора смешан с ненужными командами ассемблера.
![](https://habrastorage.org/web/cbd/c8a/fcf/cbdc8afcf348495d82ff210ac7651d38.png)
Рисунок 3. Обфусцированный ассемблерный код основного бэкдора, работающего как служба Windows.
Дополнительный бэкдор
Дополнительный бэкдор обеспечивает альтернативный механизм устойчивости, что позволяет атакующим восстановить доступ к целевой сети, если основной бэкдор будет обнаружен и/или деактивирован.
Бэкдор представляет собой троянизированную версию приложения Windows Notepad. Это полнофункциональное приложение, но вирусописатели добавили в него вредоносный код, который выполняется при каждом запуске. Далее, получив права администратора, атакующие могут вручную заменить вредоносный Notepad легитимным.
Добавленный вредоносный код сильно обфусцирован. После расшифровки он подключается к удаленному C&C-серверу (отличается от C&C основного бэкдора) и загружает полезную нагрузку. Она имеет формат шелл-кода, который загружается непосредственно в память и выполняется. Кроме того, добавленный код расшифровывает исходный код Windows Notepad, хранящийся в конце файла, и затем передает ему выполнение – так приложение работает должным образом.
![](https://habrastorage.org/web/d7e/308/504/d7e30850437b46c48f42db0db53124c5.png)
Рисунок 4. Сравнение оригинального бинарного кода Notepad (слева) и бэкдора.
Компонент запуска (Launcher)
Компонент представляет собой отдельный исполняемый файл, предназначенный для запуска полезной нагрузки и компонента стирателя данных.
Компонент запуска содержит определенное время и дату. В изученных образцах было задано две даты: 17 и 20 декабря 2016 года. Как только одна из двух дат наступает, компонент создает два потока. Первый пытается загрузить вредоносную DLL, второй ждет один или два часа (в зависимости от версии компонента), а затем пытается загрузить компонент стирателя данных. Оба потока имеют высший приоритет
THREAD_PRIORITY_HIGHEST
, что означает, что они получают более высокую долю ресурсов центрального процессора. Имя вредоносной DLL добавляется атакующими через параметр командной строки, предоставленный в одной из команд основного бэкдора («Выполнить shell-команду»). Имя файла стирателя данных – всегда
haslo.dat
. Ожидаемые командные строки имеют вид:%LAUNCHER%.exe %WORKING_DIRECTORY% %PAYLOAD%.dll %CONFIGURATION%.ini
Каждый аргумент командной строки обозначает следующее:
•
%LAUNCHER%.exe
– имя файла компонента запуска•
%WORKING_DIRECTORY%
– каталог, в котором хранится вредоносная DLL и конфигурация•
%PAYLOAD%.dll
– имя файла вредоносной DLL •
%CONFIGURATION%.ini
– файл, в котором хранятся данные конфигурации конкретной полезной нагрузки. Путь к этому файлу передается вредоносной DLL компонентом запуска Полезная нагрузка и компонент стирателя данных – стандартные файлы DLL Windows. Чтобы быть загруженными компонентом запуска, они должны экспортировать функцию
Crash
как показано на рис. 5.![](https://habrastorage.org/web/3b3/96c/99f/3b396c99f2ae4ba3a1d6659a5cf8b2cd.png)
Рисунок 5. Пример вредоносной DLL с внутренним именем
Crash101.dll
и экспортированной функцией Crash
.Компонент 101
Вредоносная DLL с именем файла
101.dll
названа в честь международного стандарта IEC 101 (он же IEC 60870-5-101), который описывает протокол мониторинга и управления электроэнергетическими системами. Протокол обеспечивает коммуникацию между промышленными системами управления и удаленными терминальными блоками (Remote Terminal Units – RTUs). Обмен данными осуществляется через последовательное соединение. Компонент 101 частично реализует протокол, описанный в стандарте IEC 101. Он способен связываться с RTU и любым другим устройством, поддерживающим этот протокол.
После выполнения компонент 101 анализирует конфигурацию, хранящуюся в INI-файле. Конфигурация может содержать несколько записей: имя процесса, имена устройств Windows (обычно COM-порты), количество диапазонов и значения диапазонов для адресов информационных объектов (Information Object Address – IOA). IOA – номер, который идентифицирует конкретный элемент данных в устройстве. На рис. 6 показан файл конфигурации компонента 101 с двумя определенными диапазонами IOA: 10-15 и 20-25.
![](https://habrastorage.org/web/734/bbf/ac9/734bbfac96e5475aa9df58a689c5a7dc.png)
Рисунок 6. Пример конфигурации компонента 101.
Имя процесса, указанного в конфигурации, принадлежит приложению, которое, как предполагают атакующие, работает в системе жертвы. Это должно быть приложение, которое машина использует для коммуникаций с RTU через последовательное соединение. Компонент 101 пытается завершить этот процесс и обращается к указанному устройству, используя функции Windows API
CreateFile
, WriteFile
и ReadFile
. Первый СОМ-порт из файла конфигурации используется для фактической связи, два остальных – открыты, чтобы предотвратить обращение других процессов. Таким образом, компонент 101 может взять на себя управление устройством RTU.Компонент выполняет итерацию по всем диапазонам IOA. Для каждого IOA он создает пакеты команд выбора и исполнения с однопозиционной (
C_SC_NA_1
) и двухпозиционной командой (C_DC_NA_1
) и отправляет на устройство RTU. Основная цель компонента – изменить значение выключателя On/Off для однопозиционного и двухпозиционного командного типа IOA. Так, на первом этапе компонент пытается переключить IOA в состояние Off, на второй – On, на заключительном этапе – вернуть в значение Off.![](https://habrastorage.org/web/caa/4a3/ae1/caa4a3ae16924b2c9479a1f2bd76655a.png)
Рисунок 7. Пример разобранного пакета полезной нагрузки в Kaitai Struct WebIDE.
Компонент 104
DLL с именем файла
104.dll
названа в честь стандарта IEC 104 (IEC 60870-5-104). Протокол IEC 104 дополняет IEC 101 так, чтобы передавать данные по TCP/IP. Благодаря гибко изменяемой конфигурации, компонент может быть настроен атакующими под различное оборудование. Рис. 8 показывает, как может выглядеть файл конфигурации.![](https://habrastorage.org/web/abe/26e/ea4/abe26eea4cc64ef59b44936fdfaa8271.png)
Рис. 8. Образец файла DLL конфигурации компонента 104.
После исполнения DLL компонента 104 произведет попытку прочитать файл конфигурации. Путь к файлу конфигурации берется из компонента загрузчика.
Конфигурация содержит раздел
STATION
, за которым следуют свойства, определяющие работу компонента 104. Конфигурация может содержать множество записей STATION
.Наш анализ этого компонента показывает следующие возможные параметры конфигурации:
![](https://habrastorage.org/web/300/e8c/cd8/300e8ccd888447d78a02658cf68913df.png)
После прочтения файла конфигурации компонент 104 создает процесс для каждого фрагмента
STATION
, по одному на каждый. В каждом таком процессе компонент 104 попытается связаться с указанным адресом IP при помощи протокола, описанного в стандарте IEC 104. До установления соединения он попытается завершить легитимный процесс, который должен отвечать за обмен данными с устройством. Это происходит только в том случае, если свойство stop_comm_service
прописано в конфигурации. По умолчанию компонент 104 завершает процесс с именем D2MultiCommService.exe
, либо с тем именем, которое прописано в его конфигурации.Основная идея использования компонента 104 относительно проста. Он связывается с указанным IP и начинает передачу пакетов с адресом ASDU, прописанным в его конфигурации. Цель этого обмена данных — связаться с IOA однопозиционного типа команд. В файле конфигурации атакующий может определить свойство
operation
, чтобы указать, как будут опрошены IOA адреса однопозиционного типа.Первый такой режим
operation
— range
. Хакеры используют его для обнаружения возможных IOA в интересующем устройстве. Им приходится применять данный подход, потому что протокол, описанный в стандарте IEC 104, не дает определенного метода получения этой информации.range
работает в два этапа. Во время первого, после получения диапазона IOA из файла конфигурации, компонент 104 подключается к целевому адресу IP и выполняет опрос указанных IOA. На каждый из этих IOA компонент 104 передает пакеты команд выбора и исполнения для изменения состояния и проверки, относится ли данный IOA к однопозиционному командному типу.![](https://habrastorage.org/web/e7d/ce5/63f/e7dce563f4894f82a0d518b908cd697d.png)
Рис. 9. Пример декодированного в Wireshark пакета компонента 104.
Как только все возможные IOA из определенного диапазона опрошены, компонент 104 переходит ко второму этапу режима
range
. Если возможность записи в логи включена, компонент запишет в него Starting only success
. Остальная часть второго этапа состоит в бесконечном цикле использования ранее обнаруженных IOA однопозиционного типа. В цикле компонент непрерывно передает пакеты команд выбора и исполнения. Вдобавок, если опция change
определена, компонент переключает состояние On/Off между этапами цикла.На рис. 10 показан файл лога, который выдал компонент 104 во время нашего анализа. Из него мы видим, что компонент опросил IOA от 10 до 15 и, когда IOA однопозиционного типа были обнаружены, начал их использование в цикле. В конфигурации опция
change
была включена, так что между циклами компонент переключал значение выключателя с On на Off и писал это в лог.![](https://habrastorage.org/web/e08/2f4/4d0/e082f44d003f4ce5a993208432d2e164.png)
Рис. 10. Пример логов компонента 104.
Второй режим
operation
— shift
. Он очень похож на режим range
. Атакующий определяет в файле конфигурации диапазон IOA и изменяемые значения. После активации компонента 104 все происходит точно так же, как и в режиме range; однако, как только все IOA в определенном диапазоне будут опрошены, он начинает опрос нового диапазона. Новый диапазон высчитывается путем сложения дефолтного диапазона и значений сдвига.Третий режим
operation
— sequence
. Может применяться хакерами после того, как они узнают значения всех IOA однопозиционного типа команд, поддерживаемых подключенным устройством. Этот компонент незамедлительно начнет исполнение бесконечного цикла, передавая пакеты выбора и исполнения на IOA, указанные в файле конфигурации.Кроме способности писать в лог, компонент 104 может выводить отладочную информацию в консоль, как это показано на рис. 11.
![](https://habrastorage.org/web/982/22a/bce/98222abce31a41bfa47f503346642f69.png)
Рис. 11. Вывод на консоль компонента 104.
Компонент 61850
В отличие от компонентов 101 и 104, существует в виде отдельного вредоносного инструмента, состоящего из исполняемого файла под названием
61850.exe
и DLL 61850.dll
. Назван в честь стандарта IEC 61850. Этот стандарт описывает протокол, используемый для обмена данными между устройствами различных производителей, которые выполняют функции защиты, автоматизации, измерения, мониторинга и управления систем автоматики электрических подстанций. Это сложный и надежный протокол, но компонент 61850 использует только небольшой ряд его параметров, чтобы привести к разрушительным последствиям.После исполнения DLL компонента 61850 пробует прочесть файл конфигурации, чей путь предоставляется компонентом запуска. Отдельная версия по умолчанию берет конфигурацию из
i.ini
. Ожидается, что файл конфигурации содержит список IP-адресов устройств, которые имеют возможность обмена данными по протоколу, описанному в стандарте IEC 61850. Если файл конфигурации не находится, компонент 61850 нумерует все подключенные адаптеры сети для определения их масок подсети TCP/IP. Затем компонент нумерует все возможные IP-адреса для каждой из масок подсети и пробует подключиться к порту 102 каждого адреса. Таким образом, компонент умеет автоматически обнаруживать подходящие устройства в сети.
В другом случае, если файл конфигурации найден и содержит целевые адреса IP, компонент подключается к порту 102 по этим адресам и найденным автоматически.
Как только этот компонент подключается к целевому хосту, он передает пакет запроса на подключение при помощи транспортного протокола, ориентированного на соединение, как показано на рис. 12.
![](https://habrastorage.org/web/c7a/dc4/80a/c7adc480a820488b898a0f69e1070777.png)
Рис. 12 Декодированный пакет запроса на подключение в Wireshark.
Если целевое устройство отвечает должным образом, компонент 61850 передает пакет
InitiateRequest
при помощи Спецификации производственных сообщений (MMS). Если ожидаемый ответ получен, он передает MMS запрос getNameList
. Таким образом, компонент составляет список имен объектов в виртуальном производственном устройстве (VMD). Затем этот компонент 61850 нумерует компоненты, обнаруженные на предыдущем этапе, и отправляет предметно-ориентированные запросы
getNameList
с каждым именем объекта. Таким образом, компонент нумерует названные переменные в определенном домене. ![](https://habrastorage.org/web/e30/e4a/c37/e30e4ac37f6f4cc4a9bcda3d8f49295f.png)
Рис. 13. Декодированный запрос MMS
getNameList
в Wireshark.Затем компонент 61850 парсит информацию, полученную в ответ на эти запросы, и ищет переменные, которые содержат следующие строковые последовательности:
- CSW, CF, Pos и Model
- CSW, ST, Pos и stVal
- CSW, CO, Pos, Oper, но не $T
- CSW, CO, Pos, SBO, но не $T
Последовательность CSW — это название логического узла, который используется для управления прерывателями цепи и выключателями.
Для переменных, которые содержат последовательности Model или stVal, компонент 61850 передает дополнительный MMS запрос
Read
. Для некоторых из этих переменных компонент также может передать MMS запрос Write
, который изменит их текущее состояние.Компонент 61850 создаст файл с логами его работы, содержащий IP-адреса, MMS домены, названные переменные и состояние узлов (открытые или закрытые) его целей.
Компонент OPC DA
Компонент OPC DA внедряет клиент для протокола, описанного в спецификации OPC Data Access. OPC (OLE for Process Control) — это стандарт ПО и спецификация, основанная на технологиях Microsoft, таких как OLE, COM и DCOM. Часть, относящаяся к доступу к данным (DA) спецификации OPC, позволяет производить обмен данными в реальном времени между распространяемыми компонентами по принципу модели «клиент-сервер».
Этот компонент существует в качестве отдельного вредоносного инструмента с именем файла
OPC.exe
и DLL, который использует функционал и 61850, и OPC DA компонентов. Внутреннее название DLL в экспортированной таблице PE OPCClientDemo.dll
, что дает основание предположить, что этот компонент может быть основан на проекте с открытым исходным кодом OPC Client.![](https://habrastorage.org/web/c0d/485/fea/c0d485fea69e443b9e28c33ad825ffb0.png)
Рис. 14. Таблица PE показывает внутреннее имя DLL компонента OPC DA.
Компонент OPC DA не требует какого-либо файла с конфигурацией. После исполнения атакующим он номерует все OPC-серверы при помощи метода
ICatInformation::EnumClassesOfCategories
с идентификатором категории CATID_OPCDAServer20
и IOPCServer::GetStatus
для определения тех, которые запущены.Следующий компонент использует интерфейс
IOPCBrowseServerAddressSpace
для нумерации всех серверных элементов OPC. Особым образом он ищет элементы, содержащие следующие последовательности в имени:- ctlSelOn
- ctlOperOn
- ctlSelOff
- ctlOperOff
- \Pos и stVal
Имена элементов дают основание предполагать, что атакующих интересует элементы OPC, предоставленные серверами OPC, которые относятся к решениям ABB, такие как линейка MicroSCADA. На рис. 15 показан образец элементов OPC, который содержат имена с похожими строковыми последовательностями. Этот список элементов OPC получен инструментом списков объектов процесса OPC от ABB.
![](https://habrastorage.org/web/d31/188/46d/d3118846d12b4ba5bded2db19c03dab6.png)
Рис. 15. Пример имен элементов OPC в поле IN, полученным при помощи инструмента списков объектов процесса OPC.
Атакующие используют строку
Abdul
при добавлении новой группы OPC. Возможно эта строка используется атакующими в качестве сленгового названия решений ABB.![](https://habrastorage.org/web/aed/9a6/08d/aed9a608d94842db9f58205322681539.png)
Рис. 16. Дизассемблированный код компонента OPC DA, который использует строку
Abdul
. На финальном этапе компонент OPC DA пробует изменить состояние обнаруженных элементов OPC при помощи интерфейса
IOPCSyncIO
, прописывая значение 0x01 дважды. ![](https://habrastorage.org/web/0b5/06e/29c/0b506e29c27a4d529233e369e9f2a0b8.png)
Рис. 17. Дизассемблированный код компонента OPC DA, который использует интерфейс
IOPCSyncIO
.Компонент прописывает имя сервера OPC, состояние имени элемента OPC, код качества и значение в лог-файле. Записанные значения разделяются следующими строками заголовка:
- [*ServerName: %SERVERNAME%] [State: Before]
- [*ServerName: %SERVERNAME%] [State: After ON]
- [*ServerName: %SERVERNAME%] [State: After OFF]
Компонент стирателя данных
Компонент стирателя данных (Data Wiper) — это деструктивный компонент, который используется на финальном этапе атаки. Хакеры используют этот компонент, чтобы замести следы и усложнить процесс восстановления.
Имя файла этого компонента
haslo.dat
или haslo.exe
, он может быть исполнен компонентом запуска, либо использоваться в качестве отдельного вредоносного инструмента.После исполнения компонент пробует пронумеровать все ключи в реестре, который перечисляет службы Windows.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
Он пытается установить значение реестра
ImagePath
с пустой строкой в каждой обнаруженной записи. Это приведет к тому, что операционная система перестанет загружаться.Следующий этап — удаление содержимого файла. Компонент нумерует файлы с определенными расширениями на всех приводах, подключенных к компьютеру, от C:\ до Z:\. Нужно отметить, что во время нумерации компонент пропускает файлы, расположенные в подкаталоге, которые содержат слово
Windows
в названии.Компонент подменяет содержимое файла бессмысленной информацией, получаемой из содержимого новой выделенной памяти. Чтобы исполнить эту операцию должным образом, компонент пробует переписать файлы дважды. Первая попытка происходит, когда файл обнаруживается на приводе. Если первая попытка безуспешна, компонент совершает вторую попытку, но перед этим завершает все процессы, кроме включенных в список критических системных процессов. Список процессов показан на рис. 18.
Чтобы ускорить процесс стирания, компонент переписывает только часть содержимого файла в его начале. Объем информации, который будет переписан, зависит от размера файла. Наименьший объем информации будет переписан у файлов размером 1 Mb (4096 байтов) и меньше. Наибольший объем информации будет переписан у файлов размером 10 Mb (32768 байтов) и меньше.
Наконец, этот компонент пробует завершить все процессы, включая системные, кроме собственного. Это приведет к тому, что система перестанет отвечать и в итоге выйдет из строя.
![](https://habrastorage.org/web/23c/99b/b73/23c99bb7341e478780f33ff963e05704.png)
Рис. 18. Список процессов, которые не завершаются во время второй попытки.
Маски имен файлов, которые переписывает компонент стирателя:
- SYS_BASCON.COM
- *.v
- *.PL
- *.paf
- *.v
- *.XRF
- *.trc
- *.SCL
- *.bak
- *.cid
- *.scd
- *.pcmp
- *.pcmi
- *.pcmt
- *.xml
- *.CIN
- *.ini
- *.prj
- *.cxm
- *.elb
- *.epl
- *.mdf
- *.ldf
- *.bak
- *.bk
- *.bkp
- *.log
- *.zip
- *.rar
- *.tar
- *.7z
- *.exe
- *.dll
Этот список содержит расширения имен файлов, которые используются в стандартной среде, такие как бинарники Windows (.exe/.dll), архивы (.7z /.tar/.rar/.zip), файлы бэкапа (.bak/.bk/.bkp), файлы сервера Microsoft SQL (.mdf/.ldf) и различные файлы конфигурации (.ini/.xml). Вдобавок компонент стирает файлы, которые могут использоваться в промышленных системах управления, например, написанные при помощи языка описания конфигурации подстанций (.scl/.cid/.scd), а также файлы и расширения, которые используются продуктами ABB.
Например, файл под названием
SYS_BASCON.COM
используется решениями ABB для хранения информации с конфигурацией, а файлы с расширением .paf
(Product Authorization File
) – для хранения информации по лицензиям для продуктов ABB MicroSCADA.Дополнительные инструменты: сканер портов
Арсенал атакующих включает сканер портов, который может быть использован для составления карты сети и поиска компьютеров, относящихся к их атаке. Что интересно, вместо использования уже существующего ПО, хакеры создали собственный сканер портов. Как видно из рис. 19, они могут назначить диапазон IP-адресов и диапазон портов сети, которые будут просканированы этим инструментом.
![](https://habrastorage.org/web/e8f/b8f/b98/e8fb8fb9806f4767a388a85935b10076.png)
Рис. 19. Пример использования сканера портов.
Дополнительные инструменты: DoS Tool
Еще один инструмент из арсенала хакеров — инструмент отказа в обслуживании (DoS), нацеленный на устройства Siemens SIPROTEC. Инструмент эксплуатирует уязвимость CVE-2015-5374, чтобы вызвать зависание устройства. Как только эта уязвимость будет использована, устройство перестанет отвечать на какие-либо команды до тех пор, пока не будет перезагружено вручную.
Чтобы использовать эту уязвимость, атакующие жестко запрограммировали в DoS-инструменте IP-адреса устройств. При использовании инструмент посылает специально созданные пакеты на порт 50000 на целевой IP-адрес при помощи UDP (User Datagram Protocol). Пакет UDP содержит всего 18 байтов.
![](https://habrastorage.org/web/b9f/c88/4eb/b9fc884eb5144046a0d6fae250008e01.png)
Рис. 20. Содержимое пакета UDP, задействованного при использовании уязвимости CVE-2015-5374.
Вывод
Расследование отключения электроэнергии в Киеве в декабре 2016 года пока не завершено. На данный момент нет подтверждений тому, что Industroyer стал прямой причиной сбоя. Тем не менее, мы считаем эту версию вполне вероятной, поскольку вредоносная программа позволяет напрямую управлять выключателями и прерывателями цепи в сети электрических подстанций при помощи протоколов ICS, а также содержит метку времени активации 17 декабря 2016 года – в день отключения электроэнергии.
Мы можем с уверенностью сказать, что семейство Win32/Industroyer — это продвинутая и сложная вредоносная программа, нацеленная на промышленные системы управления. Проблема в том, что малварь – лишь инструмент в руках еще более продвинутых и высококвалифицированных злоумышленников. Кибергруппа, стоящая за Industroyer, может адаптировать программу для любой подобной среды.
Широко распространенные промышленные протоколы, которые использует Industroyer, создавались десятилетия назад без учета вопросов безопасности. Таким образом, любое вмешательство хакеров в работу промышленной сети, где применяются эти протоколы, заведомо приведет к серьезным последствиям.
Индикаторы заражения (IoCs)
Хеши SHA-1:
F6C21F8189CED6AE150F9EF2E82A3A57843B587D
CCCCE62996D578B984984426A024D9B250237533
8E39ECA1E48240C01EE570631AE8F0C9A9637187
2CB8230281B86FA944D3043AE906016C8B5984D9
79CA89711CDAEDB16B0CCCCFDCFBD6AA7E57120A
94488F214B165512D2FC0438A581F5C9E3BD4D4C
5A5FAFBC3FEC8D36FD57B075EBF34119BA3BFF04
B92149F046F00BB69DE329B8457D32C24726EE00
B335163E6EB854DF5E08E85026B2C3518891EDA8
IP-адреса C&C серверов:
195.16.88[.]6
46.28.200[.]132
188.42.253[.]43
5.39.218[.]152
93.115.27[.]57
Внимание! Большинство серверов с этими IP-адресами были частью сети Tor, что означает, что использование индикаторов может дать ложноположительное совпадение.
Задать дополнительные вопросы или передать образцы вредоносного ПО, имеющие отношение к Win32/Industroyer, можно по электронной почте threatintel@eset.com.