MySQL Injection - Используйте запрос SELECT, чтобы ОБНОВИТЬ / УДАЛИТЬ - PullRequest
8 голосов
/ 23 апреля 2011

У меня есть один простой вопрос: скажем, есть сайт с запросом вроде:

SELECT id, name, message FROM messages WHERE id = $_GET['q'].

Есть ли способ получить что-то обновленное / удаленное в базе данных (MySQL)?До сих пор я никогда не видел инъекцию, которая могла бы удалять / обновлять с помощью SELECT-запроса , поэтому возможно ли это?

Ответы [ 4 ]

6 голосов
/ 21 декабря 2017

Прежде чем непосредственно ответить на вопрос, стоит отметить, что даже если злоумышленник может только прочитать данных, которые он не должен иметь, это обычно все еще очень плохо. Учтите, что используя JOIN s и SELECT ing из системных таблиц (например, mysql.innodb_table_stats), злоумышленник, который начинает с SELECT инъекции и , не имея никаких других знаний о вашей базе данных , может сопоставить вашу схему а затем отфильтровать все данные, которые у вас есть в MySQL. Для подавляющего большинства баз данных и приложений это уже представляет собой катастрофическую дыру в безопасности.

Но чтобы ответить прямо на этот вопрос: я знаю несколько способов, которыми инъекция в MySQL SELECT может использоваться для изменения данных. К счастью, все они требуют разумных необычных обстоятельств, чтобы быть возможными. Все приведенные ниже примеры инъекций приведены относительно примера инъецируемого запроса из вопроса:

SELECT id, name, message FROM messages WHERE id = $_GET['q']

1. «Сложенные» или «пакетные» запросы.

Классическая техника инъекции, заключающаяся в добавлении всего другого утверждения после того, как оно вводится. Как предложено в другом ответе здесь , вы можете установить $_GET['q'] в 1; DELETE FROM users; --, чтобы запрос формировал два оператора, которые выполняются последовательно, второй из которых удаляет все в таблице users.

В смягчении

Большинство коннекторов MySQL - особенно включая функции PHP * (не рекомендуется) mysql_* и (не рекомендуется) mysqli_* - вообще не поддерживают стековые или пакетные запросы, поэтому такая атака просто не работает. Тем не менее, некоторые do - особенно включая PHP PDO-разъем (хотя поддержку можно отключить для повышения безопасности ).

2. Использование пользовательских функций

Функции могут вызываться из SELECT и могут изменять данные. Если в базе данных была создана функция изменения данных, вы можете сделать так, чтобы SELECT вызывал ее, например, передав 0 OR SOME_FUNCTION_NAME() в качестве значения $_GET['q'].

В смягчении

Большинство баз данных не содержат пользовательских функций, не говоря уже об изменении данных, и поэтому вообще не предоставляют возможности для выполнения такого рода эксплойтов.

3. Запись в файлы

Как описано в статье Мухаймина Дзульфакара (несколько самонадеянно названной) Advanced MySQL Exploitation , вы можете использовать предложения INTO OUTFILE или INTO DUMPFILE для выбора MySQL для выгрузки результата в файл. Поскольку при использовании UNION любой произвольный результат может быть SELECT ed, это позволяет писать новые файлы с произвольным содержимым в любом месте, к которому может иметь доступ пользователь, запускающий mysqld. Вероятно, это можно использовать не только для изменения данных в базе данных MySQL, но и для получения доступа оболочки к серверу, на котором он выполняется, например, путем написания PHP-скрипта в webroot и последующего запроса к нему, если Сервер MySQL размещается совместно с сервером PHP.

В смягчении

Множество факторов снижает практическую применимость этой впечатляюще звучащей атаки:

  • MySQL никогда не позволит вам использовать INTO OUTFILE или INTO DUMPFILE для перезаписи существующего файла или записи в папку, которая не существует. Это предотвращает такие атаки, как создание папки .ssh с закрытым ключом в домашнем каталоге пользователя mysql с последующим SSH-подключением или перезапись самого двоичного файла mysqld вредоносной версией и ожидание перезапуска сервера.
  • Любой наполовину приличный установочный пакет настроит специального пользователя (обычно с именем mysql) для запуска mysqld и предоставит этому пользователю только очень ограниченные разрешения. Как таковой, он не должен иметь возможность записи в большинство мест в файловой системе - и, конечно, обычно не должен иметь возможность делать такие вещи, как запись в webroot веб-приложения.
  • Современные установки MySQL поставляются с --secure-file-priv, установленными по умолчанию, что предотвращает запись MySQL в любое место, кроме назначенного каталога импорта / экспорта данных, и, таким образом, делает эту атаку почти полностью бессильной ... если только владелец сервера намеренно отключил его. К счастью, никто никогда не отключит такую ​​функцию безопасности, как эта, - очевидно, это будет - о, не бери в голову .

4. Вызов функции sys_exec() из lib_mysqludf_sys для запуска произвольных команд оболочки

Существует расширение MySQL под названием lib_mysqludf_sys, которое - судя по его звездам на GitHub и - быстрый поиск по переполнению стека - имеет как минимум несколько сотен пользователей. Он добавляет функцию с именем sys_exec, которая запускает команды оболочки. Как отмечено в # 2, функции можно вызывать из SELECT; последствия, надеюсь, очевидны. По словам источника , эта функция "может представлять угрозу безопасности" .

В смягчении

В большинстве систем это расширение не установлено.

6 голосов
/ 23 апреля 2011

Если вы говорите, что используете mysql_query, который не поддерживает несколько запросов, вы не можете напрямую добавить DELETE / UPDATE / INSERT, но возможно изменить данные при некоторых обстоятельствах. Например, допустим, у вас есть следующая функция

DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `testP`()
RETURNS int(11)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''  
BEGIN      
  DELETE FROM test2;
  return 1;
END //

Теперь вы можете вызвать эту функцию в SELECT:
SELECT id, name, message FROM messages WHERE id = NULL OR testP() (id = NULL - всегда NULL (FALSE), поэтому testP () всегда выполняется.

2 голосов
/ 23 апреля 2011

Зависит от используемого вами коннектора СУБД. Большую часть времени ваш сценарий не должен быть возможен, но при определенных обстоятельствах он может работать. Для получения более подробной информации вы должны взглянуть на главы 4 и 5 из Blackhat-Paper Advanced MySQL Exploitation .

0 голосов
/ 23 апреля 2011

Да, это возможно.

$ _ GET ['q'] будет содержать 1; DELETE FROM users; --

SELECT id, name, message FROM messages WHERE id = 1; DELETE FROM users; -- whatever here');
...