Нулевой байт (Null Byte Injection, Null Byte Poisoning attack) в Java, Perl, PHP
Posted on | July 20, 2010 | No Comments
Для начала разберёмся что такое нулевой байт(%00, 0x00, null byte), откуда он появился и зачем собственно он нужен. Для этого придётся немного вспомнить как представляются строки в C. Строка в C – это набор символов или точнее байтов, которые оканчиваются нулевым байтом (‘\0’). Такие строки получили названия C Strings или нуль-терминированные строки. В таком представлении строк нулевой байт необходим для опознавания конца строки.
Давайте представим ситуацию, что в заполненную строку длинной в n символов мы впишем ‘\0’ на место символа n/2. Теперь, C-функции для работы со строками (strlen, strcpy..) просто не будут видеть “мнимую часть”, она как бы больше не существует. Байты, следующие за null байтом игнорируются. Казалось бы ну и чёрт с ним, и такая реакция полностью оправдана, если такая ситуация встречается в программе написанной на C/C++. А вот если программа написана на языках разработки веб-приложений, таких как Java (JSP), Perl, PHP – то это может грозить нам неприятностями.
В Java, Perl и PHP строки хоть и не представлены в виде нуль-терминированных, однако, не стоит забывать, что работа на системном уровне представлена в этих языках через C/C++ функции. Из-за чего и возникает опасность атак с использованием нулевого байта (Null Byte Injection, Null Byte Poisoning attack).
Рассмотрим пример уязвимого Perl скрипта. Переменная получаемая из переданного запроса недостаточно грамотно проверяется на метасимволы. В итоге загрязнённые данные поступают в системную функцию open(), которая реализована на C, поэтому при использовании %00 игнорируется казалось бы предопредлённый формат файла (JPG).
... $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"); ...
Обычный запрос: …/script.pl?page=userphoto
Небезопасный запрос: …/script.pl?page=../../../../etc/passwd%00
#лечить можно так $fn = s/\0//g;
При плохом экранировании метасимволов аналогичный ситуация может быть и в PHP скрипте.
... $file = $_GET['file']; require_once("/var/www/images/$file.dat"); ...
Обычный запрос: …/script.php?file=myprofile
Небезопасный запрос: …/script.php?file=../../../etc/passwd%00
//теперь вылечим $string = str_replace( chr( 0 ), '', $string );
Также в PHP некоторые внутренние функции (функции для работы с регулярными выражениями) обрабатывают строки, как C-Strings: ereg, eregi, ereg_replace, eregi_replace, split, spliti, sql_regcase, mb_ereg, mb_eregi_replace и т.п. Незнание этого ньюанса может сильно испортить жизнь web-программисту.
Нижеследующий код дает злоумышленнику большое поле для деятельности:
Нижеследующий код дает злоумышленнику большое поле для деятельности:
$text = (string)@$_GET['text']; if (!ereg('<|>|&', $text)) echo $text;
Обычный запрос: …/script.php?text=bla-bla-bla
Небезопасный запрос: …/script.php?text=%00<script>alert()</script>
Фактически, это полноценная XSS уязвимость (XSS атака – Сross Site Sсripting или межсайтовый скриптинг). А уж придумать как использовать эту XSS дыру не составит большой сложности.
В Java в некоторых функциях тоже имеются схожие уязвимости. Например, в конструкторе класса File(String file) из модуля java.io.File конструктор передаёт принимаемое на вход значение в C-функцию. Рассмотрим наш пример. Пользователь запрашивает доступ к определённому файлу, который имеет расширение ‘.db’ При этом в программе проверяется передаваемая строка: и если строка завершается расширением ‘.db’, тогда создается объект класса File и данные считаются из файла для последующего вывода.
... String fn = request.getParameter("fn"); if (fn.endsWith(".db")){ File f = new File(fn); … }
Обычный запрос: …/script.jsp?fn=report.db
Небезопасный запрос: …/script.jsp?fn=serverlogs.txt%00.db
//лечим fn = fn.replace('\0', '');
По WASC Threat Classification данной уязвимости причислен тип атаки и выдан ID: WASC-28.
Comments
Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/dezhik.ru/wp-includes/class-wp-comment-query.php on line 399