Всем привет. При исследовании различных WEB-приложений без наличия исходных кодов поиск уязвимостей осуществляется только с белого входа - страниц сайта которые обрабатывают различные запросы от пользователя с параметрами GET, POST, Cookie, Headers, это может быть как и главная страница, так и Ajax запрос, запрос от Flash-приложения где кстати может использоваться не только HTTP и т.п.
В большинстве случаев все параметры тщательно проверяются и уязвимостей просто нет, однако довольно часто и особенно в крупных приложениях существует черный вход - страницы, к которым обращается сервер и парсит из них нужную ему информацию. Конечно не секрет, что многие скрипты поступают таким образом, но если у нас нет никакой информации о том, что делает сервер достаточно проблематично найти какую-либо уязвимость.
В этой теме возможно собрать различные методы исследования из вне таких приложений, типах уязвимостей о которых в данном случае разработчики не осведомлены, далее можно попробовать рассмотреть какое-либо приложение, использующие эту технологию. Основные сложности здесь в том, что обычно мы не можем получить какой-либо информации о использовании данных, ошибок и т.п. особенно если действия выполняются в фоне.
Некоторые вариации уязвимостей в других источниках были названы
SSRF (Server-Side Request Forgery) но это не совсем корректно - подделки запросов здесь нет, нам будет удобнее просто рассматривать действия с содержимым страницы на стороне .
Начнем.
A. DoS - Самая простая атака в нашем случае, цель - отказ в обслуживании. Стандартная ситуация, приложение VK загружаемое в ифрейме, к которому передается некоторые параметры:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"]app[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]php[/COLOR][COLOR="#007700"]?[/COLOR][COLOR="#0000BB"]api_url[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]http[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#FF8000"]//api.vk.com/api.php&api_id...
[/COLOR][/COLOR]
Как видим приложению передается
api_url на тот случай если адрес скрипта(
old_api.php) или домен изменится(
vkontakte.ru vs
vk.com), далее сценарий приложения подсоединяется к этому серверу и предположим сохраняет информацию о пользователе себе в файл. Если мы передадим ссылку на сервер с большим файлом, да несколько раз обновим страницу, канал сервера будет полностью забит да и места на диске рано или поздно не останется.
Это самое простое, что можно придумать но я не советую так поступать. Другие методы основаны на разборе данных сервером, что мы сейчас и и рассмотрим, цель - передать скомпрометированные ответы с некоторой информацией, которая может использоваться ...
B.Уязвимости можно разделить на 3-категории - уязвимости в парсере, уязвимости в обработчике запросов и туннельные уязвимости где благодаря наличию нескольких уязвимостей предыдущих типов мы можем построить через них туннель до требуемой нам операции.
1.Уязвимости в парсере весьма стандартны - данные не проходят соответствующею фильтрацию и используются далее - в SQL-запросах, запросах к файлам, небезопасным вычислениям, нужно лишь узнать, что используется и каким образом методом проб и ошибок.
Здесь имеет место определить зависимость использования соединения во время парсинга, к примеру в фоновом процессе мы можем иметь инъекцию типа:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"]SELECT[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]from[/COLOR][COLOR="#007700"]`[/COLOR][COLOR="#DD0000"]news[/COLOR][COLOR="#007700"]`[/COLOR][COLOR="#0000BB"]WHERE id[/COLOR][COLOR="#007700"]= [[/COLOR][COLOR="#0000BB"]SQL_CODE[/COLOR][COLOR="#007700"]]
[/COLOR][/COLOR]
и если фоновый процесс разрывает соединение после выполнения запроса мы можем определить время парсинга которое включает выполнения данного запроса.
Если данные используются для вывода, нужно проверить возможность
XSS и
XXE, последняя из которых возникает при разборе многофункциональными парсерами
XML документа, как некоторые советуют использовать на форумах:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]
]>
&data;
'[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$doc[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]DOMDocument[/COLOR][COLOR="#007700"]();
[/COLOR][COLOR="#0000BB"]$doc[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]loadXML[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);
echo[/COLOR][COLOR="#0000BB"]$doc[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]getElementsByTagName[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'antichat'[/COLOR][COLOR="#007700"])->[/COLOR][COLOR="#0000BB"]item[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"])->[/COLOR][COLOR="#0000BB"]textContent[/COLOR][COLOR="#007700"];
[/COLOR][/COLOR]
Не будем на них останавливаеться - к информации о них лучше обращаться по мере надобности, тем более она доступна в свободном доступе.
2. Уязвимости в обработчике запросов.
I.fsockopen:
fsockopen - Самая простая обертка, за исключением
tcp и
udp доступны
tls,
ssl,
sslv2 и
sslv3 а так-же
udg,
unix с помощью которых вохможно использовать локальные сокеты, такие как
/dev/log но использовать простые файлы невозможно.
После изучения исходников практически не нашел за что можно зацепится, единственное - 4-ый параметр функции отдающий ошибку, которая в будущем может быть занесена в php-файл, БД и т.д. Есть несколько методов возможности передачи текста с нашим содержимым в него, но лишь некоторые позволяют передать спецсимволы:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]...
[/COLOR][COLOR="#FF8000"]//Приоритет имеет первый параметр, к примеру если нужно использовать порт 0 для unix-сокетов это пригодится
[/COLOR][COLOR="#007700"]@[/COLOR][COLOR="#0000BB"]fsockopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"tcp://abc.ru:80"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]803[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorNo[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorSTR[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#FF8000"]//PORT abcd"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorNo[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorSTR[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#FF8000"]//int(0) string(43) "Failed to parse address "abcd"
//Однако передачей порта в первом параметре это не осуществить, но так-же нужно заметить что возможно передавать цифровые значения в других системах счисления.
[/COLOR][COLOR="#007700"]...
@[/COLOR][COLOR="#0000BB"]fsockopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"tcp://abc.com"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]9223372036854775808[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorNo[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorSTR[/COLOR][COLOR="#007700"]);[/COLOR][COLOR="#FF8000"]//В 64-bit системах такой вариант тоже вызовет ошибку с выводом параметра
[/COLOR][COLOR="#007700"]...
[/COLOR][COLOR="#0000BB"]var_dump[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$errorNo[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorSTR[/COLOR][COLOR="#007700"], (int)[/COLOR][COLOR="#0000BB"]9923372036854775089[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]intval[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]9923372036854775089[/COLOR][COLOR="#007700"]), ([/COLOR][COLOR="#0000BB"]9923372036854775089[/COLOR][COLOR="#007700"]>[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]));
[/COLOR][COLOR="#FF8000"]//Отрицательное число в PHP может быть больше одного, возможно при обходе фильтров это поможет
[/COLOR][COLOR="#007700"]...
@[/COLOR][COLOR="#0000BB"]fsockopen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"tcp://[abc.com"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]80[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorNo[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$errorSTR[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#FF8000"]//Вывод в ошибку при разборе IPv6 адресов
/*
Возникновение таких ошибок имеется и в других сетевых функциях php.
*/
[/COLOR][COLOR="#007700"]...
[/COLOR][/COLOR]
II.Разбор после использования
cURL.
cURL - очень злая штука, во многом благодаря тому, что самолично принимает решения. При её использовании программист обычно забывает про её опасность и клепает
ПО из различных примеров.
К примеру задание
33 было основано на этом:
/thread363372.html
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]open[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]) {[/COLOR][COLOR="#FF8000"]//
[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]curl_init[/COLOR][COLOR="#007700"]();
[/COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_URL[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'http://'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/data.php'[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_RETURNTRANSFER[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_POST[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_POSTFIELDS[/COLOR][COLOR="#007700"], array([/COLOR][COLOR="#DD0000"]'post'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'true'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'testdata'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]));
return[/COLOR][COLOR="#0000BB"]curl_exec[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]ch[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#FF8000"]//CURLOPT_URL, CURLOPT_POST - Это обычные цифорвые константы, различающиеся от версии к версии.
[/COLOR][COLOR="#007700"]}
[/COLOR][/COLOR]
В функции допущена большая ошибка - при наличи в переменной
$data строки
@/etc/passwd на сервер
$url отправилось бы содержимое этого файла.
Сообщение от
None
CURLOPT_POSTFIELDS
- Все данные, передаваемые в HTTP POST-запросе. Для передачи файла, укажите перед именем файла @, а также используйте полный путь к файлу. Тип файла также может быть указан с помощью формата ';type=mimetype', следующим за именем файла. Этот параметр может быть передан как в качестве url-закодированной строки, наподобие 'para1=val1¶2=val2&...', так и в виде массива, ключами которого будут имена полей, а значениями - их содержимое. Если value является массивом, заголовок Content-Type будет установлен в значение multipart/form-data. Начиная с версии PHP 5.2.0, при передаче файлов с префиксом @, value должен быть массивом.
Читать мы можем только доступные файлы:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]if (([/COLOR][COLOR="#0000BB"]type[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]php_memnstr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]postval[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]";type="[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]sizeof[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]";type="[/COLOR][COLOR="#007700"]) -[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]postval[/COLOR][COLOR="#007700"]+[/COLOR][COLOR="#0000BB"]Z_STRLEN_PP[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]current[/COLOR][COLOR="#007700"])))) {
*[/COLOR][COLOR="#0000BB"]type[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'\0'[/COLOR][COLOR="#007700"];
}
[/COLOR][COLOR="#FF8000"]//А вот этого в документации нет, используется при указании имени файла:
[/COLOR][COLOR="#0000BB"]f[/COLOR][COLOR="#007700"](([/COLOR][COLOR="#0000BB"]filename[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]php_memnstr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]postval[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]";filename="[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]sizeof[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]";filename="[/COLOR][COLOR="#007700"]) -[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]postval[/COLOR][COLOR="#007700"]+[/COLOR][COLOR="#0000BB"]Z_STRLEN_PP[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]current[/COLOR][COLOR="#007700"])))) {
*[/COLOR][COLOR="#0000BB"]filename[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'\0'[/COLOR][COLOR="#007700"];
}
[/COLOR][COLOR="#FF8000"]/* safe_mode / open_basedir check */
[/COLOR][COLOR="#007700"]if ([/COLOR][COLOR="#0000BB"]php_check_open_basedir[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]postval TSRMLS_CC[/COLOR][COLOR="#007700"]) || ([/COLOR][COLOR="#0000BB"]PG[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]safe_mode[/COLOR][COLOR="#007700"]) && ![/COLOR][COLOR="#0000BB"]php_checkuid[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]postval[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]"rb+"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CHECKUID_CHECK_MODE_PARAM[/COLOR][COLOR="#007700"]))) {
[/COLOR][COLOR="#0000BB"]RETVAL_FALSE[/COLOR][COLOR="#007700"];
return[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"];
}
[/COLOR][/COLOR]
Пожалуй мы добралиь до атак, которые можно назвать
SSRF. Смысл этого заключается в том, что
cURL при недостаточной обработке адреса сайта или включенной опции
CURLOPT_FOLLOWLOCATION может применить свою интеллектуальность и весьма-корректно обрабатывать запросы на получение локальной или внутри-сетевой информации:
PHP код:
PHP:
[COLOR="#000000"][COLOR="#0000BB"]file[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#FF8000"]///etc/passwd (file:// + /etc/passwd)
[/COLOR][/COLOR]
Здесь есть некоторые исследования:
http://www.riyazwalikar.com/2012/11/cross-site-port-attacks-xspa-part-1.html
При анализе проекта нужно посмотреть на ответ сервера при различных видах переадрестации, неправильного ответа сервера, выдаче данных неопределенной длины, больший файлов, MIME-типов.
III.Экзотические функции - анализ DNS записей, WHOIS - Не могу сейчас сказать, что возможно, но это интересная тема для анализа.
Это - краткий обзор, тут не следует делать кучу примеров, интересные темы можно будет рассмотреть далее, прямо здесь, возможно попробовать что-то использовать на практике, ведь каждое ПО - уникальное. Возможно я что-то забыл упомянуть. Предлагайте свои функции, возможно данные возможности используются в некоторых CMS или существуют некоторые сервисы использующие внешние запросы, однако не желательно устраивать здесь взломы.