Статьи ⇒ Общее ⇒ Инъекция нулевого байта

Инъекция нулевого байта

Опубликовано: 18 апр 2011 в 17:28
Автор: Robert Auger  Перевод: freeeeez 

Техника инъекции нулевого байта (Null Byte Injection) использует обход фильтров проверки веб-приложений, путем добавления нулевого байта (%00 или 0x00) в конец строки URL. Дело в том, что большинство веб-приложений, написанных на языках высокого уровня (PHP, Java, ASP и Perl), воспринимают нулевой символ, как конец строки. Эта инъекция позволяет изменять логику работы скрипта, позволяя атакующему получить несанкционированный доступ к системным файлам.

Это пришло из C/C++. Некоторые функции в серверных языках обрабатывают данные как функции языка C, т.е. побайтно. Разнообразные подходы к манипулированию данной особенностью и породили класс атак, называемых "Инъекция нулевого байта". В C/C++ нулевой байт означает остановку обработки строки. Байты следующие за ним будут игнорироваться. Если же нулевой байт не обнаружен, длинна строки становится неизвестной до обнаружения следующего разделителя. Из-за таких различий в интерпретации нулевой байт легко позволяет манипулировать поведением приложений.

Диапазон символов для URL-адреса ограничен US-ASCII от 0x20 до 0x7E (в HEX) или от 32 до 126 (в десятичной системе). Однако в данном диапазоне используются несколько недопустимых символов, которые являются зарезервированными для HTTP-протокола. Именно по этому схема кодирования URL была расширена дополнительными символами ASCII. Нулевой байт кодируется как %00. Это и позволяет злоумышленнику манипулировать скриптом для чтения или записи на основе пользовательских привилегий. Это довольно архаичный вид атаки времен "больших компьютеров" и магазинов, в которых можно было найти денди или купить электронную игру "Ну, погоди"

Давайте рассмотрим несколько примеров, чтобы продемонстрировать возможные атаки с использованием нулевого байта.

Пример #1 Perl

$buffer = $ENV{'QUERY_STRING'};
$buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$fn = '/home/userx/data/' .$buffer. '.jpg';
open (FILE,"<$fn");
Рассмотрим функцию "open File()". Функция работает на движке C и обрабатывает %00 как конец строки. В случае выше, следует обойти фильтрацию внешних данных путем указания правильного расширения файла, для того чтобы обмануть скрипт и прочитать системный файл (например, /etc/passwd):

URL: http://www.example.xx/read.pl?file=1.jpg

Атака: http://www.example.xx/read.pl?file=../../../../etc/passwd%00jpg

Пример #2 PHP

Сценарий, представленный выше, верен и для PHP. Например, если пользователь запрашивает файл с сервера, к строке будет добавляться расширение файла ".DAT".
$file = $_GET['file'];
require_once("/var/www/images/$file.dat");
Этот подход кажется безопасным вследствие добавления расширения, но его можно убрать путем добавления нулевого байта в конце URL-адреса.

URL: http://www.example.xx/user.php?file=myprofile.dat

Атака: http://www.example.xx/user.php?file=../../../etc/passwd%00

Защита от нулевого байта

Чтобы избежать подобных ситуаций, следует фильтровать внешние данные на появление в них нулевого байта. Есть несколько способов предотвращения Null Byte Injection. Можно экранировать нулевой байт обратным слэшем, однако наиболее рекомендуемый способ это полностью удалить нулевой байт из строки.

Фильтрация для Perl

$data=~s/\0//g;

Фильтрация для PHP

$file = str_replace(chr(0), '', $string);
В данной статье рассмотрена фильтрация данных только от Null Byte. О фильтрации SQL-инъекций и HTML-тэгов смотрите в статьях на сайте.

4 комментария
14 338 просмотров


#1 Vit, 18 апр 2011 в 18:37
Любые входные данные нужно фильтровать и не только на нулевой байт.
А так
$file = $_GET['file'];
require_once("/var/www/images/$file.dat");
уже давно ни кто не пишет ;)
#2 freeeeez, 18 апр 2011 в 18:39
Я рад, что Вы так не пишите.
По поводу фильтрации читайте статьи на сайте.
#3 Кир, 17 ноя 2011 в 21:17
Объясните немного подробнее, пожалуйста, для случая с PHP.

У меня передаются тольчко числовые данные ID и соответственно обрабатываются if !is_numeric - если таковыми не являются - просто перебрасываю на главную.

А с нуль байт как? ЧТо значит эта строка:

$file = str_replace(chr(0), '', $string);

то есть мы просто вырезаем нуль? А chr - это что? Спасибо. Сорри за ламерские вопросы - я новичок.
#4 freeeeez, 18 ноя 2011 в 08:39
Кир, эта строка означает, что при нахождении ASCII символа 0 в строке $string, мы заменяем его на ''. Функция chr(int $ascii) возвращает ASCII символ того, что находиться в скобках.

Оставить комментарий:

Имя:
Email:
Сайт:
Комментарий:

Допустимые теги: <em> • <strong> • <u> • <sub> • <sup> • <blockquote>

Проверочный код:

Введите проверочный код, для подтверждения, что вы не робот.
P.S. Если вы робот, то, к сожалению, вы
не сможете прочитать символы с картинки.