Опасные архивы: символические ссылки и уязвимости Zip Slip в Golang
Пока обновлял раздел курса про поиск и эксплуатацию уязвимостей directory traversal, наткнулся на интересное развитие старой уязвимости Zip Slip. Атакующий может загрузить специально сформированный архив (tar, jar, war, cpio, apk, rar, 7z), и если модуль, отвечающий за его распаковку, не проверяет имена файлов, атакующий может выйти за пределы каталога, в который производится распаковка.
Об этой проблеме известно с 2018 года, но уязвимых библиотек по-прежнему много. А вот об интересной особенности процесса распаковки в Golang известно совсем недавно. Запакуем в tar-архив два файла с одинаковым именем:
$ tar -tvf alice.tar
lrw------- 0 0 0 0 1 Jan 1970 rabbit_hole -> /tmp/wonderland
-rw-r--r-- 0 0 0 39 1 Jan 1970 rabbit_hole
Первый файл является символической ссылкой, а второй — текстовым файлом.
Какое поведение мы ожидаем от распаковки? При распаковке файл с символической ссылкой должен быть заменен текстовым файлом.
На самом деле, оказалось, что если распаковка происходит с помощью Golang-функции os.Create(), то содержимое файла заменяется на содержимое символической ссылки. Это значит, что атакующий может создать произвольный файл в любом месте системы.
Причина такого поведения заключается в некорректной обработке символических ссылок в при распаковке tar-архивов. Поэтому защищаем свои ресурсы от “зараженных” архивов. Инструмент для проверки поможет.
*makrushin