Статьи [новый способ] замена нулл-байту в инклудах

Discussion in 'Статьи' started by [Raz0r], 29 Dec 2008.

  1. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    вот еще цифра зависит от getcwd, в общем в сумме имя файла со слешами и с getcwd 4094, те перемещаем скрипт в другое место и соответственно кол-во слешей изменяется.
     
  2. SQLHACK

    SQLHACK Остались только слоны

    Joined:
    27 Sep 2006
    Messages:
    437
    Likes Received:
    372
    Reputations:
    407
    Вообщем написал скрипт для быстрой проверки.

    Складываем в папку z:/home/localhost/www/testinc/
    Скрипт становится доступным по адресу http://www.localhost/testinc/test.php

    Скрипт который запускаем (test.php)
    PHP:
    <?php
    $evilstr 
    "";
    $fp fopen("log.txt","a");
    for (
    $x=0;$x<=500;$x++){
        
    $evilstr .= "<";
        
    $content file_get_contents("http://www.localhost/testinc/inc.php?inc=vuln.txt".$evilstr);
        if (
    preg_match("#(.*)bugworking(.*)#",$content,$matches)){
            echo 
    "http://www.localhost/testinc/inc.php?inc=vuln.txt".$evilstr."\r\n";
            die (
    "Bug working with $x added chars");
        }else{
             
    fputs($fp$content."\r\n\r\n");
        }
    }
    fclose($fp);
    ?>
    Скрипт который инклюдит inc.php ложим туда же

    PHP:
    <?php
    error_reporting
    (E_ALL);
    include(
    $_GET['inc'].".txt");
    ?>
    и ложим файл vuln.txt с содержимым

    PHP:
    -bugworking-
    запускаем в браузере http://www.localhost/testinc/test.php
    Получаю в ответ, что бага работает 216 символов и более.

    Версии
    PHP Version => 5.2.4
    Windows NT XHOME 5.1 build 2600 Build Date хр короче
    Apache 2.2.4

    но стоит прописать абсолютный путь в любом варианте, и больше ни чё не пашет.

    PHP:
    <?php
    error_reporting
    (E_ALL);
    include(
    "Z:/home/localhost/www/testinc/".$_GET['inc'].".txt");
    ?>
    Внимание вопрос. Почему ?
    У кого есть идеи ?
    то есть я не вижу объективных причин не работать с абсолютным путём.
     
    _________________________
    #22 SQLHACK, 30 Dec 2008
    Last edited: 30 Dec 2008
  3. 1ten0.0net1

    1ten0.0net1 Time out

    Joined:
    28 Nov 2005
    Messages:
    473
    Likes Received:
    330
    Reputations:
    389
    Скрипт SQLHACK переделаный под себя не работает. Имхо - с 4.4.0 не работает
     
  4. Spyder

    Spyder Elder - Старейшина

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    копать сорцы пшп?
     
    1 person likes this.
  5. SQLHACK

    SQLHACK Остались только слоны

    Joined:
    27 Sep 2006
    Messages:
    437
    Likes Received:
    372
    Reputations:
    407
    вот проверил несколько функций, как то странно.

    require_once - работает
    require - работает
    include - работает
    include_once - работает
    file_get_contents - не работает
    fopen - не работает
    file - не работает
    readfile - не работает

    почему только функции инклюда подвержены ?
    а Virtual и другие не пашут.
     
    _________________________
  6. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Угу, к тому же они не оч сложные. Надеюсь если их скомпилировать, бага останется. Имхо там гдето тупой оверфлоу должен быть, а длина обусловлена расстоянием до той строки которая фактически передастся в функцию инклуда (или может там отдельно как нибудь текущая дира передаётся и её значение и переписывается этим методом?), но это догадки. Пока времени посмотреть нет :(

    P.S.
    php-5.2.6-Win32 пример от SQLHACK работает, выдаёт "Bug working with 219 added chars".

    P.P.S.
    С абсолютным путём кстати и может неработать, если переписывается имено указатель на текущую директорию, относительно которой относительный путь конвертится в абсолютный. А в случае абсолютного пути, нет необходимости в вычеслении действительного пути.
     
    #26 Qwazar, 30 Dec 2008
    Last edited: 30 Dec 2008
  7. SQLHACK

    SQLHACK Остались только слоны

    Joined:
    27 Sep 2006
    Messages:
    437
    Likes Received:
    372
    Reputations:
    407
    есил бы бы был оверфлов то пхп бы падал ,имхо , а тут всё корректно обрабатывается при любом количестве символов в пути
     
    _________________________
  8. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Не обязательно должен падать, мож строка где нибудь обрезается после какого нибудь предела, а всё что переписывается отношения к исполняемому коду не имеет.

    А вот ещё один признак того, что скорее всего переписывается результат функции getcwd (получение текущего каталога), ну и причина того, что абсолютные пути не пашут:
    P.S.
    Вот тут: http://bugs.php.net/bug.php?id=41822
    написано, что include с относительным путём вызывает getcwd.
     
    #28 Qwazar, 30 Dec 2008
    Last edited: 30 Dec 2008
  9. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    По ходу уязвимость где-то в этих функциях:

    PHP:
    static int php_stream_open_for_zend(const char *filenamezend_file_handle *handle TSRMLS_DC/* {{{ */
    {
        return 
    php_stream_open_for_zend_ex(filenamehandleENFORCE_SAFE_MODE|USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
    }
    /* }}} */

    PHPAPI int php_stream_open_for_zend_ex(const char *filenamezend_file_handle *handleint mode TSRMLS_DC/* {{{ */
    {
        
    php_stream *stream;

        
    stream php_stream_open_wrapper((char *)filename"rb"mode, &handle->opened_path);

        if (
    stream) {
            
    handle->type ZEND_HANDLE_STREAM;
            
    handle->filename = (char*)filename;
            
    handle->free_filename 0;
            
    handle->handle.stream.handle stream;
            
    handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read;
            
    handle->handle.stream.closer stream_closer_for_zend;
            
    handle->handle.stream.fteller stream_fteller_for_zend;
            
    handle->handle.stream.interactive 0;
            
    /* suppress warning if this stream is not explicitly closed */
            
    php_stream_auto_cleanup(stream);

            return 
    SUCCESS;
        }
        return 
    FAILURE;
    }

    php_stream_open_wrapper(); - предпологаю, что уязвимость где-то в ней
     
    #29 Chaak, 30 Dec 2008
    Last edited: 30 Dec 2008
  10. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Я бы посмотрел ещё, где &handle->opened_path вычисляется..

    З.Ы.
    Второй файл что ты выложил - не в тему, он для GZIP.
     
  11. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Сейчас сорцы качаю.
    Потому что ТОЛЬКО функции инклуда, вызывают функцию getcwd, для вычисления абсолютного пути по относительному :) (хех, я был прав, в том что проблема с вычислением пути по текущему, посмотрим прав ли в остальном)
     
    3 people like this.
  12. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    А что если какая-то логическая ошибка => как-бы получается что функция выполняется, но значение параметра становится = '\0', что значит конец строки => обход magic_quotes'ов?


    Вот кое-чот интересное! Похоже на переполнение буфера! Возможно длина строки неправильно расчитывается
    PHP:
    /* no docref given but function is known (the default) */
        
    if (!docref && is_function) {
            
    int doclen;
            if (
    space[0] == '\0') {
                
    doclen spprintf(&docref_buf0"function.%s", function);
            } else {
                
    doclen spprintf(&docref_buf0"%s.%s"class_name, function);
            }
            while((
    strchr(docref_buf'_')) != NULL) {
                *
    '-';
            }
            
    docref php_strtolower(docref_bufdoclen);
        }
     
    #32 Chaak, 30 Dec 2008
    Last edited: 30 Dec 2008
    1 person likes this.
  13. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    ChaaK, ты в какието дебри полез :) Чтото я этот кусок нигде в инклуде не видел.
     
  14. Kakoytoxaker

    Kakoytoxaker Elder - Старейшина

    Joined:
    18 Feb 2008
    Messages:
    1,038
    Likes Received:
    1,139
    Reputations:
    350
    Тоже потестил, вот результат :
    Конфигурация:
    WinXP 32 bit, PHP 5.2.4, Апач 2.2.4

    Работает
    Цифра это минимальное кол-во символов

    "."-218
    " "пробел - никакой реакции
    "<"-218
    ">"-218

    С абсолютным путём не пашет Пока тестил только в include

    И обнаружился ещё один символ, с которым работает:
    "+"-218
     
    1 person likes this.
  15. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    кароч:
    файл plain_wrappers.c
    функция _php_stream_fopen_with_path:
    там же функция _php_stream_fopen (тоже что php_stream_fopen_rel)
    fname уже нормальный
    дальше файл fopen-wrappers.c функция expand_filepath:
    real_path уже нормальный, MAXPATHLEN везде (не знаю как там у вас в виндах) = 4096;
    ну что видно из этого идет везде сначала
    xxx.php/////////..../////////////.txt
    потом по MAXPATHLEN обрезается до
    xxx.php/////////..../////////////.
    дальше обрабатывается видимо функцией virtual_file_ex , она возвращает false и изменяет new_state.
     
    #35 ShAnKaR, 30 Dec 2008
    Last edited: 30 Dec 2008
    2 people like this.
  16. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    у меня вот:
    PHP:
    <?php
    $f
    ="aaaa.php".str_repeat('/',$argv[1]);
    $z=getcwd();
    $u=$f.'.fffffffff';
    $v=$z.'/'.$f;
    print 
    strlen($v)."\n";
    require(
    $u);
    ?> 
    [test@localhost cli]$ ./php ./test.php 4047
    без точки не работает.

    ты писал что папка должна существовать.
    у меня выпоняется без этого условия.
     
  17. [Raz0r]

    [Raz0r] Elder - Старейшина

    Joined:
    25 Feb 2007
    Messages:
    425
    Likes Received:
    484
    Reputations:
    295
    FreeBSD 6.3, PHP 5.2.8 - работает без точки, какая у тебя система хоть?
    это относится к linux, хотя это понятие растяжимое ) на все том же FreeBSD 6.3, PHP 5.2.8 через несуществующую папку не инклудится =\
     
  18. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    потом файл tsrm_virtual_cwd.c
    функция virtual_file_ex:
    тут TOKENIZER_STRING у меня равен "/" в винде наверно чтото другое.

    файл tsrm_strtok_r.c
    потом опять файл tsrm_virtual_cwd.c
    функция virtual_file_ex:
    и тут наверно и идет бага:
    ну а символ точка это как раз и есть 'IS_DIRECTORY_CURRENT' , следовательно можно использоывать не только длинную строчку из '/' а ещё и '/.'
    остается конечно не понятно почему без точки в конце не пашет
     
    #38 ShAnKaR, 30 Dec 2008
    Last edited: 30 Dec 2008
    1 person likes this.
  19. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    в винде по идее еще должно проходить с нормальным слешем и обратным:
    проверил php 4.4.9:
    файл streams.c функция _php_stream_fopen_with_path

    VCWD_STAT ( практически стандартная файловая функция stat ) проверяет сначала существует ли файл а потом php уже пытается открыть в пятой такого не заметил, тоесть у меня не заработало на четвертой версии, у вас как?
     
    #39 ShAnKaR, 30 Dec 2008
    Last edited: 21 Feb 2009
    1 person likes this.
  20. ShAnKaR

    ShAnKaR Пачка маргарина

    Joined:
    14 Jul 2005
    Messages:
    904
    Likes Received:
    297
    Reputations:
    553
    вот на php 4 можно так тогда, да и на пятой тоже соответственно:
    existing_dir/..//////////////////////// ... ///////////////////shell.php
    окончание если есть обрежет по maxpathlen тогда