- PVSM.RU - https://www.pvsm.ru -
На PHDays 9 мы решили рассмотреть с практической стороны модную сегодня тему безопасности машинного обучения. Для этого мы создали онлайн-конкурс AI CTF (capture the flag) формата task-based, с заданиями, посвященными безопасности применения техник искусственного интеллекта.
Напомним, что тасковые CTF-соревнования схожи с форматом «Своей игры»: есть набор заданий, разбитых по категориям с разной стоимостью. Традиционные для CTF темы: веб-уязвимости, обратная разработка, криптография, стеганография и бинарная эксплуатация. Победителем становится команда (с любым количеством участников, от одного), которая наберет наибольшее количество баллов.
AI CTF начался в первый день PHDays и длился чуть больше суток. Подразумевалось, что каждый участник будет играть за себя. Несмотря на то, что это был онлайн-конкурс, часть участников находилась на площадке форума, и все могли познакомиться друг с другом. В целом задания можно было решить за пару часов, они не требовали больших вычислительных ресурсов. Тем не менее трудные задания тоже были — не всем же выигрывать :D
Конкурс включал шесть заданий (седьмое было фановым). В этой статье мы подробно разберем, как их можно было выполнить.

Хотим поблагодарить @groke [2] и @mostobriv [3] — без их крутейших идей и технических решений этот CTF не состоялся бы. И что может быть прекрасней деплой-пати в ночь перед стартом в потрясающей компании?!

Участникам был дан датасет из 3 391 картинки котиков и собачек: tiny.cc/6fj06y [4].

Задание относилось к категории «стеганография», а значит, подразумевало сокрытие какой-то информации. Изучив изображения, несложно догадаться, что котики и собачки — это что-то бинарное. Можно было предположить, что последовательность котиков и собачек соответствует двоичному сообщению. Допустим, что котики — 1, а собачки — 0. (Если вдруг не получится, можно просто поменять местами.) Далее нужно было найти обученную модель, которая классифицирует котиков и собачек. В крайнем случае — обучить самостоятельно. Примеров уроков по классификации котиков и собачек много, как и обученных моделей, — их можно найти на GitHub. Далее нужно представить каждое изображение как 0 или 1 и последовательность байт перевести в строку.
Должен получиться текст, который содержит в себе флаг: `AICTF{533m5_y0u_und3r574nd_4n1m4l5}`.
Во время конкурса несколько участников в разное время пытались сдать флаг со словом adopted. Поначалу мы не могли понять почему, но потом оказалось, что в датасете была картинка со словом adopted, и участники, видимо, не поняв смысл стеганографии, решили отправлять это слово как ответ.
Решение, предложенное автором задания, опубликовано на GitHub [5].

Задание из категории «веб-уязвимости». Сервис представлял собой блог, на котором каждый пользователь мог оставлять публичные и приватные записи. Так как функциональность была небольшая, было нетрудно догадаться, что надо достать приватную запись.
Было фактически только одно поле ввода — id записи. Что делать?
Первое, что может прийти на ум безопаснику, — пробовать SQL-инъекции. Однако в задании сказано, что сервис защищен ИИ, поэтому простую SQL-инъекцию посылать не получалось. Сервис на такую атаку отвечал: «Hacking attempt!». Многие пытались сдавать это как флаг, но все было не так просто.
Под капотом проверки была LSTM-сеть, которая анализировала id на предмет SQL Injection. Однако вход у LSTM должен быть фиксированной длины. Для простоты мы ограничили ее двадцатью символами. Нужно было взять запрос: если он больше 20 символов — обрезать и проверить оставшуюся часть; если меньше, то дополнить 0. Поэтому простые SQL-инъекции сразу не срабатывали. Однако шанс найти такой вектор, который бы сеть не видела и приняла за легитимный запрос, был.

Необходимо было распознать QR-код:

Было дано несколько зашифрованных файлов (доступны [6] на Google-диске). Среди них был .pyc-файл. Если его разреверсить, то по коду функции можно было понять, что все нужные файлы зашифрованы AES на ключе, который получен от байт-кода этой функции и еще одной внутри нее.
Было два варианта решения. Первый: распарсить .pyc-файл и достать реализацию функции. Второй: сделать свой прокси-модуль hashlib — он бы выводил свой аргумент, запустив который, можно было получить ключ для расшифровки файлов. После запустить QR-ридер для распознавания предложенной картинки как флаг.
Приводим подробное решение участника [7], который занял третье место.

Сервис представлял собой соревнования как на Kaggle: можно было регистрироваться, скачивать данные и загружать модельки, они тестировались на приватных данных и результат заносился на скорборд. Цель очевидна — набрать 1.0 точности.
Сложно ли было? Невозможно :D
Данные были сгенерированы рандомно и, конечно, подразумевалось, что тратить время на обучение модели не стоило, — нужно было набрать точность другим способом. Сервис принимал модельки в формате PICKLE. И кажется, уже всем известно, что через Pickle можно получить RCE [8] (а что может быть хуже?!). Но, как выяснилось, не всем. А это и надо было сделать!
Получив удаленный доступ к серверу, можно было скачать данные, на которых тестировалось решение, переобучить модель и получить 1.0 точности и вместе с этим флаг.
На GitHub опубликовано решение участника, занявшего призовое место.

Как можно догадаться по названию, сервис что-то делает с изображениями. Приложение предлагало загрузить фотографию.

В ответ присылалось изображение с измененным стилем и лого соревнования.

Где тут флаг? Кажется, что вполне привычно встретить на CTF банальные уязвимости. В этот раз это был ImageTragick [9]. Однако догадались немногие, а из тех, кто понял, не все смогли ее эксплуатировать.
Это задача осталась нерешенной. Хотя после разговора с участниками, выяснилось, что они были очень близки к ответу.

Файлы к заданию доступны [10] на Google-диске.
Система принимала байт-код на Python и исполняла его у себя. Конечно, просто так это делать не будет, так как есть ИИ. Он проверяет версию Python: если код проходил проверку, то запускался на сервере. А значит, можно было получить много информации.
Байт-код, который дает интерпретатор, можно было разбавить нопами, и нейросеть, которая проверяла, пропустила бы (тоже была LSTM).
Далее, если умеешь исполнять питоновский код, можно было обнаружить на сервере бинарный файл flag_reader, который запускался от рута. В файле была уязвимость форматной строки, через которую можно было прочитать флаг.
Решение одного из участников можно почитать на GitHub [11].
К концу конкурса зарегистрировались 130 участников, 14 из них сдали хотя бы один флаг, а 5 из 6 заданий были решены.
Призовые места заняли:
Победителей наградили в конце второго дня PHDays с почестями и крутыми призами: AWS DeepLens, Coral Dev Board и рюкзак с лого конференции.
Ребята, которые обычно играют в классический CTF и теперь увлекаются машинным обучением, оценили наш конкурс, поэтому надеемся в следующий раз присоединятся и специалисты по анализу данных, которые интересуются безопасностью.
Автор: ptsecurity
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/321432
Ссылки в тексте:
[1] Image: https://habr.com/ru/company/pt/blog/456934/
[2] groke: https://twitter.com/groke1105
[3] mostobriv: https://twitter.com/mostobriv
[4] tiny.cc/6fj06y: http://tiny.cc/6fj06y
[5] опубликовано на GitHub: https://gist.github.com/amurzina/b9b825352be2cbc8baedcf6fb1365b89#file-aww_solver-py
[6] доступны: https://drive.google.com/file/d/1teib3lZZU1bOvNuvnx4PuDYAqgyL1rCj/view
[7] решение участника: https://gist.github.com/konodyuk/c604846e8dce8873971316706329ce95#file-aictf_new_edge_qr_reader-ipynb
[8] RCE: https://intoli.com/blog/dangerous-pickles/
[9] ImageTragick: https://imagetragick.com/
[10] доступны: https://drive.google.com/drive/folders/1uQ15OVFTyaZAwTVhPQKpUAL65MRgjv32
[11] почитать на GitHub: https://gist.github.com/konodyuk/ff0945f0b21c97d80787dc8873c989ff
[12] Источник: https://habr.com/ru/post/456934/?utm_campaign=456934&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.