CVSS 6.5 MEDIUM, перцентиль EPSS 0.41 - ниже медианы, эксплуатации в дикой природе не зафиксировано. На бумаге CVE-2026-23863 выглядит рядовой уязвимостью средней критичности в WhatsApp Desktop для Windows. Но если копнуть глубже - это один из самых чистых примеров CWE-158 (Improper Neutralization of Null Byte or NUL Character) в Electron-архитектуре: единственный NUL-байт в имени файла заставлял клиент показывать исполняемый файл как безобидный документ, а при открытии Windows запускал payload. Разберём root cause, место в цепочке атаки и конкретные предусловия - при которых техника работает и при которых нет.
Бизнес-логика attachment spoofing атаки
Прежде чем копать архитектуру - зачем атакующему вообще нужен этот примитив. WhatsApp Desktop - Electron-приложение с аудиторией, которая ежедневно гоняет счета, договоры и скриншоты в рабочих чатах. Attachment spoofing через мессенджер даёт доставку payload через доверенный канал: пользователь по умолчанию доверяет вложениям от знакомых контактов куда больше, чем письмам от незнакомцев.Финальный импакт - выполнение произвольного кода на машине жертвы с правами текущего пользователя. Вектор CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N расшифровывается так: атака удалённая (AV:N), сложность низкая (AC:L), привилегий не требуется (PR:N), но жертва обязана открыть файл (UI:R). Высокий импакт на целостность (I:H) при нулевом воздействии на конфиденциальность и доступность - сама уязвимость лишь доставляет и запускает payload, а не крадёт данные напрямую.
По CISA SSVC, решение для CVE-2026-23863 - Track (мониторить): эксплуатация
none, автоматизируемость no, технический импакт partial. Это не zero-day массового поражения, но для целевых атак через мессенджер - вполне рабочий initial access.Null byte injection в именах файлов: root cause на уровне CWE-158
Уязвимости присвоена CWE-158 - Improper Neutralization of Null Byte or NUL Character. По описанию MITRE CWE, суть в том, что продукт получает входные данные от upstream-компонента, но не нейтрализует (или некорректно нейтрализует) NUL-символы при передаче downstream-компоненту. Проблема исторически характерна для C и C++, но CWE-158 применима к любой технологии, где NUL-байт интерпретируется по-разному на разных уровнях стека.
Граница между JavaScript и WinAPI
В C и C++ строки завершаются нулевым байтом (\x00). Функции strlen(), CreateFileW(), ShellExecuteW() читают символы до первого \x00 и останавливаются. Всё, что идёт после NUL - для C-слоя не существует. Просто нет.В JavaScript (V8, Node.js, Chromium) строки - последовательности UTF-16 code units с явно хранимой длиной. NUL-байт для V8 - просто ещё один символ:
'file.exe\x00.pdf'.length вернёт 13, а не 8.WhatsApp Desktop построен на Electron - Chromium-обёртка с Node.js. UI-логика работает в JavaScript, а файловые операции проходят через native-слой (C/C++ bindings к Windows API). Вот тут и кроется несоответствие: JavaScript видит полную строку с NUL-байтом, а Windows API при получении этой же строки обрезает её по первому NUL.
На мой взгляд, это классическая "пограничная" проблема. Два мира - managed runtime и native код - по-разному смотрят на одну и ту же строку. И никто не проверяет, что сосед по лестничной клетке видит что-то другое.
Как это превращается в спуфинг вложений
Рассмотрим имя файлаpayload.exe\x00invoice.pdf. По описанию NVD, уязвимая версия WhatsApp для Windows "could have allowed maliciously formatted documents with embedded NUL bytes in the filename to be shown in the application as one type of file but run as an executable when opened""Это могло бы позволить отображать в приложении документы с вредоносным форматированием, содержащие нулевые байты в имени файла, как файлы одного типа, но запускаться как исполняемые файлы при открытии.".Механизм по root cause анализу CWE-158 в контексте Electron:
- JavaScript-слой WhatsApp (UI, рендеринг) видит полную строку длиной 24 символа. Логика определения типа файла читает расширение из конца строки - видит
.pdf. Показывает иконку документа. - Windows API (сохранение/открытие) получает ту же строку, но C-функции обрезают её по NUL.
ShellExecuteW()видитpayload.exe- 11 символов. Расширение.exe. Windows запускает файл как исполняемый.
.exe. Уязвимость затрагивала WhatsApp для Windows версий до v2.3000.1032164386.258709, по advisory от Meta.Маскировка исполняемого файла под документ: место в цепочке атаки
CVE-2026-23863 - не самостоятельная атака, а примитив в составе kill chain. В терминах MITRE ATT&CK цепочка выглядит так:| Этап | MITRE ATT&CK | Роль CVE-2026-23863 |
|---|---|---|
| Доставка | Spearphishing via Service (T1566.003, Initial Access) | Атакующий отправляет файл через WhatsApp |
| Маскировка | Masquerade File Type (T1036.008, Defense Evasion) | NUL-байт скрывает реальное расширение |
| Запуск | Malicious File (T1204.002, Execution) | Жертва открывает «документ», ОС исполняет payload |
| Пост-эксплуатация | Ingress Tool Transfer (T1105, C2) | Payload загружает дополнительные инструменты |
Между маскировкой и запуском стоит ещё один элемент - Exploitation for Client Execution (T1203): именно уязвимость в обработке файлов WhatsApp позволяет пройти путь от "документа" в UI до запуска
.exe на диске.Сравнение с родственными техниками обхода фильтра расширений
NUL byte injection - одна из нескольких техник маскировки исполняемых файлов под документы. Для понимания её места:| Техника | ATT&CK ID | Механизм | Сложность детектирования |
|---|---|---|---|
| NUL byte в имени | T1036.008 | NUL обрезает имя в C-слое | Средняя: нужен парсинг raw filename |
| Right-to-Left Override | T1036.002 | Unicode U+202E разворачивает отображение | Низкая: большинство шлюзов фильтруют |
| Двойное расширение | T1036.007 | file.pdf.exe - Windows скрывает расширения | Низкая: GPO "показывать расширения" |
| Obfuscated Files | T1027 | Polyglot: файл валиден как PDF и как PE | Высокая: нужна инспекция magic bytes |
NUL byte injection выигрывает у RLO и двойного расширения в незаметности. RLO-символ детектируется большинством почтовых шлюзов, двойное расширение палится при включённом отображении расширений. NUL-байт эксплуатирует архитектурную границу между runtime-средами - стандартные правила фильтрации его не ловят. По сути, это атака не на валидацию, а на само представление данных в разных слоях стека.
Воспроизведение концепции: минилаб для понимания NUL byte bypass
Требования к окружению
- ОС: Windows 10/11 (любая актуальная сборка)
- RAM: 4 ГБ минимум
- Инструменты: Python 3.10+, Process Monitor (Sysinternals)
- Изоляция: Windows Sandbox или Hyper-V VM - обязательно
- WhatsApp: уязвимы версии для Windows до v2.3000.1032164386.258709 (патч доступен - для воспроизведения нужна уязвимая версия в изолированном окружении)
- Сеть: полная изоляция от production-инфраструктуры
Демонстрация поведения NUL-байта
Прежде чем лезть в WhatsApp, полезно увидеть root cause в чистом виде - как один и тот же filename интерпретируется в двух runtime-средах:
Python:
# Демонстрация концепции - НЕ exploit
filename = "payload.exe\x00invoice.pdf"
print(f"JS-style (полная строка): '{filename}', len={len(filename)}")
c_style = filename.split('\x00')[0] # имитация C-строки
print(f"C-style (до NUL): '{c_style}', len={len(c_style)}")
print(f"Расширение для UI: {filename.rsplit('.', 1)[-1]}")
print(f"Расширение для ОС: {c_style.rsplit('.', 1)[-1]}")
Код:
JS-style (полная строка): 'payload.exe invoice.pdf', len=24
C-style (до NUL): 'payload.exe', len=11
Расширение для UI: pdf
Расширение для ОС: exe
Наблюдение через Process Monitor
Настроив Process Monitor с фильтром на процессWhatsApp.exe и операции CreateFile, Process Create, при открытии вложения с NUL-байтом в имени в уязвимой версии можно наблюдать: Electron-процесс сохраняет файл с обрезанным именем (без части после NUL), затем ShellExecuteW вызывается с путём, где расширение - .exe. Конкретные параметры зависят от версии WhatsApp Desktop.Предусловия и ограничения техники
Работает если:- WhatsApp для Windows ниже v2.3000.1032164386.258709
- Жертва открывает вложение вручную (UI:R в CVSS - обязательное условие)
- Файл не заблокирован антивирусом при записи на диск
- SmartScreen отключён или payload обфусцирован
- WhatsApp обновлён до v2.3000.1032164386.258709+ (патч нейтрализует NUL-байты в именах)
- EDR мониторит создание файлов с несовпадением MIME type и расширения (CrowdStrike Falcon с policy Medium+ детектирует такие аномалии)
- AppLocker или WDAC блокируют запуск
.exeиз пользовательских директорий (%LOCALAPPDATA%,%TEMP%) - Корпоративный proxy или DLP инспектирует содержимое вложений WhatsApp Web
- Жертва не открывает файл - массовая автоматизация невозможна (automatable:
noпо CISA SSVC, EPSS 0.0053)
Детектирование и защита от WhatsApp Desktop эксплойтов
Индикаторы для SOC
- Исполняемые файлы от процесса WhatsApp. Процесс
WhatsApp.exeсоздаёт.exe,.scr,.bat,.cmd,.ps1в%TEMP%или%LOCALAPPDATA%- аномалия для легитимного использования. Если такое прилетит в алерты - разбирать сразу, не откладывая. - MIME type mismatch. Вложение с документным MIME type (
application/pdf,image/jpeg), но magic bytes4D 5A(PE-заголовок) в содержимом. - Дочерний процесс от WhatsApp. Событие
Process Createс parent processWhatsApp.exeи исполняемым файлом из временных директорий. - NUL-байты в filename. Если SIEM парсит raw-события файловых операций - фильтр на
\x00или%00в полях имени файла.
Чеклист для передачи сисадмину
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Attachment spoofing через NUL bytes - техника, которая эксплуатирует архитектурную границу, а не конкретный баг в валидации. Патч в WhatsApp решает проблему: клиент теперь отбрасывает NUL-байты из имён файлов перед отображением и перед передачей в ОС. Но сам класс CWE-158 живёт везде, где JavaScript-фронтенд передаёт пользовательский ввод в нативный бэкенд без санитизации.
По моему опыту, главная проблема здесь не в WhatsApp, а в архитектуре Electron как таковой. Каждое Electron-приложение - потенциальная площадка для CWE-158: разработчики пишут бизнес-логику на JavaScript и редко задумываются, как их строки интерпретируются на уровне WinAPI. При аудитах корпоративных мессенджеров я сталкивался с похожими расхождениями в обработке имён файлов - валидация расширения происходила на JS-стороне, а файловые операции делегировались native-модулю без повторной проверки. Индустрия фиксит конкретные CVE, но не решает системную проблему: на границе между managed runtime и native кодом нужен двойной контроль - и на входе, и на выходе. Пока Electron остаётся стандартом для десктопных мессенджеров, NUL byte injection будет всплывать снова - в разных приложениях и с разными номерами CVE. Вопрос в том, кто найдёт следующий экземпляр первым - баг-хантер через Meta Bug Bounty или оператор таргетированной атаки.
Последнее редактирование модератором: