VolgaCTF глазами участника

    image
    15 апреля завершился отборочный этап соревнований в области информационной безопасности VolgaCTF-2012, в котором принимали участие 29 команд из различных городов Приволжского Федерального округа. Командам давалось 48 часов, на решение задач в областях:

    • Crypto –криптографические задачи;
    • Web – разнообразные веб-уязвимости;
    • Reverse engineering –обратная разработка программ;
    • StegaSic (Steganography & Forensic) – стеганография и исследования в области компьютерных преступлений;
    • PPC (Professional programming and coding) – различные задачи на программирование;
    • Joy – задачи на общую эрудицию в области информационной безопасности;
    • Blackbox Admin – задачи на администрирование сетей;

    Хочется поделиться с вами своими впечатлениями и написать как выглядят такие соревнования именно со стороны участника.

    В первую очередь, выражаю огромную благодарность организаторам этого конкурса и админам за шикарные задания, которые не были простыми, но были интересными.
    В подобного рода соревнованиях наша команда участвовала впервые. Начало соревнований было задержано на час, за это время мы успели расположится поудобнее, настроить компьютеры и немного настроить себя различными шутками и разговорами ни о чем.
    Админами был поднят VPN сервер, розданы ключи для подключения командам и игра началась!

    13.04 19:00
    Командам вручили внутренний и внешний адрес сайта с заданиями. Мы распределили задания внутри команды и начали работать.

    Уровень 100 по областям сильно различался по сложности. Два задания были решены сходу:
    1) Была дана html страница с большой таблицей. Каждая ячейка таблицы содержала свой цвет, после небольшой игры с css, была получена картинка с островом, перевели в JPG, загрузили в Google и нашли название острова, которое оказалось ключом
    2)Нам прислали архив, в котором хранились фотографии известных пиратов и хакеров, необходимо было узнать их полные имена и отправить организаторам. С помощью Google и небольшой работы с графическим редактором быстро нашли.

    13.04 19:20
    Гораздо более интересными оказались задачи на нахождение и эксплуатацию уязвимостей в web сайтах. Первой мишенью был пиратский блог, рассказывающий о рангах пиратского братства. Уже через пятнадцать минут команды соперники внедрили код скрывающий содержимое некоторых частей страницы. Это дало нам информации о наличии XSS уязвимостей. Позднее мы заметили, что блоги регулярно обновлялись, добавлялись новые топики. Хотя скорее всего информацию обновляла программа (как нам казалось) решили попробовать эксплуатировать XSS уязвимость и стандартными методами получить cookie пользователя с правами администратора. На поднятом в интернете снифере отображалась только информация о участниках других команд, но мы не сдались. Перенастроили XSS на IP адрес внутри VPN и анализатор трафика обнаружил попытку подключения администратора. Ключ был взят!

    Менее успешно решались задачи на криптографию, реверс, профессиональное программирование (ppc), которое мы тут же окрестили коротким и простым словом «ппц».
    В задаче из области PPC ребята сразу узнали обратную польскую нотацию. Из — за большого объема работы начали писать программу обработчик не сразу, потребовалось достаточно много времени на разработку и отладку. Ответ получили лишь на следующий день.
    Не осилили казалось бы простую задачу на crypto100.

    13.04 20:30
    Получили классическое задание из области Joy.

    Не стали искать скрытый смысл и зашифрованные архивы, решили сначала попробовать сделать то, что просят на фотографии. Сфотографировались, отослали, заработали свои 200 баллов)Правда, пришлось немного пофотошопить — добавить пиратскую атрибутику, но результат получился отменным)
    Примерно в это же время решили задачу с Web200, где в robots.txt была оставлена ссылка на администраторскую.

    13.04 21:15
    К сожалению, ночью находиться в университете не разрешается, поэтому нашу команду попросили освободить помещение. Полные сил и боевого духа мы отправились на квартиру, чтобы там продолжить решать задачи.

    13.04 22:30
    Примерно в это время открыли первое задание на администрирование. В распоряжение был дан сервер. Открытых портов было больше тысячи. Начали искать зацепки. Запрос на 1000 порт возвращал всегда «P». Запрос на 1001 порт после обращения на 1000 порт всегда «i». Аналогичная ситуация была на 1002, 1003, и т.д. портах. Соединенные подряд буквы с 1000 по 1005 порт давали слово «Pirat». Запрос на 1000 порт сбрасывал порядок следования символов. При большой задержке между обращениями на соседние порты алгоритм не работал.

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

    13.04 23:45
    Теперь мне хотелось бы рассказать о действительно интересных и оригинальных задачах из области web.
    3 задание ссылалось на сайт пиратского бара.

    Беглый просмотр сайта не дал видимых уязвимостей. Глаз остановился на скрытом комментарии в html коде.
    Сайт адаптирован для пиратского браузера
    Ведется учет пользователей

    Поиск в интернете «Пиратского браузера» и подстановка в User — Agent всех возможных названий не дал результата. Но вскоре обнаружили SQL-injection в этом поле. Казалось бы ничего сложного, но это была Insert injection. Интересным оказалось то, что команды типа SELECT,OR,WHERE,ORDER,GROUP,AND вырезались, приходилось запрос типа

    SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_NAME LIKE 'k%'

    приводить к виду

    SELSELECTECT TABLE_NAME FRFROMOM infoORrmation_schema.tables WHWHEREERE TABLE_NAME LIKE 'k%'

    Что еще было интересным, параметр key в COOKIE, который всегда занулялся.
    Результат выполнения нигде не отображался (хотя может быть мы не нашли), просто записывался в БД. INTO OUTFILE и другие методы не работали, пришлось прибегать к нестандартным. Решение было отложено до утра.

    Первым что пришло в голову, приводить к ошибке скрипт в случаях, когда количество строк удовлетворяющих условию подзапроса равно нулю. Первым попробовал разделить действительное число на COUNT(*), но в случаях когда COUNT(*) был равен нулю, MySQL это спокойно проглатывал.
    Поиск MySQL — функций, в которых должны быть обязательные параметры результата не дал.
    Зато получилось использовать так называемую timing attack. Запрос для поиска названия таблицы в которой мог бы быть ключ был преобразован к виду.

    pirat'),((SELSELECTECT if(COUNT(*)!=0,BENCHMARK(100000000000,NOW()),1) FRFROMOM infoorrmation_schema.tables WHERE TABLE_NAME LIKE 'k%'))#

    Грубо говоря, если не находится ни одной строчки удовлетворяющей условию, сайт открывается медленно, если есть, то быстро. Медленную скорость работы обеспечивает функция BENCHMARK 10000000000 раз повторяющая типовую операцию.

    От поиска через LIKE сначала отказался в сторону SUBSTR(TABLE_NAME,1,1)>'a'. Перебирать по одной букве было долго, так можно было задавать диапазон. (прим. Можно было реализовать скрипт который автоматизирует эти действия) После подбора нескольких первых букв названия таблицы вспомнил о существовании функции REGEXP(), с помощью которой можно задавать поиск регулярными выражениями, подбор букв стал гораздо проще. Аналогичными действиями нашел помимо названия таблицы с флагом, название поля с флагом и сам флаг, в общей сложности ручным бинарным поиском пришлось перебрать около 25 символов.
    Найденным ключем оказалось слово 'elpirata', которое не подходило как ответ к заданию. Но установка в COOKIE переменной key с этим словом позволило получить ключ от задания.

    14.04 02:00
    После не первой кружки кофе командой была решена задача с поиском exploit'a в PDF файле, потрачен не один час на поиск ключа в wav файле (который оказался на краю спектра сигнала), расшифрована вот такая вот gif-ка:

    Которая при определенных условиях сигнальными флагами передавала сообщение содержащее ключ к заданию.
    В одном из заданий, содержащем много текста в графическом JPEG-файле размером 35 МБ увидели фонтан.
    14.04 05:00
    В том же задании, увидели пальму, поняли что пора идти спать…
    Вот это задание…

    14.04 11:00
    Пришли в университет и начали работать по ранее незаконченным заданиям.
    14.04 15:00
    Мы получили интересное задание из области WEB 400 уровня. Для поиска уязвимостей была подготовлена пара сайтов.

    На первом сервере был сайт посвященный сокровищам, второй содержал в себе сайт веб-студии. Перебором входных параметров была обнаружена слепая SQL-injection, в которой невозможно было использовать команду UNION. Случайным перебором известных слов нашлась таблица user, с полями id и user содержащей 1 запись.

    В отличии от предыдущего задания не работала функция REGEXP и нами был разработан скрипт перебирающий буквы в LIKE.
    Итоговый запрос к БД:
    0 OR (SELECT user from user where user like 'adm%') LIKE '%'
    Вместо слова adm в запросе выше скрипт подставлял различные комбинации букв, в случае нахождения пользователя начинающегося на заданную комбинацию, содержимое на странице выводилось.
    Найдя пользователя были слегка удивлены. Ник оказался postgres. Логично было предположить, что использовалась СУБД PostgresSQL.
    Чтение документации по данной СУБД, помогло нам найти таблицу заменяющую таблицу в information_schema в mysql, а с ее помощью имя поля таблицы user, содержащее пароль. Данный пароль хранился в md5, после расшифровки получалось 16 символьное postgrespostgres. К панели администратора сайта данный логин не подошел, что ввело в ступор. Панель управления БД на удаленном сервере не нашли, доступ из вне был закрыт. Достаточно обидно было иметь логин от БД, но невозможность к ней подключится.

    Стали подбирать названия таблиц и нашли таблицу administrators, содержащую уже сам логин от панели администратора сайта. В панели администратора нас ждал исходный код пары страниц сайта, доступ к которому необходимо было получить. На этих страницах была возможность читать функцией fread файлы заданные в _GET если знать к ним адрес. Была скрытая ссылка на папку, открытую для листинга из браузера и не содержащую файлов.

    Перебрали и просмотрели все стандартные папки конфигураций для unix систем, пробовали получить доступ к .bash_history и access_log, но безрезультатно. К счастью, вскоре обнаружили файл .htaccess в скрытой папке. В нем стояло правило на запрет отображения файла с флагом в листинге директории. Загрузка скрытых файлов отобразила зашифрованный JavaScript код. Начали расстраиваться что задание затянется, но через минуту на странице выполнился alert, содержащий флаг от задания.
    На все задание ушло 5 часов.

    Увидев в web500 задание с basic authorization при входе на сайт, решили отложить.


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

    14.04 20:00
    Наша команда лидировала, уставшие разошлись домой. Решили хорошо выспаться, хотя за ночь кто-то все же выполнил ряд задач.

    15.04 11:00
    В последний день решили всего две задачи 5 уровня, за которые давалось больше всего баллов.
    Обе задачи были интересными, поэтому хотелось бы о них подробно рассказать.

    Задача web500, отложенная вчера поддалась. Замечено, что если отправить POST данные на файл index.php, то страница отдавалась.



    Интуиция говорила, что просто не будет. Ни о каких распространенных уязвимостях речи быть не может. Не открывшаяся картинка, оказалась base64 закодированной png улыбающегося troll-face пирата. Поиск похожих картинок дал картинку идентичного размера холста, но другого размера на диске. Поиск скрытой информации в файле не дал результата.
    Немного отчаявшись вбил в адресную строку адрес /index.php.bak и получил код исходной страницы, что скорее расстроило, ведь он был неплохо обфусцирован.

    Глаза боятся, а руки делают… Расшифровал.
    	function __autoload($classname) {
    		$classpath = './inc/class/'.$classname.'.php';
    		if(file_exists($classpath))
    			include $classpath;
    	}
    	
    	
    
    	require_once('inc/config.php');
    	echo '<!DOCTYPE html><center><form method="POST"><input name="login" type="text"><input name="password" type="text"><br><input type="submit"></form></center>';
    	if(isset($_POST['login'],$_POST['password'])) {
    		// TODO
    		echo underconstruction();
    	} elseif(isset($_COOKIE['auth'])) {
    		$auth = unserialize((string)$_COOKIE['auth']);
    		if(isset($auth['login'],$auth['password'],$auth['name']) and ($auth['login'] === 'pirate') and ($auth['password'] === 'pirate1')) {
    			echo "Привет, {$auth['name']}!";
    		} else {
    			echo "<center>Ты не пройдешь, пират!</center>";
    		}
    	}
    

    Внимательный читатель заметит уязвимую связку строки echo «Привет, {$auth['name']}!»; и __autoload'а

    Вскоре был написан скрипт, который подготавливал данные сохранения в cookie, после unserialize которых в переменной $auth['name'] находился объект неизвестного класса. Это вызывало функцию autoload, и выполнение уязвимости типа php-injection.

    $value=new arrayObject();
    $value->offsetSet('login','pirate');
    $value->offsetSet('password','pirate1');
    $value->offsetSet('name',new index);
    $value=serialize($value);
    echo 'auth='.urlencode($value).';';
    

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

    Обрадовал и придал сил класс Flag, который говорил, что осталось еще немного.
    <?php
    	class Flag {
    		public static $flag = "FLAG";
    
    		public function getFlags() {
    			return array(self::$flag);
    		}
    	}
    ?>
    

    Исследование других классов позволило выявить еще уязвимости.
    В частности важным оказалось то, что класс textbox содержит функцию
                    function __toString() {
                            return $this->obj->printObj();
                    }
    

    Object содержит функцию
                  public function printObj() {
                            return serialize($this);
                    }
    

    User содержит функцию
                     public function __sleep() {
                            return $this->login->{$this->password}();
                    }
    

    В итоге для передачи скрипту была составлена конструкция, вернувшая ключ. (прим. на самом деле в классе user нашли ошибку в названии функции __contuct() и до исправления разработчиками не работало ;)
    $value->offsetSet('name',new Textbox(new Object(new User(new Flag,'getFlags'))));
    

    На все задание ушло 7 часов.

    Параллельно нам другая часть команды нашла решение к оригинальному заданию Joy500.
    Скрипт выбирал случайных девушек с сайта vk.com. Участники команды должны были попросить их зарегистрироваться на сайте, разработанном для конкурса.
    Вроде бы ничего сложного,

    Смотрим сайт, на который необходимо заманивать, видим окно:

    Потом это:

    И сам сайт:

    На фоне играет зловещая музыка, перед регистрацией нужно подождать 333 секунды. Все это время выходят модальные окна.В общем сатанинский сайтик) Не так — то просто было уговорить незнакомых девушек зарегистрироваться.

    На этом закончу рассказ о VolgaCTF. Наша команда победила с хорошим отрывом, получила много опыта, получила путевку в Самару на очный тур лето. А еще мы развели админов на классные футболки.
    Командная фотография в ответ на Joy200.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 11

      +2
      YARRR, в мои студенческий годы такого не было :(
        +1
        Всё, пойду на вышку — убедили)
          +3
          Отличный пост, спасибо, все верно подмечено. =)
          Наша команда также участвовала в VolgaCTF этого года, сначала набрала неплохой ход, но потом на нас, видимо, сказалась усталость.
          Из нюансов игры нашей команды: четыре участника, включая меня, два дня жили у меня дома, остальные играли у себя, общение шло через Skype.
          Если сравнивать с VolgaCTF прошлого года, то уровень организации стал очень высоким, за что отдельное спасибо команде Koibasta из Самарского Государственного Аэрокосмического Университета.
          Ну а команде rm -rf удачи в финале =)
            0
            в Encounter такие бы задания…
              +1
              Тоже участвовал в VolgaCTF. Очень понравились задания, но к сожалению в топ-10 не смогли пробиться по тех. причинам(
              Относительно заданий:
              1) Я теперь знаю, что надо прокачивать скилл в реверс инжениринг ибо там совсем глухо(хотя видно что у всех глухо)
              2) Кто-нибудь сделал задание admin500? А то Королева, пчелы, хокку- очень заманчиво :D
              3) И вообще всем Дас Капитал!
                +1
                В реверсе там всё было не так сложно, проблема была больше в математике. Первое задание — тривиальный кейчек под linux, навыков отладки под linux не было — выдрал весь код и собрал под win. int 80h ручками обходить пришло и подкладывать значения на угад. В конце концов приходим к сравнению ответа и какой-то строки, сгенерированной на основе ввода.
                Вторая задача была — обратить Алгоритм. Сам Алгоритм запускался в несколько потоков, вычисления велись на fpu. Алгоритм разбирался легко, с обращением были проблемы. Использовались 64битные вещественные числа, надо назвать такое входное вещественное число, которое после работы алгоритма даст числа, последние 32бита которых будут соответствовать заранее подготовленному выходу (давался в задании).
                Третья — разобрать приложение под iphone со всеми вытекающими. Надо знать arm.
                  0
                  С третьей накосячила наша команда) У нас был разработчик под iPhone :) И как — то пропустили задание)
                    +1
                    Там мало просто девелопить под iphone, там надо знать arm, уметь дебажить приложение без сырков на эмуляторе или ещё как.
                +2
                Crypto100 было на работу с текстом. Дана книга, даны какие-то числа разделённые на 2 части, формат — число | блок из нескольких чисел, разделённых запятыми. Таких блоков было 3. Первое число — глава, остальные — порядковые номера слов в этих главах. Собираем слова, получаем фразу, гуглим, ответ.
                Crypto200 на угадывание шифра по входам и выходам. Угадывался достаточно легко, если внимательно следить за закономерностями.
                Crypto300 не успел, но там был пошифрованный PEшник, который собран известным линкером. И дана программа-шифратор. Шифровала xor, каждый складывала со случайным байтом, полученным с помощью регистр сдвига с линейной обратной связью. Надо было подобрать инициализирующую последовательность. Plaintext атака по началу PEшника подсказывала несколько первых байт, с которыми ксорили шифрованный файл.
                Crypto400 было на атаку Хастада, три сообщения, E=3, длина сообщения меньше длины ключа (1024), по китайской теореме об остатках находим p^E=n (m1*m2*m3), искомое сообщение p, m1,m2,m3 — ключи из сертификатов n — шифротекст.
                Crypto500 был на подписи с помощью эль-гамаля, решать не пробовал.
                  +1
                  Crypto200-да, там просто) Хотя сначала думали, что намудрили. После того как дали подсказку-поняли, что правильно мыслили и довели ее)
                  0
                  Эх, вот в массы бы такие квесты, меньше бы новостей было про всяких «хакеров» взломавших 100500+ сайтов.

                  Only users with full accounts can post comments. Log in, please.