Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
stripped binaries
Почему это важно для SCA/OSA
strip удаляет из ELF отладочную и символьную информацию, уменьшая бинарь перед поставкой. Для SCA это означает потерю улик: именно по символам и отладочным данным можно было бы косвенно доказать присутствие статически вшитого компонента и его версию. На stripped-бинаре этот канал закрыт, и слепая зона статической линковки становится ещё темнее — у компонента не остаётся ни пакета, ни soname, ни имени функции, по которому его можно опознать.
Ключевой нюанс: strip убирает не всё. Динамическая линковка после strip продолжает работать, значит часть данных обязана уцелеть. Понимать, что именно strip удаляет, а что оставляет, — значит точно знать, какие способы идентификации ещё применимы к поставленному бинарю, а какие уже бесполезны.
Как это проявляется
После strip исчезает таблица символов .symtab и отладочные секции .debug_*, но динамическая таблица .dynsym и секции данных остаются — иначе бинарь не запустился бы:
$ strip ./app_static # удаляет .symtab и .debug_*
# символов больше нет — косвенная идентификация по nm не работает
$ nm -C ./app_static
nm: ./app_static: no symbols
# но динамическая секция и динамические символы целы — рантайм жив
$ readelf -d ./app_static | grep NEEDED
0x0...0001 (NEEDED) Shared library: [libc.so.6]
$ readelf --dyn-syms ./app_static | head
# последнее, что иногда уцелевает, — строка версии в данных
$ strings ./app_static | grep -iE 'OpenSSL [0-9]'
OpenSSL 3.0.11 19 Sep 2023
Таблица: что strip забирает и что оставляет.
| Секция | После strip |
Что значит для SCA |
|---|---|---|
.symtab (все символы) |
удалена | nm пуст: вшитый код по символам не опознать |
.debug_* (DWARF) |
удалена | теряется evidence из отладочной инфы |
.dynsym (динамические символы) |
сохранена | имена экспортируемых/импортируемых символов видны |
.dynamic (DT_NEEDED) |
сохранена | динамические зависимости читаются как обычно |
.rodata / строки |
сохранена | строка версии библиотеки может уцелеть |
После strip версию вшитого кода восстановить почти нечем
stripуносит.symtabи.debug_*— двух главных источников доказательства версии статически слинкованного компонента. Остаётся единственный, ненадёжный канал: строка версии в.rodata(strings), которую вшивают не все библиотеки. Если её нет, честный результат — «компонент присутствует, версия из бинаря недоступна», и закрывать пробел нужно журналом сборки, а не бинарём.
Слепая зона или приём
Слепая зона — пересечение strip и статической линковки. Динамические зависимости после strip читаются по-прежнему (DT_NEEDED цел), а вот статически вшитая библиотека теряет последнюю улику: символов нет (.symtab удалена), DWARF нет, остаётся только надежда на строку версии в .rodata — а её вшивают не все библиотеки. Если и строки нет, корректный итог — «компонент присутствует, версия из бинаря недоступна».
Приём — относиться к отладочным символам как к ценному evidence и не выбрасывать их при поставке без причины: непочищенные .debug_*/.symtab (или отдельный debuginfo-пакет) позволяют доказать происхождение и версию вшитого кода. Если бинарь уже stripped, единственный надёжный источник состава — журнал сборки (компиляция и линковка) и build-inventory, а не сам бинарь.
Что делать на проекте
- Проверять, stripped ли бинарь:
file ./app(stripped/not stripped) или наличие.symtabчерезreadelf -S. - На stripped-бинаре не ждать символов:
nmбудет пуст — это не сбой, а признак удалённого.symtab. - Использовать уцелевшие каналы:
readelf -d(динамические зависимости целы),readelf --dyn-syms(динамические символы),strings(строка версии, если есть). - Для статически вшитого кода в stripped-бинаре фиксировать честный результат «версия недоступна» и заносить в реестр неопознанных.
- Беречь debug-символы как доказательную базу: хранить debuginfo отдельно, не стрипить артефакты, нужные для аудита (см. debug symbols как evidence).
- Если состав по бинарю не восстановить — переключаться на источник истины этапа сборки (build-scan), а не угадывать.
Связь
- Модуль: М09. C/C++ legacy
- Практики: П23. Статическая линковка как слепая зона
- Нормативка: NIST SP 800-218 SSDF (PS.3.2, RV.1) · ГОСТ Р 56939-2024 · BSI TR-03183-2 v2.1.0
- Шаблон: Порядок работы с неопознанной библиотекой
- Смежные заметки 06: статическая линковка · debug symbols как evidence · ELF и разделы dynamic · hash-based identification · компиляция и линковка