ZeroNights hackquest
filed in Конкурсы on Nov.22, 2011
UPD 23/11/11: пока только описание WEB270 The Kirovsky Plant, CRYPTO170/190 METRO1/2, WEB100 The State Hermitage Museum
Совсем скоро откроет двери долгожданная конференция ZeroNights, где впервые в России в одном зале соберутся западные и отечественные эксперты ИБ. Именно эксперты, а не маркетологи, менеждеры, руководители и прочие важые люди.
В рамках анонса этой конференции мы провели конкурс HackQuest, который был доступен абсолютно всем через Интернет на английском языке. Сразу отмечу, что все задания до сих пор можно проходить и получать флаги, только их добавление заблокировано.
Прежде всего, отмечу плюсы и минусы организационной работы:
+ Впервые представлены задания на соц. инжерению (голосовое скайп общение и ICQ)
+ Множество заданий без ярковыраженного акцента на безопасность веб-приложений
+ Максимально приближенные к реальной жизни задания (поэтому и брута было так много)
- Не было объявлено точной даты окончания квеста заранее
- Соц. инженереия работала не 24/7 (что вполне себе отвечает реальной жизни)
- Не было ценных призов (нормальная практика всех анонсов разыгрывать только инвайты)
Не затягивая больше, перейду к описанию самих конкурсных заданий.
Описывать буду в порядке убывания сложности.
1. WEB270. The Kirovsky Plant (https://hackquest.zeronights.org/missions/kirovsky.php).
Задание расположено на примечательном месте – Кировский завод, где уже несколько раз проходил СС.
Первый этап – найти исходный код, ищется без труда с помощью логики и эрудиции – по адресу /kirovsky/auth.inc:
<?php
class auth {
public $attempt;
public function getRole($login,$pass){
if($login==='4DM1N' && $pass==='pa55w0rd'){
return true;
}else{
return false;
}
}
public function __destruct(){
buildXML($this->attempt);
}
}
class failed {
public $failed_count;
?>
Как видим, доступны логин/пароль и некий объект auth, с параметром attempt, который попадает в функцию buildXML(), исходника которой у нас уже нет. Вводим логин/пароль из исходника и радостно понимаем, что задание несколько обширнее, чем просто поиск файла. После авторизации в параметр $_COOKIE['admin_data_asdgwugq7gw7er6wqge7riqwgrqwe87or'] попадает значение 10.
Меняя это значение на 10-1, и проверяя затем 10a, понимаем, что теперь имеем дело с внедрением операторов СУБД, осложненного двумя факторами: во-первых одинарные кавычки вырезаются, во-вторых, внедрение полностью слепое (без вывода ошибок и самих данных в HTTP-ответе).
Использовалась СУБД SQLite (и в остальных квестах тоже, кстати), поэтому единственным возможным способом получить данные быол использование Time-based техники. Примеров оных под SQLite нет, на что и был расчет. Тут каждый придумывал сам, смысл только в том, чтобы построить конструкцию CASE WHEN THEN ELSE с логическим условием, которое вызывает отработку тормозящей функции/конструкции, когда результат проверки логики положительный/отрицательный.
Долго ли, коротко ли, получаем записи data из admins, которые имеют следующий вид:
i:10
Понимаем, что они проходят десериализацию и проводим вторую инъекция так, чтобы возвращаемое значение содержало нужным нам объект. Каким может быть этот объект? Только auth с параметром attempt, больше ведь ничего не доступно в исходниках.
После десериализации строка из attempt идет на вход XML парсерсу. Уязвимостей XML не много, собственно на серверной стороне можно набеятся только на XXE. Пробуем ее и о приближаемся к победе. Уязвимость дает чтение локальных файлов из директории ./kirovsky/.
O:4:”auth”:1:{s:7:”attempt”;s:62:”<!DOCTYPE asd [<!ENTITY dsa SYSTEM "./kirovsky/config.php">]>”}
Только через инъекцию без одинарных кавычек так просто не просунуть двойные. Надо использовать Escape chars и конкатенацию, ну это уже лирика.
Читаем сначала config.php, затем flag.blabla-antibrute.php, имя которого лежит в конфиге.
Все, флаг получен %)
2. CRYPTO170. The Subway (https://hackquest.zeronights.org/missions/metro.php).
Задание не очень-то на криптографию, скорее на общее понимание форматов и смекалку.
Имеем два билета на фотограциях и два дампа их электронного содержимого.
Прежде всего смотрим что у нас есть из информации на картинках – номер билета, дата и время продажи.
Ясно, что надо подделывать дату.
Начинаем битфлип и быстро получаем флаг (если проходите в первый деь публикации задания).
Если не в первый день публикации задания, то начинаем брутить по байту и чуть дольше получаем флаг.
3. CRYPTO190. Metro#2 (https://hackquest.zeronights.org/missions/metro2.php).
Работаем с билетами первого метро. Чтобы пройти второе надо понять их формат полностью.
Когда узнали где лежит дата, можем без труда понять как она храниться - номер дня от начала года.
По той же логике находим номер билета (4 байта без ведущего нуля) и его ключ.
После этого понимаем, что 12 байт данных билетов в обоих метро ксорятся нехитрым ключем – METRO, то есть METROMETROME, учитывая блоки.
Зная что должно быть в дате ксорим ее с дампом и понимаем ключ шифрования.
В конце, как водится, стоит контрольная сумма, в первом метро она не мешает получить флаг (ошибка выдается, но и флаг тоже) и не ксорится с ключем. Второе метро отличается только тем, что там контр. сумма ксорится и проверяется, в случае, если не сходится, то и флаг не выдается.
Проверяем crc32 от первых 12 байт и смотрим что вышло, а затем смотрим что в последний 4 байтах – таже самая CRC32, только без старшего разряда. Все, контрольная сумма разгадалана.
Считаем CRC32 от 12 байт билета второго метро, ксорим с тем, что там записано в последних 4 байтах и понимаем ключ для контр. суммы билетов второго метро – ключ получается HASH.
Теперь все разгадано – тупо сдвигаем номер билета сильно вперед, дату на текущую, генерим билет, ксорим данные, считаем CRC32, ксорим ее, отправляем, получаем флаг.
ВУАЛЯ =) Кстати, формат билетов взят с реальных пропусков, которые мне доводилось видеть.
3. WEB100. The State Hermitage Museum (https://hackquest.zeronights.org/missions/hermitage.php).
Самое тугое по прохождению задание, с точки зрения логов =)
Ничего сложного тут нет. Загружается картинка, и дано описание, что это должна быть фотография Эрмитажа. Ну как скрипт может проверять фотографию на дислокацию? Конечно, только по EXIF тэгам с координатами.
Когда отправялется такая картинка, скрипт выдает сообщение: “Can not find photo location in database “, что явно намекает на СУБД и внедрение операторов. Создаем картинку с кавычкой в координатах и видим, как все радостно падает. Дальше – дело техники.
Редактирование EXIF метаданных – излюбленный способ хакеров снабжать картинки полехной нагрузкой в виде шеллов для проведения RCE через LFI при полноценной валидации картинки графическими библиотеками.
Уязвимый участок кода был дан в подсказке в Твиттере, вот он:
$exif = exif_read_data($_FILES['photo']['tmp_name'],"GPS");
if(@$exif['GPSLatitude'] && @$exif['GPSLongitude']){
if(is_array($exif['GPSLatitude'])){
$lat = implode(" ",$exif['GPSLatitude']);
}else{$lat = $exif['GPSLatitude'];}
if(is_array($exif['GPSLongitude'])){
$lon = implode(" ",$exif['GPSLongitude']);
}else{$lon = $exif['GPSLongitude'];}
$res = $db->query("select id,descr from objects where id in
(select object_id from object_locations where latitude='$lat' and longitude='$lon')
");
$row = $res->fetchArray();
if($row){
echo "Upload OK. Thank you! Location: {$row['descr']}";
}else{
echo "Can not find photo location in database ";
}
}else{
echo "Can not verify that this photo of the Hermitage!";
}
Как видим, не сложное 100 балльное задание.
November 23rd, 2011 on 6:59 am
Наконец-то, я понял, как сформулировать свое отношение к бруту на квестах.
Дело в том, что в реальной жизни тебе платят деньги, у тебя есть обязательства, у тебя отсутствует соревновательный принцип. Это совершенно другой уровень мотивации.
Лично для меня мотивация продолжать брут в квестах и прочих CTF пропадает примерно через час-два.
November 23rd, 2011 on 8:52 am
>> Первый этап – найти исходный код, ищется без труда с помощью логики и эрудиции
Хех, ловко-то как! Только не сказано, что обращаясь к дире kirovsky, ты получаешь ошибку 404, как и к прочим несуществующим директориям. Так что “без труда” я бы не стал говорить)
Большинство участников оказалось нелогичными и неэрудированными
November 23rd, 2011 on 11:40 am
Насчёт брута солидарен, не люблю его.
А в целом для меня квест был полезным, спасибо, хоть и был ряд дурацких заданий.
Rebz, брутить диры надо было фаззингом url: {dir}/.htaccess
November 23rd, 2011 on 11:43 am
Да, Rebz, nginx имеет документированную багу, если директория есть, то на dir/.htaccess отдается 403, иначе – 404, так что не надо
Замечания по бруту принимаются.
November 23rd, 2011 on 11:53 am
Угу, я уже это понял, почитав комменты обзора Андрея Путхова. Но надо ж было знать, что на сервере nginx! Ну зато что-то новое узнал).
PS документированная бага – это не бага, а фича
November 23rd, 2011 on 12:55 pm
достаточно было указать диру буз завершающего слеша в конце – и мы получали редирект 301 что свидетельствовало о существовании оной.
HTTP/1.1 301 Moved Permanently
Location: http://hackquest.zeronights.org/missions/kirovsky/
November 23rd, 2011 on 1:08 pm
Вам в работе брут реально помогает?
Хех, “открыл” багу с nginx в ходе прохождения, не знал о ней раньше, и только сейчас узнал, что она только в nginx =)
А вообще хотелось бы видеть множество различных систем. Иногда начинаешь работать с новой системой и понимаешь, что практически не знаешь, как и что нужно с ней делать.
А в целом молодцы, что подготовили квест, было интересно, давно хотел разобраться с exif и попробовал sqlite на вкус.
> которое вызывает отработку тормозящей функции/конструкции
брутил так, кому интересно могу выложить весь код:
var payload = ‘select case when hex(‘ + column + ‘) like “‘ + encode(word) + ‘%” then load_extension(“/etc/passwd”) else 1 end from ‘ + table + ‘ where hex(‘ + column + ‘) like “‘ + encode(word) + ‘%”;’
document.cookie = ‘admin_data_asdgwugq7gw7er6wqge7riqwgrqwe87or=’ + escape(‘ 0 union ‘ + payload);
November 23rd, 2011 on 3:19 pm
Xотел еще спросить, вы в каком приложении встречали md5>gzip>base64?
Мне показалось это надуманным.
November 23rd, 2011 on 3:37 pm
@shafigullin, это повсеместно в шеллах используется. Больше нигде вроде не встречал =)
November 23rd, 2011 on 4:24 pm
Встрачал в корп. секторе, вы тоже можете встретить, обращайте внимание на порталы, которыми пользутесь каждый день
November 23rd, 2011 on 5:27 pm
когда они поймут, что это не эффективно, будут использовать триплзип, знаю таких..
November 23rd, 2011 on 8:46 pm
Насчет брута. Брут и перебор по словарю – вещи разные. На тему помогает – не помогает, я занимаюсь комплексным аудитом, а там нету ничего лишнего, надо обеспечить полноту предлагаемого аудита, то есть все методы должны быть использованы. Если говорить о тех случаях, где словарный перебор помогал получить рут на веб-сервере – то где-то 40%.
November 24th, 2011 on 10:24 am
40! это очень много
February 15th, 2013 on 9:25 am
Замечаем, что алфавит состоит из символов ADFGVX. Вбив это в гугл, добавив на всякий случай слово cipher, получил ссылку на википедию . Осуществив ликбез, воспользовался гуглом с ключевым словосочетанием “ADFGVX online” и получил ссылку на этот сервис . Дальше уже совсем все просто – вставляем шифрограмму, используем ключ USSR и получаем флаг.