PHDays 9: разбор заданий AI CTF

Тема безопасности машинного обучения довольно хайповая последнее время и хотелось затронуть именно практическую ее сторону. А тут повод крутой — PHDays, где собираются самые разные специалисты из мира ИБ и есть возможность привлечь внимание к этой теме.

В общем-то мы сделали task-based CTF, с заданиями затрагивающих часть рисков безопасности применения техник машинного обучения.

fr8j4diu3gmmkvnxf5qqxwosewo.png

Что такое CTF???
Capture The Flag (CTF) — очень популярные соревнования по компьютерной безопасности (по популярности как kaggle-соревнования для датасаентистов). Есть два формата: тасковые (jeorpady) и сервисные (attack-defence). Мы делали тасковые.

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

В CTF традиционными категориями являются: web — веб-уязвимости, reverse — обратная разработка, crypto — криптография, stegano — стеганография, pwn — бинарная эксплуатация.

Команды (от 1 до n человек) решают задания и кто решит заданий на большее количество баллов — тот молодец.


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

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

figdy3kqntpoz2mhxnpv3xfgxa0.png

Сразу хотелось бы выразить огромную благодарность ребятам, без которых этот CTF не состоялся бы: @groke и @mostobriv. Крутейшие идеи, технические решения и деплой-пати в ночь перед стартом — что может быть прекрасней, когда это в потрясающей компании?! :)


pduij3j0i_tkfnjculfbufynurk.png

tiny.cc/6fj06y

Дан датасет из 3 391 картинок котиков и собачек.

as5jgbejjo1mql9qreqwppc9jze.png

Задание было отмечено как «Stegano». Задания на стегано подразумевают сокрытие какой-то информации. Казалось несложно догадаться, что котики и собачки — это что-то бинарное. Немного подумав можно предположить, что эта последовательность котиков и собачек может быть каким-то двоичным сообщением. Пусть допустим, котики будут 1, а собачки — 0. Если вдруг не получится, можно просто поменять местами. Далее находим обученную модель, которая классифицирует котиков и собачек. Примеров уроков по классификации котиков и собачек много, как и обученных моделей после них — можно найти обученные модели на гитхабе. Берем обученную модель, в крайнем случае обучаем сами. Предсказываем каждое изображение как 0 или 1. И эту последовательность «байт» переводим в строку.

Авторское решение можно посмотреть тут


Получаем текст, который содержит в себе флаг `AICTF{533m5_y0u_und3r574nd_4n1m4l5}`.

Однако почему-то несколько участников в разное время пытались сдать странный флаг со словом «Adopted». Не знаем откуда взяли, если вдруг участники пояснят, будет круто : D


ahkwag86u5v5cqk6rxc_v8xblfw.png

Сервис представлял из себя некоторый «блог», где каждый пользователь мог оставлять публичные и приватные записи. Так как функциональность была небольшая — было не трудно догадаться, что надо как-то достать приватную запись.

Было фактически только одно поле ввода — id записи.
Что делать?

Первое, что приходит на ум безопаснику — пробовать sql-инъекции. Однако сказано, что сервис защищен ИИ. И простую sql-injection посылать не получалось. Сервис на такую атаку отвечал «Hacking attempt!». Многие пытались сдавать это как флаг, но неужели думали, что все так просто?

Под капотом проверки была LSTM-сеть, которая анализировала id на предмет sql-injection. Однако, вход у LSTM должен быть фиксированной длины. Для простоты мы ограничили ее 20ью символами. Т.е логика была такая: берем запрос, если он больше 20 символов — обрезаем и оставшуюся часть проверяем, если меньше, то дополняем 0.

Собственно поэтому простые sql-injection сразу не срабатывали.
Однако шанс найти такой вектор, который бы сеть не видела и приняла за хороший запрос был.


q2thumpfbquscedzdlpk1cf5ptk.png

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

lowxgqpsyes69_u_m_szxbuc0aq.png

Файлы к таску доступны тут

Было дано несколько зашифрованных файлов. Среди них был pyc-файл, разреверсив который было очевидно, что там была функция по коду которой можно было понять, что все нужные файлы зашифрованы AES на ключе, который получен от байткода этой функции и еще одной внутри нее.

Варианта решения было два: распарсить pyc-файл и достать реализацию функций или сделать свой прокси модуль hashlib, который бы выводил свой аргумент и запустив его можно было получить ключ, чтобы затем расшифровать файлы и запустить QR-Reader, который распознавал предложенную картинку как флаг.

Подробное решение участника, занявшего 3 место можно почитать тут:


tze6tseaccvcsl5vejw7ydaf1uq.png

Сервис представлял из себя что-то вроде соревнования как на kaggle. Можно было регистрироваться, скачивать данные и загружать модельки, они тестировались на приватных данных и результат заносился на скорборд.

И кажется цель очевидна — набрать 1.0 точности.

Сложно ли было? Невозможно : D

Данные были сгенерированы рандомно и, конечно, подразумевалось, что такую точность необходимо было набрать каким-то другим образом. Сервис принимал модельки в формате .pickle. И кажется, что уже всем известно, но оказывается не всем, что через pickle можно получить RCE, а что может быть хуже?

Решение Никиты (konodyuk)


Собственно это и надо было сделать! Получив удаленный доступ к серверу, можно было скачать данные, на которых тестировалось решение, переобучить модель и получить 1.0 точности и вместе с этим флаг.
xopzosoyjcpwvl4eopndieyd--u.png

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

lieygxshmr1ecyldaceexqg8ty0.jpeg

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

-puisg2vdp89dkyujlk4jwr1dko.png

Где тут флаг?

Кажется, что вполне привычно встретить на CTF банальные уязвимости — в этот раз это был Image Tragick. Однако догадались немногие или заэксплуатировали не все, кто пытался.


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

ymmnb4-hqjzawewcod6exshjje4.png

Файлы к таску можно посмотреть тут

Система принимает байткод питона и исполняет у себя. Но, конечно, просто так делать не будет, так как есть «ИИ». Он проверяет версию питона и не допускает «неправильную». Если код проходил проверку, то запускался на сервере —, а значит можно было получить много информации.

Байткод, который дает интерпритатор, можно было разбавить нопами, и нейросеть, которая проверяла пропустила бы (тоже была LSTM), или еще можно было в конец дописать кучу мусора.

Далее, когда умеешь исполнять питоновский код, можно было обнаружить на сервере бинарь `flag_reader`, который запускался от рута. В бинаре была уязвимость форматной строки, через которую можно было прочитать флаг.

Решение Никиты (konodyuk) также можно почитать тут


К концу конкурса 130 зарегистрировавшихся, 14 сдали хотя бы один флаг, а 5 из 6 заданий были решены — значит с балансировкой сложных и легких тасков у нас получилось.
Учитывая, что мы не сильно распространяли информацию, так как делали впервые и были бы не готовы к большой нагрузке, все равно считаем супер удачно проведенным соревнованием.

Призовые места заняли:

  • 1 место — silent
  • 2 место — kurmur
  • 3 место — konodyuk


Победителей наградили в конце второго дня PHDays с почестями и крутыми призами: AWS DeepLens, Coral Dev Board и рюкзак с лого конференции.

Ребята, которые обычно играют в классический CTF и теперь увлекаются машинным обучением, оценили наш конкурс, поэтому надеемся в следующий раз присоединятся и датасаентисты, которые интересуются безопасностью.

© Habrahabr.ru