MyDOOM: червь, из-за которого каждое 12-е письмо в мире было заражённым

В январе 2004 года через одно из каждых двенадцати писем в мировом почтовом трафике распространялся MyDOOM, один из самых быстрых почтовых червей в истории. Разбираем, как был устроен Win32.Mydoom.A, чем он отличался от ILOVEYOU и как найти его следы с помощью YARA и Sigma.

Mydoom.A превращал запуск почтового вложения в долговременную компрометацию Windows. Червь рассылал свои копии, распространялся через Kazaa, готовил HTTP-атаку на SCO и оставлял отдельный компонент удалённого доступа. Все эти функции уже перечислены в предупреждении Qualys от 26 января 2004 года. Поэтому расследование такого заражения нельзя заканчивать на удалении письма или остановке процесса рассылки. Qualys, MyDoom Email Worm.

В этом исследовании я разбираю Mydoom.A / Novarg: инициализацию, сбор почтовых адресов, собственный SMTP-движок, DDoS-модуль и бэкдор. Основа статьи — мой реверс. Публикации антивирусных лабораторий дополняют технический разбор историческим контекстом и позволяют сопоставить описания образцов. Псевдокод передаёт восстановленную логику; имена вспомогательных функций в нём условные.

Как письмо становилось точкой входа

Заражение начиналось с выполнения файла пользователем. Письма могли выглядеть как служебные уведомления: темы Mail Delivery System, Error, Status, объяснение проблем с доставкой или кодировкой, вложение с именем вроде document или readme. Использовались исполняемые расширения .exe, .scr, .pif, .cmd, .bat, ZIP-контейнеры и двойные расширения. Само открытие ZIP не равнозначно выполнению находящегося внутри червя. Panda Security, Mydoom.A, F-Secure, Mydoom.

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

У этой приманки была последовательная логика. Получателю предлагалось открыть «недоставленное сообщение», а после запуска появлялся Notepad с бессмысленным содержимым. Такой экран мог выглядеть как результат повреждения документа. Microsoft описывает временный файл %Temp%\Message, его показ в Notepad и последующее удаление. Microsoft Security Intelligence, Mydoom.A.

Исследуемый образец и упаковка

В исследовании зафиксированы следующие идентификаторы и характеристики файла:

Параметр Значение
MD5 e78b28cf9b32fa99f43058869151525a
SHA-1 1bb753ca16bc205634568da9db3e061803d09a25
SHA-256 4d033157b517e8086cb4d4f70758a93ca6768c0f8166dae5a92d667d1be0b9e0
Подсистема Win32 GUI
Определённая при анализе среда сборки Microsoft Visual C++ 6.0 / Win32 API

Для классического UPX-образца Panda указывает 22 528 байт в упакованном виде и 32 768 байт после распаковки. Часть строк скрыта ROT13. Упакованный файл и результат распаковки нужно учитывать как разные артефакты. Panda Security.

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

Два механизма закрепления

Инициализация проверяет именованный mutex через CreateMutexA; при ERROR_ALREADY_EXISTS процесс завершает работу. В моём разборе строка записана как SwebSipcSmtxS0V. В описаниях Microsoft и F-Secure встречаются другие окончания; это расхождение отдельно отмечено в таблице индикаторов.

Основные файлы — taskmon.exe и shimgapi.dll. Закрепление копии червя выполняется через значение TaskMon в ветке Run под HKLM либо HKCU. Microsoft также описывает резервное размещение файлов в %Temp%, если запись в системный каталог не удалась. Microsoft Security Intelligence.

HKLM\Software\Microsoft\Windows\CurrentVersion\Run
    TaskMon = <путь к taskmon.exe>

HKCU\Software\Microsoft\Windows\CurrentVersion\Run
    TaskMon = <путь к taskmon.exe>

Вторая точка закрепления связана с COM. Значение по умолчанию у следующего ключа заменяется путём к shimgapi.dll; штатно здесь ожидалась webcheck.dll. Qualys отдельно включала восстановление этого значения в процедуру устранения заражения. Qualys.

HKCR\CLSID\{E6FB5E20-DE35-11CF-9C87-00AA005127ED}\InProcServer32
    (Default) = <путь к shimgapi.dll>

Результат — загрузка DLL в адресное пространство explorer.exe при запуске оболочки. Такое поведение описано в исследовании Роберта Новотняка 2004 года. Анализ MyDoom.A.

При первом заражении, по Virus Bulletin, DLL загружает сам червь; COM-регистрация обеспечивает загрузку оболочкой при следующем запуске. Владелец сокета поэтому зависит от стадии заражения. Virus Bulletin.

Завершение taskmon.exe не доказывает прекращение удалённого доступа. Нужно проверить загруженные модули оболочки, COM-регистрацию и владельца слушающего сокета. Имя штатного процесса не освобождает его от проверки.

Сбор адресов и отправка писем

Червь читает содержимое локальных файлов и извлекает адреса собственным парсером. В разобранном пути обход каталогов использует FindFirstFileA / FindNextFileA; работа с адресами не требует вызова почтового клиента через Simple MAPI. Парсер ищет символ @, определяет границы окружающей строки и передаёт кандидата на фильтрацию перед добавлением в очередь отправки.

Упрощённая реконструкция этой части алгоритма:

для каждой позиции i в буфере:
    если buffer[i] != '@':
        перейти к следующей позиции

    start = найти начало адреса слева от i
    end = найти конец адреса справа от i
    candidate = buffer[start:end]

    если candidate проходит фильтры адреса и домена:
        добавить candidate в очередь отправки

    продолжить поиск с end

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

В источниках перечислены адресная книга Windows и файлы .htm, .sht, .php, .asp, .dbx, .tbb, .adb, .pl, .wab, .txt. Встроенный SMTP-модуль позволял червю самостоятельно формировать и отправлять сообщения. Дополнительным каналом служила общая папка Kazaa: туда попадали копии под видом программ и «кряков», например winamp5 и office_crack. Panda Security.

DNS и SMTP

В разобранном сетевом модуле выделена ветка поиска MX-записей: запрос к домену получателя использует QTYPE = 0x000F и QCLASS = 0x0001. После выбора сервера SMTP-модуль формирует сообщение и отправляет его через Winsock. Схема обмена ниже показывает последовательность команд; это представление протокола, а не дословный дамп сессии:

HELO <имя клиента>
MAIL FROM:<подставленный отправитель>
RCPT TO:<получатель>
DATA
<заголовки и MIME-тело с вложением>
.
QUIT

Собственный SMTP-клиент не означает полного отказа от настроек пользователя. Microsoft перечисляет подбор имён серверов с префиксами mail., mx., smtp. и чтение настройки SMTP из Internet Account Manager\Accounts. Для сетевого расследования это означает несколько возможных путей доставки, включая использование настроенного SMTP-сервера. Microsoft Security Intelligence.

Подмена отправителя осложняла расследование. В разборе Габора Саппаноша (Gabor Szappanos) описаны ложные адреса отправителей, ошибочные адреса получателей и дополнительная нагрузка от уведомлений, которые почтовые шлюзы возвращали подставленным отправителям. По той же причине адрес в поле From нельзя считать адресом заражённого компьютера. Virus Bulletin, март 2004 года; переиздание 2019 года.

При анализе почтового архива я бы сохранял исходный MIME, вложение и журналы доверенного шлюза. Проверять происхождение сообщения следует от известного принимающего сервера назад по доступным логам; произвольные заголовки из самого письма не дают надёжной атрибуции. Для сети полезна связка «запуск подозрительного файла на рабочей станции → множество исходящих SMTP-соединений», если такая телеметрия сохранилась.

Что оставалось после заражения

Бэкдор в shimgapi.dll выбирает первый доступный TCP-порт в диапазоне 3127–3198. Он позволяет использовать узел как TCP-прокси и передавать исполняемый файл для запуска. F-Secure.

В сетевой части бэкдора последовательность socket → bind → listen → accept передаёт входящее соединение обработчику. Прокси-ветка и загрузка файла — разные операции. Новотняк также разбирает эти две команды протокола: туннелирование соединения и приём файла с последующим выполнением. В контексте TI полезно разделять эти возможности: прокси даёт сетевой выход через чужой компьютер, загрузка программы позволяет расширить компрометацию. Называть весь протокол просто «SOCKS4» недостаточно: это не описывает команду передачи исполняемого файла. Анализ протокола Shimg.

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

Использование оставленного доступа получило отдельное продолжение: F-Secure описывает Doomjuice, обнаруженный 9 февраля 2004 года. Он находил уже заражённые Mydoom.A машины через TCP/3127 и передавал им свою копию для исполнения; почтового распространения у него не было. Этот случай показывает, почему расследование нельзя ограничивать первым найденным червём. F-Secure, Doomjuice.

DDoS и календарная ловушка

Цель Mydoom.A — www.sco[.]com, HTTP на TCP/80. F-Secure описывает запуск 64 потоков и повтор запросов примерно через 1024 мс, начиная с 1 февраля 2004 года, 16:09:18 UTC по часам заражённой системы. F-Secure.

В разборе DDoS-модуля цепочка вызовов выглядит так: разрешение имени через gethostbyname, создание TCP-сокета, connect к порту 80, отправка HTTP GET и закрытие соединения. Параллельное выполнение обеспечивают 64 рабочих потока.

В исследовании приведены оценки нагрузки:

Показатель Значение для рассматриваемого сценария
Интенсивность HTTP-запросов Около 200–500 запросов/с на узел
Одновременные исходящие SMTP-сокеты До 100

Эти оценки характеризуют рассматриваемый сценарий; количество потоков само по себе не задаёт фиксированную производительность на любой машине.

В исторических описаниях есть расхождение по темпу запросов: F-Secure указывает 1024 мс, Virus Bulletin — один запрос каждую миллисекунду. Virus Bulletin также разбирает ошибку сравнения частей временной метки, из-за которой атака запускалась не на всех узлах. Virus Bulletin.

Там же описана проверка конечной даты при старте: 12 февраля 2004 года, 02:28:57 UTC. Уже работающий экземпляр мог продолжить действия после этой границы до остановки или перезапуска. Бэкдор при этом сохранялся. Поэтому выражение «самоликвидация 12 февраля» технически неверно. Virus Bulletin.

Для лабораторного воспроизведения это означает необходимость фиксировать гостевое время и момент запуска. Если исследовать старый образец при сегодняшней дате, часть поведения может не проявиться. Такой отрицательный результат нельзя автоматически переносить на условия января–февраля 2004 года.

Варианты семейства следует учитывать отдельно. У Mydoom.B F-Secure описывает другие имена компонентов — explorer.exe и ctfmon.dll, изменение hosts для блокировки сайтов и дополнительную цель DDoS — Microsoft. Переносить эти признаки на вариант A нельзя. Речь о вредоносной копии с именем explorer.exe, которую также нужно отличать от штатной оболочки Windows. F-Secure, Mydoom.B.

Индикаторы и их доказательная сила

Следующая таблица объединяет описанные выше признаки. Это исторические ориентиры для поиска; их наличие и сочетание нужно проверять на исследуемом хосте.

Признак Что проверять Чего он сам по себе не доказывает
taskmon.exe Путь, содержимое, происхождение, запуск через TaskMon Принадлежность файла семейству по одному имени
shimgapi.dll Байты DLL, COM-регистрацию, загрузку оболочкой Фактическое использование удалённого доступа
Run\TaskMon Данные значения и существование целевого файла Успешное выполнение после входа пользователя
Указанный CLSID → shimgapi.dll Значение по умолчанию InProcServer32 Личность оператора или наличие следующей стадии
SwebSipcSmtxS0V — авторский разбор; SwebSipcSmtxS0 / SwebSipcSmtxSO — внешние описания Точное значение строки в исследуемом файле и памяти Тождество образцов только по названию семейства
TCP/3127–3198 Локальный порт, процесс, направление и содержимое соединения Вредоносность любого сервиса на этом порту
www.sco[.]com Исторические HTTP-запросы и их связь с процессом Принадлежность домена атакующему

Источники значений: авторский разбор и описания Microsoft, Qualys, F-Secure.

Домен SCO в этом кейсе — цель атаки. Его нельзя переносить в список инфраструктуры управления вредоносным ПО.

В авторском разборе указан SwebSipcSmtxS0V, у Microsoft — SwebSipcSmtxS0, у F-Secure — SwebSipcSmtxSO. Ниже эти строки учитываются как поисковые альтернативы. Различие сохранено явно: замена строки из исследуемого образца на строку из справочника могла бы скрыть отличие самого файла или ошибку транскрипции.

Примеры обнаружения

Ниже приведены редакционные версии правил по результатам разбора. Для этих версий проверены разбор YAML и ROT13-строки; компиляция и прогон на корпусе в ходе редактуры не выполнялись, поэтому у Sigma сохранён статус experimental. Формат и значения статусов определяет спецификация Sigma.

Sigma ниже задаёт требования к современному источнику событий. Эти примеры не предполагают, что на Windows 2000/XP в 2004 году работал Sysmon. При анализе старого дискового образа основой будут файлы и сохранённые кусты реестра; наличие журналов нужного формата проверяется отдельно.

Первое правило ищет сочетание строк в распакованном PE. Для каждого признака указаны открытая и ROT13-форма. Оно не покрывает произвольный дамп памяти, всю совокупность вариантов Mydoom или любой UPX-контейнер.

rule Mydoom_Related_Unpacked_PE_Strings_Experimental
{
    meta:
        description = "Hunting candidate for unpacked Mydoom-related PE files"
        date = "2026-10-03"
        scope = "Unpacked PE file; not validated on malware or clean corpus"
        reference = "https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=Worm%3AWin32%2FMydoom.A%40mm"
        reference_alt = "https://www.f-secure.com/v-descs/novarg"

    strings:
        $mutex_author = "SwebSipcSmtxS0V" ascii
        $mutex_author_rot13 = "FjroFvcpFzgkF0I" ascii
        $mutex_plain = "SwebSipcSmtxS0" ascii
        $mutex_rot13 = "FjroFvcpFzgkF0" ascii
        $mutex_plain_o = "SwebSipcSmtxSO" ascii
        $mutex_rot13_o = "FjroFvcpFzgkFB" ascii
        $worm_plain = "taskmon.exe" ascii nocase
        $worm_rot13 = "gnfxzba.rkr" ascii nocase
        $dll_plain = "shimgapi.dll" ascii nocase
        $dll_rot13 = "fuvztncv.qyy" ascii nocase

    condition:
        uint16(0) == 0x5A4D and
        1 of ($mutex_*) and
        1 of ($worm_*) and
        1 of ($dll_*)
}

Здесь MZ — лишь предварительный фильтр. Срабатывание следует подтверждать разбором файла. Для оценки правила нужны положительные образцы, чистые PE и отрицательные проверки с отдельными строками: файл только с именем taskmon.exe срабатывать не должен. Синтаксис строк и условий описан в документации YARA.

Следующее правило ищет запись одного из двух значений закрепления. Оно требует источник событий с полями TargetObject и Details и сохранением строковых данных реестра. Оно не утверждает, что DLL уже загрузилась или бэкдор принял соединение.

title: Mydoom Related Run Or COM Registry Value
status: experimental
description: Detects registry values associated with historical Mydoom persistence.
references:
    - https://cdn2.qualys.com/docs/mktg/securityalerts/Qadvise-MyDoomWorm-20040126.pdf
date: 2026-10-03
logsource:
    category: registry_set
    product: windows
detection:
    selection_run:
        TargetObject|endswith: '\Software\Microsoft\Windows\CurrentVersion\Run\TaskMon'
        Details|contains: '\taskmon.exe'
    selection_com:
        TargetObject|contains: '\CLSID\{E6FB5E20-DE35-11CF-9C87-00AA005127ED}\InProcServer32'
        Details|contains: '\shimgapi.dll'
    condition: selection_run or selection_com
falsepositives:
    - Authorized historical malware analysis or detection testing
    - Unrelated software reusing the same names and registry locations
level: high

Поиск contains в COM-ветке намеренно допускает разное представление значения по умолчанию. Он также может захватить другие значения внутри этого ключа: перед выводом о подмене нужно прочитать исходное событие. Регистрозависимость, кавычки в пути и нормализацию веток HKLM/HKU следует проверить после преобразования Sigma в запрос конкретной SIEM.

Сетевой кандидат ниже ищет входящее соединение, а не создание слушающего сокета. Sysmon Event ID 3 регистрирует сетевые соединения при включённом сборе этой категории; по умолчанию такой сбор отключён. Событие соединения не доказывает, что зафиксирован именно вызов bind() или listen(). Документация Sysmon.

title: Inbound TCP Connection To Historical Mydoom Port Range
status: experimental
description: Broad hunting candidate; port matching does not identify Mydoom.
references:
    - https://www.f-secure.com/v-descs/novarg
date: 2026-10-03
logsource:
    category: network_connection
    product: windows
detection:
    selection:
        Initiated: 'false'
        Protocol: 'tcp'
        DestinationPort|gte: 3127
        DestinationPort|lte: 3198
    condition: selection
falsepositives:
    - Legitimate applications using these ports
    - Authorized laboratory traffic
level: low

Правило предполагает, что для входящего события DestinationPort обозначает локальный порт принимающей стороны, а Initiated нормализован в строку. Это нужно проверить на реальных событиях используемого источника. gte и lte — числовые модификаторы сравнения из спецификации Sigma.

Пограничные проверки должны включать порты 3126, 3127, 3198 и 3199, исходящее соединение и UDP. Исключать событие только из-за имени explorer.exe нельзя: именно загрузка посторонней DLL делает этот процесс существенным объектом расследования.

Как выстроить форензическое расследование

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

  1. Зафиксировать исходные данные. Сохранить образ диска, доступную память, почтовые сообщения и логи; записать время получения и вычислить хеши. Оригинал и рабочие копии учитывать отдельно.
  2. Установить факт выполнения. Сопоставить вложение с файлами на диске, записью автозагрузки и доступными следами запуска. Отдельно отметить, какие артефакты отсутствуют из-за ограничений старой ОС или неполного сбора.
  3. Проверить обе точки закрепления. Исследовать Run\TaskMon и COM-ветку, прочитать пути к файлам, проверить DLL в памяти оболочки, если память доступна.
  4. Разделить сетевые роли. Отдельно учитывать исходящую рассылку, HTTP к цели DDoS, входящие соединения к бэкдору и возможное проксирование. Для каждого вывода сохранять событие или пакет, на котором он основан.
  5. Искать дополнительные программы. Проверить новые исполняемые файлы и последующие запуски. Наличие бэкдора обосновывает такой поиск, но не позволяет заранее объявить следующую стадию обнаруженной.
  6. Оценить восстановление. После сохранения доказательств устранить точки закрепления и проверить повторный запуск системы. При подтверждённом выполнении неизвестного кода через бэкдор рассматривать восстановление из доверенного источника: удаление двух известных файлов не гарантирует полноту очистки.

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

Атрибуция и выводы

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

Mydoom.A оставлял после массовой рассылки отдельный механизм доступа к системе. Поэтому завершённое расследование должно отвечать на два вопроса: удалось ли остановить распространение и удалось ли вернуть доверие к хосту. Календарная дата окончания активности червя не отвечает на второй вопрос.

Мерч к статье

Больше — в сообществе Похек