
PoC и анализ локального переполнения буфера стека в dataSIMS Avionics ARINC 664-1 v4.5.3, с разбором полезной нагрузки, скриптом воспроизведения и исправлениями записей CVE.
Локальное переполнение буфера стека в dataSIMS Avionics ARINC 4.5.3 (Data Device Corporation)
Привет, я Kağan Çapar. В феврале 2020 года я нашёл локальное переполнение буфера стека в авиационном ПО dataSIMS для databus от DDC и в феврале 2021 года опубликовал proof of concept на Exploit-DB. Почти пять лет спустя, в январе 2026 года, VulnCheck присвоил ему CVE-2021-47881 как ретроактивный CVE — о присвоении я узнал постфактум, а не от них.
Этот репозиторий — архивная запись об этой находке: оригинальный PoC, сохранённый в том виде, в котором он был опубликован, байт-идентичный порт на Python 3, аннотированный разбор полезной нагрузки и исправления двух проблем в опубликованной записи CVE.
Сразу об объёме. Это запись, а не анализ первопричины. dataSIMS — это коммерческое ПО с закрытым исходным кодом, патча от вендора нет, и я не перепроверял это на текущем релизе. Что здесь можно проверить — проверено и показано; всё остальное отмечено в Ограничениях. Если вы пришли сюда в ожидании глубины CVE-2026-5201, сначала прочтите эту заметку.
| CVE | CVE-2021-47881 |
| CWE | CWE-121 — переполнение буфера на основе стека |
| CVSS v4.0 | 6.7 СРЕДНИЙ — AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N (VulnCheck) |
| CVSS v3.1 | 8.4 ВЫСОКИЙ — AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (VulnCheck) |
| Затронуто | dataSIMS Avionics ARINC 664-1, версия 4.5.3 |
| Вендор | Data Device Corporation |
| CNA | VulnCheck |
| Обнаружено | 2020-02-17 |
| PoC опубликован | 2021-02-19 — EDB-49577 |
| CVE опубликован | 2026-01-23 (NVD) |
| Патч вендора | не опубликован |
| Протестировано на | Windows 10 Enterprise x64 |
Затронутый компонент — модуль ARINC 664-1 в dataSIMS 4.5.3. Он считывает файл результатов, который — несмотря на модуль, к которому он относится, — называется milstd1553result.txt; это имя — артефакт вендора, доставшийся от линии MIL-STD-1553 этого пакета, а не указание на то, какой модуль затронут. Подача чрезмерно длинной версии этого файла, сформированной атакующим, переполняет буфер стека фиксированного размера на пути чтения и перезаписывает сохранённый обратный адрес. Крах происходит при полном контроле над EIP:
EIP 42424242 <- 'BBBB' from the payload
ECX 42424242
C0000005 <- STATUS_ACCESS_VIOLATION
Опубликованный PoC имеет размер 1040 байт и останавливается на перезаписи EIP. Он не достигает выполнения кода и никогда не был для этого предназначен — см. Эксплуатируемость.
Раскладка полей PoC, проверенная запуском порта (py poc/poc_py3.py --layout):
| Поле | Смещение | Длина | Содержимое |
|---|---|---|---|
junk | 0 / 0x000 | 600 | заполнитель 0x41 |
align | 600 / 0x258 | 8 | "22221111" |
prop | 608 / 0x260 | 380 | заполнитель 0x43 |
imp | 988 / 0x3dc | 10 | "bzhrturlu2" |
imp2 | 998 / 0x3e6 | 9 | "aracag" 0x13 "1z" |
overwrite | 1007 / 0x3ef | 4 | 0x42 × 4 → сохранённый обратный адрес |
buf | 1011 / 0x3f3 | 29 | заглушка-декодер shikata_ga_nai |
| итого | 1040 | sha256 530efb5efef917082e40dcf379f5e0a526375724af18aba6f0270f794f96d066 |
Смещение до EIP — 1007. Это не число, которое вы получите от !mona findmsp или pattern_offset.rb, — это сумма пяти полей, настроенных вручную. Оригинальный PoC был собран путём расширения данных до тех пор, пока не сдвинулся обратный адрес, а не путём аналитического определения смещения. Я отмечаю это, а не приукрашиваю: аккуратный переписанный вариант нашёл бы истинное расстояние до сохранённого обратного адреса и полностью отбросил бы align, imp и imp2, поскольку ни одно из них не несёт смысла. imp/imp2 — это строки-заполнители, а не импорты.
buf — это 29-байтная заглушка shikata_ga_nai от msfvenom. Дизассемблировано с помощью ndisasm -b32:
00000000 DAC1 fcmovb st1 ; junk FPU op (sgn signature)
00000002 D97424F4 fnstenv [esp-0xc] ; GetPC
00000006 58 pop eax ; eax = &stub
00000007 BB0B7E9762 mov ebx,0x62977e0b ; XOR key
0000000C 33C9 xor ecx,ecx
0000000E B101 mov cl,0x1 ; <-- ONE 4-byte block
00000010 315819 xor [eax+0x19],ebx ; decode block at +0x19
00000013 83E8FC sub eax,-4 ; eax += 4
00000016 035815 add ebx,[eax+0x15] ; key schedule
00000019 E9 db 0xe9 ; <-- encoded block, not code
0000001A 8B db 0x8b
0000001C 7C9C jl 0xffffffb9
Из этого вытекают две вещи, и обе означают, что полезная нагрузка никогда не сможет выполниться:
mov cl,0x1 — цикл декодирования настроен на один 4-байтный блок. За ним нет реальной полезной нагрузки, только эти 4 байта.
Терминатор \xe2\xf4 (loop) отсутствует. Полная заглушка sgn завершает цикл декодирования инструкцией loop перед закодированным телом. Здесь выполнение падает прямо с add ebx,[eax+0x15] на E9 8B 7C 9C — которая в этот момент всё ещё закодирована и в любом случае не является валидной последовательностью инструкций.
Итак, заглушка — это заполнитель, занимающий хвост полезной нагрузки. Это соответствует тому, как PoC был описан на Exploit-DB, и это честное прочтение: это демонстрация контроля над EIP, а не рабочий эксплойт.
Оценивая это так, как это сделал бы брокер или вендор, а не так, как вектор CVSS v3.1:
Ни одна граница привилегий не пересекается. milstd1553result.txt — это файл, который создаёт само приложение, в месте, которым тот же пользователь уже управляет. Атакующий, способный перезаписать его, как правило, уже может выполнять код от имени этого пользователя. Это делает данную ошибку скорее ошибкой надёжности, чем ошибкой безопасности.
PoC не опережает время. Контроль над EIP в x86-сборке эпохи 2020 года сам по себе мало о чём говорит. Превращение его в выполнение кода требует истории с DEP/ASLR — модуля без /DYNAMICBASE, ROP-цепочки или частичной перезаписи. Ничего из этого не было сделано, и я не проверял, с какими механизмами смягчения поставляется текущая сборка.
Она локальна и требует, чтобы оператор загрузил файл. UI:A в CVSS v4.0 отражает реальность; UI:N в v3.1 — нет.
Если кто-то хочет сделать это по-настоящему интересным, продуктивные поверхности атаки — вовсе не этот файл: драйвер ядра, который DDC поставляет для своих PCIe-карт 1553/664 (обработка IOCTL → LPE), любой сетевой разбор кадров ARINC 664/AFDX и входные форматы файлов, которые пакет потребляет из недоверенных источников. Они пересекают реальные границы. Этот — нет.
В записи CVE есть два дефекта, о которых стоит сказать прямо, поскольку она опубликована под моим именем.
Обозначение продукта в записи — "dataSIMS Avionics ARINC 664-1 версия 4.5.3" — корректно. Затронутый компонент — модуль ARINC 664, как указано в моём оригинальном заголовке на Exploit-DB.