Пиков / КАПО
Как читать авторский курс и нормативные материалы

Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин 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, а не сам бинарь.

Что делать на проекте

  1. Проверять, stripped ли бинарь: file ./app (stripped/not stripped) или наличие .symtab через readelf -S.
  2. На stripped-бинаре не ждать символов: nm будет пуст — это не сбой, а признак удалённого .symtab.
  3. Использовать уцелевшие каналы: readelf -d (динамические зависимости целы), readelf --dyn-syms (динамические символы), strings (строка версии, если есть).
  4. Для статически вшитого кода в stripped-бинаре фиксировать честный результат «версия недоступна» и заносить в реестр неопознанных.
  5. Беречь debug-символы как доказательную базу: хранить debuginfo отдельно, не стрипить артефакты, нужные для аудита (см. debug symbols как evidence).
  6. Если состав по бинарю не восстановить — переключаться на источник истины этапа сборки (build-scan), а не угадывать.

Связь