7zip - популярный архиватор с открытым исходным кодом, который получил широкое распространение благодаря своей высокой степени сжатия данных и поддержке множества форматов архивов. Он стал неотъемлемым инструментом для многих пользователей, которые сталкиваются с необходимостью архивации и извлечения данных. Однако, как и любая другая программа, 7zip не застрахован от уязвимостей, которые могут стать угрозой для безопасности пользователей.

Целью данной статьи является обсуждение exclude rules в 7zip, а так же способа их обхода. Данный материал поможет пользователям лучше понять угрозы, связанные с использованием exclude rules в 7zip.

Что такое exclude rules в 7zip

Exclude rules в 7zip представляют собой набор правил, которые позволяют пользователям исключать определенные файлы или каталоги при архивации или извлечении данных. Это полезная функция для контроля над тем, какие файлы должны быть включены в архив или извлечены из него, особенно в случаях, когда пользователи хотят ограничить доступ к определенным данным или упростить структуру архива.

Exclude rules могут быть заданы через командную строку при использовании 7zip, позволяя пользователям указывать файлы или каталоги для исключения на основе имени. Таким образом, пользователи могут гибко управлять процессом архивации или извлечения данных, адаптируя его к своим индивидуальным потребностям.

Для использования exclude rules, пользователь должен указать флаг -x в командной строке при вызове 7zip, а затем задать соответствующие условия и ограничения. Пример использования exclude rules:

7z x archive.7z -o output_directory -r -x!'*.txt'

Особенность exclude и рекурсивного парсинга

Флаг -r (рекурсивный режим) в 7zip указывает архиватору обрабатывать все файлы и подкаталоги в указанном каталоге рекурсивно. Это означает, что 7zip будет включать в архив или извлекать из архива все файлы и каталоги, находящиеся на любой глубине вложенности внутри указанного каталога. Флаг -r используется в командной строке при архивации и извлечении данных.

Особенность работы exclude rules в сочетании с флагом -r заключается в том, что указанные исключения будут применяться ко всем файлам и каталогам на всех уровнях вложенности, если в условии исключения не указано иное. Это может привести к исключению файлов, которые пользователь не планировал исключить изначально.

Важно учитывать эту особенность при использовании exclude rules с флагом -r, особенно если вам нужно исключить файлы только на определенных уровнях вложенности. В этом случае следует указать более точные условия исключения, чтобы предотвратить непреднамеренное исключение файлов. Например, для исключения файлов начинающихся на SECRET только из корневого каталога, вы можете указать путь к этому каталогу в условии исключения:

7z x archive.7z -ooutput_directory -x!"SECRET*"

При запуске на обычном архиве убедимся, что файл не записался

~/PoC> mkdir output_directory
~/PoC> 7z l archive.zip 

7-Zip [64] 17.04 : Copyright (c) 1999-2021 Igor Pavlov : 2017-08-28
p7zip Version 17.04 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs LE)

Scanning the drive for archives:
1 file, 171 bytes (1 KiB)

Listing archive: archive.zip

--
Path = archive.zip
Type = zip
Physical Size = 171

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2023-04-20 12:50:00 .....            7            7  SECRET_PASSWORD
------------------- ----- ------------ ------------  ------------------------
2023-04-20 12:50:00                  7            7  1 files

~/PoC> 7z x archive.zip -ooutput_directory -x!"S*"

7-Zip (z) 21.07 (arm64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-12-26
64-bit arm_v:8 locale=UTF-8 Threads:8, ASM

Scanning the drive for archives:
1 file, 171 bytes (1 KiB)

Extracting archive: archive.zip
--
Path = archive.zip
Type = zip
Physical Size = 171


No files to process
Everything is Ok

Files: 0
Size:       0
Compressed: 171
~/PoC> ls -la output_directory/
total 0
drwxr-xr-x  2 slonser  staff   64 Apr 21 01:47 ./
drwxr-xr-x  9 slonser  staff  288 Apr 21 01:47 ../

Как можно увидеть файл SECRET_PASSWORD не был записан.

Трюк с обходом

Для начала, нужно сделать маленькое отступление.

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

  1. При архивации: 7zip автоматически преобразует относительные пути, содержащие "../", удаляя из них нежелательные компоненты, чтобы предотвратить возможные проблемы при последующем извлечении файлов.

  2. При извлечении: 7zip проверяет пути файлов в архиве и игнорирует "../" в относительном пути. Таким образом, файлы с такими путями не будут извлечены вне директории распаковки, предотвращая потенциальные риски для безопасности.

Но из-за данного механизма косвенно получается возможным один способ обхода exclude правил.
Вернемся к ситуации из предыдущего раздела, но теперь используем специально заготовленный архив.

~/PoC>7z  x PoC.zip -ooutput_directory -x!"S*"

7-Zip (z) 21.07 (arm64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-12-26
 64-bit arm_v:8 locale=UTF-8 Threads:8, ASM

Scanning the drive for archives:
1 file, 177 bytes (1 KiB)

Extracting archive: PoC.zip
--
Path = PoC.zip
Type = zip
Physical Size = 177

Everything is Ok

Size:       7
Compressed: 177
~/PoC> ls output_directory/
SECRET_PASSWORD

Тут можно заметить, что файл в директорию записался, и думаю многие догадались почему, остальным предоставлю листинг архива:

~/PoC> ~/Downloads/7z2107-mac/7zz  l PoC.zip

7-Zip (z) 21.07 (arm64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-12-26
 64-bit arm_v:8 locale=UTF-8 Threads:8, ASM

Scanning the drive for archives:
1 file, 177 bytes (1 KiB)

Listing archive: PoC.zip

--
Path = PoC.zip
Type = zip
Physical Size = 177

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2023-04-20 12:50:00 .....            7            7  ../SECRET_PASSWORD
------------------- ----- ------------ ------------  ------------------------
2023-04-20 12:50:00                  7            7  1 files

Как можно заметить файл содержит "../" в названии, следовательно не подходит под регулярное выражение S*.

Это становиться возможным, потому что нормализация пути в архиве происходит уже после применения exclude правил.

Риски

Если при обходе exclude правил при разархивации происходит перезапись файла, это может привести к ряду рисков и проблем, включая:

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

  2. Внесение изменений в системные файлы: Если в результате обхода exclude правил перезаписываются критические системные файлы, это может привести к нарушению стабильности и функционирования операционной системы или приложений. В худшем случае это может вызвать полную неработоспособность системы и потребность в переустановке.

  3. Компрометация безопасности: Перезапись файлов может привести к установке вредоносного кода или изменению настроек безопасности, что, в свою очередь, может создать уязвимости, доступные для эксплуатации злоумышленниками.

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

Мысли разработчиков

Игорь Павлов (создатель 7zip) ответил, что файл ../../SECRET_PASSWORD хранится в сабдиректории, поэтому должен использоваться флаг -r

Я не согласен с этой позицией, потому что файл записывается на верхнем уровне директории. А так же если мы будем использовать -r, это нарушит концепт exclude только на верхнем уровне, потому что мы не сможем записать файл SECRET_PASSWORD в любой подкаталог.
Поэтому мне дали разрешение на публикацию этой информации в публичном поле:

Итоги

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

Для минимизации таких рисков, я советую использовать exclude правила только в рекурсивном режиме.

P.S.

Это моя первая статья на Хабре, наверное даже первая подобная статья в жизни, так что я уверен в том, что допустил некоторые ошибки, буду рад вашим комментариям!

Комментарии (3)


  1. VADemon
    24.04.2023 23:37

    Очень специфичная штуковина, интересно. Правильно ли я понимаю, проблема бы решилась добавлением отдельного ключа для full path exclude и relative path exclude? Чтобы не пришлось изворачиваться через -r?

    Мне описания -r не хватило для полного понимания, man 7z на зачаточном уровне, а на архаичную систему команд не хочется смотреть дольше четырех секунд.

    Это моя первая статья на Хабре, наверное даже первая подобная статья в жизни

    Оно видно, нету той сухой заносчивости, красками которой пестрит иной write-up от мнящих себя важными infosec компаний. Всё спокойно и четко. Но такой ли это 0-day? (по тегам)


    1. Slonser Автор
      24.04.2023 23:37

      Лично по моему мнению проблема бы решилась, если бы проверку на правила сделали на нормализованных путях. Добавление отдельных ключей, как показывает практика, лишь способствует тому, что люди будут их путать и использовать неправильно.
      Я не считаю это чем-то очень серьезным и заслуживающим названия "0-day", использовал этот тег лишь потому, что не видел упоминания данной техники на других ресурсах. В следующий раз обдумаю применение тегов более тщательно.


      1. VADemon
        24.04.2023 23:37

        Логично. Насчет тегов: я бы из "0day-vulnerability" просто вычленил vulnerability в отдельный тег (а сам его удалил, раз уже "0day" есть). А так, no sweat. Тут, дай Бог, чтобы одна десятая теги хоть чем бы релевантным заполняла :)