| RSS



Меню

Bookmark and Share


Статистика
Ваш IP: 3.238.99.243
Вы используете: v





Сейчас на сайте:

Тех поддержка ->

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 PHP Эксплоит Windows Server 2008 qip Virtual chroot kernel proc sysctl tune FreeBSD bridge Boot Disk Bluetooth GEO game directx Emulator Python Shell DDoS червь Conficker вирус троян Лаборатория Касперского пиратство apple iPhone ИТ-отрасль Щеголев Microsoft экономический кризис Twitter социальная сеть анонимность Лицензия Open Source ASP.NET MVC уязвимость MySQL база данных файлообмен закон франция пират Skype мобильный Deutsche Telekom Хакер киберпреступник Trend Micro кибератака Германия робот утечка данных персональные данные ноутбук интернет Китай цензура ядро Linux Торвальдс Windows Vista Acer Linux патент браузер Firefox Internet Explorer Opera Net Applications Safari Intel Linux Foundation Moblin Oracle патч банкомат кардер HSM IBM X-Force Cofee сша кибервойна Эстония Dell ИТ-специалист хакерские атаки Pirate Bay контроль кибербезопасность язык программирования The Pirate Bay Пиратская партия утечка информации приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 Баллмер взлом Пентагон ботнет Украина Facebook Cisco cloud Windows XP нетбук торрент музыка биометрический nokia ФБР IP-адрес CIPAV Comcast sms RSA java Google CAPTCHA Symantec спам конфиденциальная информация инсайдер Perimetrix антивирус тест Anti-Malware Windows 7 операционная система Windows провайдер авторское право RapidShare UNIX свиной грипп шантаж дети EFF BluWiki копирайт экстремизм Panda Security cloud computing McAfee Cybercrime Response Unit Bottle Domains HTTPS ICANN студент шпионское ПО Норвегия школьник New York Times XSS YouTube Warner Music кибершпионаж КНДР Ubuntu свободное ПО AMD ATI касперский Россия РФ сервер хостинг фальшивый антивирус Comodo CA Wi-Fi D-Link суд пароль блог фишинг Одноклассники медведев контрафакт мошенник штраф Sony GPS по Gumblar JAVASCRIPT хакеры вредоносное ПО Yahoo ФАС компьютер Софт MPAA кибероружие PandaLabs Red Hat Минкомсвязи сбой ASUSTeK Computer мошенничество Доктор Веб ВКонтакте Cyber-Arc исходный код PCI DSS МВД фильтр порнография BREIN свобода слова Казахстан GEMA Autodesk сисадмин Gmail кредитная карта кибермошенник LiveJournal шифрование криптография Deep Purple банк нанотехнологии Wikipedia zero-day ColdFusion выборы кража данных DNS BIND Android BASIC атака Black Hat Mac OS X Click Forensics Clampi домен фсб Прокуратура Уголовное дело icq Barrelfish киберпреступность Sophos AT&T ошибка Electa Gamma Knife OpenBSD DARPA военные Сайт Visual Studio 2010 .NET Framework 4 Chrome OS электронная почта турция конференция спамер FTC полиция российская ОС Koobface Великобритания БЕЛОРУССИЯ грузия BSA Bittorrent облачные вычисления Azure Европа Dr.Web Билл Гейтс спецслужбы Cryzip Живой Журнал Royal Bank of Scotland смартфон Canonical Pwn2Own F-Secure Symbian Hotmail фильм

Главная » Статьи » Общие Статьи

Неслучайные числа: Ultimate-баг движка PHP

Недавно обнаруженная известным IT Security специалистом Стефаном Эссером уязвимость в интерпретаторе PHP теоретически может затронуть миллионы веб-сайтов, на которых используется PHP<=5.2.5. Тебе интересно, в чем суть уязвимости? В статье я разобрал advisory бага по полочкам.

Баг затрагивает функции генерации псевдослучайных чисел rand() и mt_rand(). Зачастую они используются для создания паролей, сессий, кукисов и других различных конфиденциальных данных пользователя.

Rand() — это просто враппер для библиотеки libc rand(), а mt_rand() — враппер для генератора псевдослучайных чисел Mersenne Twister. Обе функции используют так называемый seed (семя), который можно задавать соответственно функциями srand() и mt_srand(). По дефолту сид представляет собой 32‑битный DWORD (2 в 32 степени или 4294967296 комбинаций). Обычно такой длины достаточно, чтобы обеспечить криптографическую стойкость приложения. Ведь для брутфорса пароля, сгенерированного с помощью одной из этих функций, необходимо знать не только сид, но и сгенерированные на его основе числа. Впрочем, существует ряд ситуаций, в которых брутфорс вполне применим...

Затравка

В PHP 4 и PHP 5 <= 5.2.0 присутствует следующая недоработка: любой seed, вызываемый mt_srand(), либо присваиваемый автоматически, имеет разрядность всего 31 бит, так как последний бит всегда устанавливается равным одному. Таким образом, для брутфорса семени нам нужно перебрать 2147483648 комбинаций. Уже лучше, но все-таки для эксплуатации такого бага времени потратить придется немало. В последующих версиях PHP эту недоработку залатали, но оставили другую. В PHP 4 и PHP <= 5.2.5 всякий раз, когда 26 последних бит становятся равными нулю, seed также принудительно становится равным нулю (либо 1, в зависимости от установки принудительных бит системой). Это правило действует для 32‑битных систем. На 64‑битных системах ситуация чуть лучше — сид просто становится 24‑битным.

Принудительная генерация seed

Выше я раскрыл одну сторону бага, а теперь — самое вкусное! Если ты любишь покопаться в сорцах бесплатных PHP-цмсок, то, наверняка, знаешь, что их кодеры очень любят инициализировать генераторы псевдослучайных чисел при помощи функций srand() и mt_srand():

mt_srand(time());
mt_srand((double) microtime() * 100000);
mt_srand((double) microtime() * 1000000);
mt_srand((double) microtime() * 10000000);

Такая инициализация не криптоустойчива, потому что:

1. функция time() не является случайной. Ее значение будет известно хакеру. Даже если админы намеренно установят локальное время сервера ошибочным, — его точное значение всегда будет возвращаться в HTTP-заголовках;

2-4. первое слагаемое (double) microtime() будет равно 0, либо 1, а второе — соответственно, от 100000 до 10000000. В итоге, получаем для брутфорса все то же число: от 100000 до 10000000 значений. При 1000000 значений процесс брутфорса сида займет всего несколько секунд!

Keep-alive соединения

Материал был бы бесполезным, если бы не тот факт, что Keep-alive HTTP-соединения всегда обслуживаются одним и тем же процессом на удаленном веб-сервере! Это означает, что seed, сгенерированный единожды на одном домене этого сервера, будет таким же и для другого домена на этом сервере! То есть, если какой-либо php-скрипт выведет сгенерированные случайные числа, мы сможем определить по ним сид, — и остальные случайные числа генерить на его основе! Правило, как ты уже понял, относится не только к одному хосту, но и ко всем хостам на удаленном сервере. Нельзя не заметить, что это действует только для PHP, запущенного как модуль Апача, а вот для cgi генераторы псевдослучайных чисел всегда будут инициализироваться заново. Но cgi, скорее, исключение из правил, так что не будем брать его в расчет. Кстати, Стефан Эссер подсказал здесь хинт. Если ты хостишься на одном сервере с жертвой, то можешь принудительно запустить скрипт на своем хосте с srand(0) или mt_srand(0). Сид у жертвы будет, соответственно, 0 :).

От теории к практике

Настало время обобщить все сказанное. Итак, запусти следующий скрипт:

<?php
mt_srand(31337);
print mt_rand()."\n";
print mt_rand()."\n";
print mt_rand()."\n";
print mt_rand();
?>

При каждом выводе mt_rand() тебе будут показаны одинаковые числа, так как seed везде один и тот же. Теперь запусти другой скрипт:

<?php
print rand()."\n";
print rand();
?>

Допустим, ты получил числа 11834 и 2795. Снова запускай данный код, но теперь в качестве сида укажи первое получившееся число:

<?php
srand(11834);
print rand()."\n";
print rand();
?>

В итоге ты получишь числа 2795 и 28744. Обрати внимание на предыдущий результат :). Эту особенность генератора обнаружил raz0r (ссылки на его адвисори смотри в конце статьи).

Cross Application Attacks

Некоторые веб-приложения сами инициализируют seed, а затем выводят полученные на его основе псевдослучайные числа конечному пользователю. Пример такого приложения — phpBB2. Вот код из search.php:

mt_srand ((double) microtime() * 1000000);
$search_id = mt_rand();

Проблема в этом примере заключается в том, что количество комбинаций составляет всего 1000000, плюс в html-исходнике страницы мы увидим вывод значения $search_id. Как ты уже понял, зная сгенерированное случайное число, мы, фактически, знаем и seed! Тем более, на сравнение 1000000 результатов работы генератора с полученным $search_id уйдет совсем немного времени. Простор для действий тут очень большой. Можно создать rainbow-таблицы со всего лишь 1000000 значений.

Ситуация верна для PHP 5 => 5.2.1. А в случае с PHP 4 и PHP 5 <= 5.2.0 она становится еще лучше! Для них количество вариантов сокращается почти в два раза, то есть до 2 в 19 степени. Причину я описал в первых абзацах. Ты спросишь, почему же в этом примере утечка сгенерированного числа является проблемой безопасности? Вот почему:

  1. Запуск генератора случайных чисел влияет не только на представленный в примере phpBB2, но и на остальные веб-приложения, установленные на этом сервере;
  2. Псевдослучайные числа, сгенерированные на основе предыдущего seed, будут предсказуемыми;
  3. Остальные приложения на этом же сервере могут создавать пароли, сессии и т.д. на основе полученного ранее seed.

Теперь рассмотрим ситуацию, когда phpBB2 и любимый мной WordPress установлены на одном сервере. Отталкиваясь от полученной выше информации, Стефан описывает такой алгоритм атаки на веб-приложения (Cross Application Attacks):

  1. Запускаем keep-alive соединение к поиску phpBB2 и ищем любое часто встречающееся слово, вроде «a», «the» и т.д;
  2. Если запрос вернул более 30 результатов поиска, то смотрим html-исходник страницы. В ссылке на следующую страницу форум должен вывести случайное число в параметре search_id, — запоминаем его;
  3. Запускаем брутфорс по найденному псевдослучайному числу из search_id для определения изначального seed. Для этого raz0r предлагает функцию:

    function search_seed($rand_num) {
    $max = 1000000;
    for($seed=0;$seed<=$max;$seed++){

    mt_srand($seed);
    $key = mt_rand();
    if($key==$rand_num) return $seed;

    }
    return false;
    }

     
  4. 4. Запускаем mt_srand() с полученным значением seed и отбрасываем первое число — тот самый search_id;
  5. В том же keep-alive соединении отправляем запрос на смену пароля админа блога;
  6. На основе полученного сида генерируем случайное число для активационного ключа смены пароля, который блог должен был выслать на мыло админа;
  7. Снова все в том же keep-alive соединении переходим по сгенерированной эксплойтом активационной ссылке. Это должно привести к смене пароля администратора;
  8. Генерируем пароль той же функцией, с помощью которой получили активационный ключ, и заходим в админскую часть WordPress :). Кстати, если на сервере-жертве стоит PHP 4 или PHP 5 <= 5.2.0, то желательно генерировать псевдослучайные числа на той же версии PHP; то же самое относится и к PHP 5 >= 5.2.1. Эксплойт, основанный на этом алгоритме, написал все тот же raz0r.
    часто встречающееся слово, вроде «a», «the» и т.д; Ссылку смотри ниже.

Снова WordPress

Попробуем подойти к описанной уязвимости с другой стороны и рассмотреть последний эксплойт для WordPress, названный Wordpress 2.6.1 (SQL Column Truncation) Admin Takeover Exploit. Алгоритм эксплойта основан сразу на двух глобальных уязвимостях: на, собственно, предсказуемости псевдослучайных чисел и на SQL Column Truncation — усечении данных в MySQL.

Сделаю небольшое отступление и расскажу об этом пресловутом усечении данных в мускуле. Уже известный тебе Стефан Эссер опубликовал в своем блоге очередную advisory, посвященную новой уязвимости. Она связана с особенностями сравнения строк и автоматического усечения данных в MySQL. Известно, что любой столбец в таблице имеет определенную длину. Допустим, существует поле varchar(60) (как в WordPress <= 2.6.1 для логина пользователя). Что будет, если записать в это поле любое значение, которое превысит обозначенные 60 символов? Лишние символы отсекутся! В поле останутся первые 60 символов, которые мы попытались туда записать. Дальше. Если у нас есть поле в базе данных со значением «admin», и мы попытаемся сравнить это значение, например, с «admin » (admin и 2 пробела), то мускул это проделает и скажет, что поля равны. Эта особенность MySQL работает в дефолтной конфигурации, — что открывает новый вектор атаки на веб-приложения!

Подробнее о уязвимости советую прочитать по адресам, указанным в конце статьи. Но вернемся к нашему эксплойту.

Принцип его работы изложен ниже:

  1. Регистрируем нового пользователя с логином admin[55 пробелов]x. Далее конечный символ «x» отсекается, и в базе мы получаем пользователя admin с 55 пробелами, что для мускула фактически будет равно просто логину «admin»;
  2. Запрашиваем линк сброса пароля на свое мыло и получаем уникальный ключ из параметра key, который был сгенерирован функцией mt_rand();
  3. Сбрасываем пароль администратора с полученным ключом. В итоге, новый пароль уйдет только на мыло админа;
  4. На основе полученного ранее ключа ищем сид для вновь сгенерированного пароля. Тут можно сгенерировать rainbow-таблицы для поиска, которые будут весить примерно 4294967296 (строк, возможных значений сида, номер строки=seed) * 20 (количество символов кея для смены пароля) = 85899345920 байт или 80 гигабайт. Для версий PHP 4, PHP 5 <= 5.2.0 и PHP 5 >= 5.2.1 нужно генерировать отдельные таблицы. В эксплойте также есть возможность искать seed и без применения радужных таблиц, но процесс займет очень долгое время. Делается это следующей функцией:

    function getseed($resetkey) {
    echo "[-] calculating rand seed for $resetkey (this will take a looong time)";
    $max = pow(2,(32‑BUGGY));
    for($x=0;$x<=$max;$x++) {
    $seed = BUGGY ? ($x << 1) + 1 : $x;
    mt_srand($seed);
    $testkey = wp_generate_password(20,false);
    if($testkey==$resetkey) {
    echo "o\n"; return $seed;
    }
    if(!($x % 10000)) echo ".";
    }
    echo "\n";
    return false;
    }


    Параметр BUGGY — не что иное, как вышеописанный баг, когда 26 последних бит сида становятся равными нулю, то есть число всех значений для перебора будет равным 2 в 31 степени. Вычисляется бажность генератора так:

    mt_srand(2); $a = mt_rand(); mt_srand(3); $b = mt_rand();
    define('BUGGY', $a == $b);

Изучив исходник этого эксплойта, ты сможешь более подробно вникнуть в суть уязвимостей, найденных Стефаном Эссером.

Пока что эксплойты на вышеописанных багах не очень распространены. Я думаю, это из-за того, что для многих эксплуатация уязвимостей генераторов псевдослучайных чисел может показатьсячересчур сложной. На самом деле, это не так. Хакеру я посоветовал бы изучить исходники эксплойтов, ссылки на которые есть в сноске, и написать на основе полученной информации свои мегапробивные релизы. А для админов и просто юзеров — обновить свой PHP до последней версии и поставить Suhosin-патч от Стефана Эссера.

Good luck!

Ссылки

http://www.suspekt.org/2008/08/17/mt_srand-and-not-sorandom-numbers — оригинальное advisory Стефана Эссера на тему mt_rand()
http://www.suspekt.org/2008/08/18/mysql-and-sql-columntruncation-vulnerabilities — MySQL and SQL Column Truncation Vulnerabilities
http://milw0rm.com/exploits/6421 — Wordpress 2.6.1 (SQL Column Truncation) Admin Takeover Exploit
http://raz0r.name/wp-content/uploads/2008/08/wp1.html — Wordpress 2.5 <= 2.6.1 through phpBB2 Reset Admin Password Exploit
http://raz0r.name/articles/predskazyvaem-sluchajnye-chisla-v-php — исследование raz0r’а на тему предсказуемости случайных чисел в mt_rand()
http://raz0r.name/vulnerabilities/sql-column-truncation-security — исследование raz0r’а на тему усечения данных в MySQL
http://raz0r.name/articles/magiya-sluchajnyx-chisel-chast-2 — исследование raz0r’а на тему предсказуемости случайных чисел в rand()
http://raz0r.name/vulnerabilities/uyazvimosti-v-simple-machinesforum — уязвимости SMF на основе предсказуемости случайных чисел.

Категория: Общие Статьи | Добавил: aka_kludge (30.04.2009)
Просмотров: 1835 | Теги: а mt_rand(), PHP, Ultimate, libc rand() | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

14:01
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2021 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика