Просматривая забугорный форум sla.ckers.org, обнаружил новый способ, позволяющий отбросить любое значение, в частности расширение файла, в инклудах без использования нулл-байта. Как известно, нулл-байт экранируется при magic_quotes_gpc=on, поэтому это зачастую создает трудности при эксплуатировании LFI. Способ заключается в том, что расширение можно отбросить, если до него предшествует последовательность символов, при чем длина этой последовательности может различаться в зависимости от OS. Где в коде PHP находится уязвимость пока сказать сложно, но вполне ясно, что она связана с теми же особенностями, которые ведут к проблемам с нулл-байтом, т.е. все исходит из C, на котором написан PHP. К сожалению, уязвимость не позволяет выбраться из текущей папки просто дописав перед значением ../, но мной был найден способ обхода (также зависит от OS). 1. *nix Символы, составляющие последовательность: 0x2F / (не экранируется) Длина полного пути *: *getcwd() + DIRECTORY_SEPARATOR + имя файла + последовательность символов 4095 Linux 1023 FreeBSD Пример: http://localhost/test.php?lol=inc.php//////////////////////[...] Выход за пределы текущей папки: http://localhost/test.php?lol=existing_dir/../../inc.php//////////////////////[...] где existing_dir имя существующей папки в некоторых версиях PHP (e.g. 5.1.2) на linux имя папки может быть любым 2. windows В windows имеются значительные отличия в зависимости от версии PHP. Почти в каждой версии имеются свои особенности. Символы, составляющие последовательность: 0x20 пробел не экранируется работает во всех версиях не работает при использовании способа с выходом из текущей директории 0x22 " экранируется работает в PHP => 5.2.0 не работает при использовании способа с выходом из текущей директории 0x2E . не экранируется работает во всех версиях работает при использовании способа с выходом из текущей директории 0x3C < не экранируется работает в PHP => 5.2.0 не работает при использовании способа с выходом из текущей директории 0x3E > не экранируется работает в PHP => 5.2.0 не работает при использовании способа с выходом из текущей директории 0x2f / не экранируется работает во всех версиях, но в PHP => 5.2.0 только при условии, если отсутствует точка в отбрасываемом значении работает при использовании способа с выходом из текущей директории, но лишь в некоторых версиях 0x5c \ экранируется работает во всех версиях, но в PHP => 5.2.0 только при условии, если отсутствует точка в отбрасываемом значении работает при использовании способа с выходом из текущей директории, но лишь в некоторых версиях а также различные вариации с точкой: ./ .\ . (пробел) .//.// .\\.\\ etc Длина полного пути *: *getcwd() + DIRECTORY_SEPARATOR + имя файла + последовательность символов PHP 4.4.2, 5.1.2, 5.2.6 265 если присутствует точка в отбрасываемом значении 266 если отсутствует PHP 4.4.4, 4.4.9, 5.2.0 258 если присутствует точка в отбрасываемом значении 259 если отсутствует точка в отбрасываемом значении Пример: http://localhost/test.php?lol=inc.php.......................[...] http://localhost/test.php?lol=inc.php<<<<<<<<<<<[...] Выход за пределы текущей папки: http://localhost/test.php?lol=exsiting_dir/../../inc.php............................[...] http://localhost/test.php?lol=nonexsiting_dir/../../inc.php............................[...] где nonexsiting_dir имя любой папки, даже несуществующей Вывод исследования: для windows универсальный символ для последовательности в векторе атаки это точка (.); минимальная универсальная длина этой последовательности - 266 символов в *nix единственным и универсальным символом является слэш (/); минимальная универсальная длина последовательности - 4095 символов; Для эксплуатации LFI в реальных условиях необходимо рассчитывать длину последовательности с учетом максимальной длины URL, которую способен принять веб-сервер. Если, например, сервер имеет ограничение URL < 4096 байт, а система работает на linux, то реализовать уязвимость не удастся Информация конечно не совсем приватная, но пока что распространение она не получила. Оригинальный топик: http://sla.ckers.org/forum/read.php?16,25706
Длина максимального URL зависит от конфигурации веб-сервера. Апач по умолчанию держит 4096 байт, как раз достаточно дле реализации уязвимости http://paradigm.ru/2007/12/19/url-max-length/
в смысле на локалхосте? я про веб-сервер, апач он и на локалхосте апач ) з.ы. у меня на локалхосте ограничение 4096 байт )
Напишите у кого какие версии всего софта, ось, пхп, апач, способ подключения пхп к апачу. Что то у меня не работает данная конструкция, если у кого то это работает то отпишите на каких настройках. PHP: <?php $_GET['inc'] = "/1.txt"; for($x=1;$x<=230;$x++){ //$_GET['inc'] .= urldecode("%3C"); $_GET['inc'] .= "<"; } include("Z:\\home\\localhost\\www".$_GET['inc']."some.txt"); ?>
я проверял- не пахало поэтому и спросил. UP проверил побольше диапазон в общем оказалась магической цифра 4075, хз почему, тоесть имя файла вмесле со слешами имеет длину 4075 символа-> увеличиваю имя файла , уменшаю количесво сдешей соответственно, система linux PHP 5.2.6 еще кстати фигня: PHP: $a=$_GET['qd'].'.xxxxxxx'; include($a); убираю точку в подгружаемом расширении и уже не работает. из корневой папки без спуска ../ не хочет работать тоже, пашет при спуске через типа: zzzzzzzzz/../../../ и тп папке zzzzzzzzzz существовать не обязательно.
PHP Version 4.4.0 System Windows NT 5.1 Код: PHP: <?php $a=$_GET['page'].'ТУТ_5000_символов_<'.'.php'; include($a); ?> Apache/1.3.33 magic_quotes=Off Аналогично, на: PHP Version 4.4.9 System Linux 2.6.24.2 #1 SMP i686 magic_quotes=On Apache/1.3.34 (Debian) Не работает никак. Отпишитесь, пожалуйста, кто пробовал на 2ке апача и на 5ке php
php 5.2.8 apache 2.2.11 windows xp работает PHP: http://localhost/test.php?file=lol.bmp....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... PHP: <?php include($_GET['file'].'.php'); ?>
хм система линукс PHP 5.2.6 апач 2.2.8 <? include($_GET['page'].'.php'); ?> итак incl.php?page=omg.txt - 4062 символа/ incl.php?page=om.txt 4064 символа / incl.php?page=o.txt 4065 символов / incl.php?page=omfg.txt - 4062 символа / incl.php?page=xekxekekxek.txt - 4056 симвлов / может тут кто то видит порядок, я нет =) PS в каждом случае указано минимально кол-во символов /, если ставить больше то всё работает, к примеру 4070 символов будут работать в любом примере
А на ngnix/light httpd работает? Может бага апача? Нет возможности проверить. У кого есть возможность отпишитесь
PHP: http://www.thejustinfoundation.org/main.php?pg=documents/../../../../../../../../../../../etc/shells Живой нерабочий пример Здесь, как и в моих примерах выше - Apache/1.3.33
PHP 4.4.2 WinXP 32 bit - работает PHP 4.4.4 WinXP 32 bit - работает PHP 5.1.2 WinXP 32 bit - работает PHP 5.2.0 WinXP 32 bit - работает PHP 4.4.4 Vista 32 bit - работает PHP 5.2.0 Vista 32 bit - работает PHP 5.2.6 Vista 32 bit - работает PHP 5.2.8 FreeBSD 6.3 - работает В общем везде, где проверял у меня работало. Возможная проблема у тех, у кого не работало - вы указывали абсолютный путь, с ним уязвимость не работает. у меня такого не наблюдалось ни на винде, ни на линуксе. об этом уже писал Предлагаю заняться ииследованием сорцов для выяснения причин баги. Возможно удастся понять от чего зависит длина необходимой последовательности. @1ten0.0net1 на твоем живом примере не работает, потому что доставляется ./: