Урок 3. Как работать с архивами и не испортить исходные данные

Смотрим содержимое ZIP, извлекаем нужные файлы в отдельную папку и считаем контрольную сумму.

В олимпиадной задаче часто выдают ZIP с несколькими журналами, изображениями или ещё одним архивом внутри. Главная опасность здесь не в сложной теории. Можно случайно посчитать контрольную сумму не того файла, потерять путь внутри архива или смешать исходные данные с результатами своей работы.

В этом уроке нужен простой порядок:

  1. сохранить выданный файл без изменений;
  2. посмотреть содержимое архива;
  3. извлекать данные только в отдельную папку;
  4. записывать, к какому именно файлу относится найденный ответ.

Все команды ниже доступны в обычной Kali Linux. Для учебного архива достаточно штатных возможностей unzip.

Исходник и рабочая копия

Создайте для задачи отдельную папку:

case/
├── original/    # то, что выдали
├── work/        # распакованные копии
└── notes.txt    # ответы и места, где они найдены

Файл в original/ не редактируют и не распаковывают поверх него. Это полезно не только криминалисту. Если вы ошиблись, всегда можно удалить work/ и начать заново, не скачивая материал ещё раз.

Пример подготовки:

mkdir -p case/original case/work
cp l3_workspace.zip case/original/

Команда cp создаёт копию. После этого все действия выполняются с файлом из case/original/, а результаты появляются в case/work/.

Сначала список, потом распаковка

Чтобы увидеть содержимое ZIP, не извлекая его:

unzip -l case/original/l3_workspace.zip

Ключ -l означает list — список. Вы увидите имена, размеры и время файлов. Более компактный вариант, который печатает только имена:

unzip -Z1 case/original/l3_workspace.zip

Список сразу отвечает на несколько вопросов:

  • есть ли внутри ещё один архив;
  • в каких папках лежат журналы и изображения;
  • совпадает ли имя из условия с реальным путём;
  • нет ли неожиданно огромного файла.

Проверить, что ZIP читается без ошибок, можно так:

unzip -t case/original/l3_workspace.zip

Это не извлекает данные, а только проверяет записи архива.

Распаковка в отдельную папку

После просмотра списка распакуйте внешний архив:

unzip case/original/l3_workspace.zip -d case/work/outer

В учебном наборе появится файл:

case/work/outer/original/evidence_bundle.zip

Обратите внимание: l3_workspace.zip и evidence_bundle.zip — два разных файла. У них разный размер, разное содержимое и разные контрольные суммы. Если вопрос просит SHA-256 внутреннего архива, сумма внешнего ZIP не подойдёт.

Если вопрос просит SHA-256 файла внутри архива, что нужно хешировать? · 4 б.

Зачем нужна SHA-256

SHA-256 — алгоритм контрольной суммы. Он превращает содержимое файла в строку из 64 шестнадцатеричных символов. Одинаковые файлы дают одинаковую строку; изменение хотя бы одного байта почти наверняка изменит результат.

На олимпиаде контрольная сумма встречается по двум причинам:

  • как точный ответ на вопрос;
  • как способ убедиться, что извлечена правильная копия.

Команда:

sha256sum case/work/outer/original/evidence_bundle.zip

Всегда читайте условие ещё раз перед запуском. Эти три команды считают суммы трёх разных объектов:

sha256sum case/original/l3_workspace.zip
sha256sum case/work/outer/original/evidence_bundle.zip
sha256sum case/work/inner/reports/day.csv

Все результаты могут быть корректными, но правильным ответом будет только сумма указанного в вопросе файла.

Как работать с архивом внутри архива

Внутренний ZIP тоже сначала просматривают:

unzip -l case/work/outer/original/evidence_bundle.zip

Если нужно распаковать его целиком:

unzip case/work/outer/original/evidence_bundle.zip -d case/work/inner

Если нужен один небольшой текстовый файл, весь архив можно не извлекать. Команда unzip -p выводит содержимое выбранного файла на экран:

unzip -p evidence_bundle.zip reports/day.csv

Для поиска текста по небольшим CSV и TXT удобно перебрать только такие имена:

for name in $(unzip -Z1 evidence_bundle.zip | grep -E '\.(csv|txt|ini)$'); do
  unzip -p evidence_bundle.zip "$name" | grep -H 'Case-ID' /dev/stdin && echo "файл: $name"
done

В реальной задаче имена могут содержать пробелы, поэтому такой короткий цикл подходит только для аккуратно подготовленного учебного набора. Более надёжный путь — распаковать проверенный архив в отдельную папку и искать через Visual Studio Code или grep -R.

Как посчитать файлы по списку архива

Задача может попросить число файлов внутри ZIP. В учебном архиве достаточно:

unzip -Z1 evidence_bundle.zip | grep -v '/$' | wc -l

Команда выполняется слева направо:

  1. unzip -Z1 печатает имена;
  2. grep -v '/$' убирает строки, заканчивающиеся на /, то есть каталоги;
  3. wc -l считает оставшиеся строки.

Получается короткая последовательность готовых операций: вывести имена, убрать каталоги и посчитать оставшиеся строки.

Что полезно сделать до распаковки ZIP? · 4 б.

Что делать с незнакомым архивом

Архивы курса созданы нами и проходят автоматическую проверку. В произвольной задаче всё равно соблюдайте несколько правил:

  • не распаковывайте ZIP прямо в домашнюю папку;
  • сначала выполните unzip -l и unzip -t;
  • используйте новую пустую папку;
  • не запускайте программы, найденные внутри;
  • если видите путь вроде ../../file или абсолютный путь /etc/..., остановитесь и не распаковывайте архив обычной командой.

Для небольших архивов из олимпиадных заданий этих правил достаточно. Глубокая проверка символических ссылок и архивных бомб относится к отдельной задаче разработки безопасных систем.

Разбор учебного набора

В l3_workspace.zip есть внешний README.txt и внутренний original/evidence_bundle.zip. Самостоятельные задания проверяют три разных действия:

  • C7 — посчитать SHA-256 именно внутреннего ZIP;
  • C8 — найти полный путь файла с заданным Case-ID;
  • C9 — посчитать обычные файлы внутри внутреннего ZIP.

Не переносите пути и числа из примеров выше. Они показаны только для объяснения команд; в задании нужно прочитать реальный список.

Реальная задача ВСОШ: образ диска Pinecraft

В задаче заключительного этапа ВСОШ 2025–2026 для 9 класса выдавался pinecraft_backup.img — образ диска взломанного Minecraft-сервера. Открыть исходный разбор задачи.

Подробный разбор: журнал сервера и удалённый пароль

Участнику нужно было найти IP-адрес источника доступа и пароль из удалённого резервного файла администратора.

Сначала команда file определяла тип объекта:

file pinecraft_backup.img

Образ распознавался как файловая система ext4. В авторском решении его подключали только для чтения:

sudo mkdir -p /mnt/pinecraft
sudo mount -o ro,loop pinecraft_backup.img /mnt/pinecraft

Параметр ro означает read only — только чтение. Он нужен, чтобы операционная система не записала служебные данные внутрь исследуемого образа. После анализа подключение снимают:

sudo umount /mnt/pinecraft

В каталоге /minecraft находились настройки сервера, мир, плагины и logs/server.log. В журнале была строка несанкционированного доступа с IP:

10.13.37.42

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

strings pinecraft_backup.img | grep -iE 'secret|backup|password'

Так находился фрагмент удалённого admin_backup.txt с паролем:

d3l3t3d_but_n0t_g0n3

Важно понимать границу метода. strings нашёл текст, но не восстановил имя файла, время удаления и место в файловой системе. Для ответа этой задачи строки было достаточно; полное восстановление удалённых файлов изучается позже.

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

Исходник остаётся точкой отсчёта

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

В следующем наборе одного аккуратного пути будет недостаточно: имена файлов намеренно не совпадут с их содержимым.

Скачать практический набор: l3_workspace.zip
C7

C7. Отпечаток исходника

10 б.

Распакуйте внешний учебный набор в рабочий каталог. Сдайте SHA-256 файла original/evidence_bundle.zip строчными буквами.

C8

C8. Список до распаковки

12 б.

Не распаковывая весь внутренний ZIP, найдите файл со строкой Case-ID: CASE-731. Сдайте полный путь этого файла внутри архива.

C9

C9. Сколько файлов внутри

14 б.

Сколько обычных файлов находится внутри original/evidence_bundle.zip? Каталоги, если они есть, не считайте. Сдайте одно целое число.