Блог об it, программировании и интернет-маркетинге

Делюсь наблюдениями и личным опытом в области программирования и интернет-маркетинга

Нулевой байт (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.
  • SEO Community Ваау! News2.ru SMI2 Google Bookmarks I.ua Закладки Yandex Ruspace Web-zakladka Zakladok.net delicious БобрДобр.ru Memori.ru rucity.com МоёМесто.ru Mister Wong

    Comments