Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #47, ОКТЯБРЬ 2004 г.

База данных под прицелом

Крис Касперски aka мыщъх

Спецвыпуск: Хакер, номер #047, стр. 047-064-3


Допустим, пользователь введет KPNC/passwd. Тогда строка запроса будет выглядеть так: "select * from userTable where login = 'KPNC' and password = 'passwd'".

Если такой логин/пароль действительно присутствует в базе, функция сообщает идентификатор результата, в противном случае возвращается FALSE.

Хочешь войти в систему под именем другого пользователя, зная его логин, но не зная пароль? Воспользуйся тем, что механизм интерполяции позволяет атакующему воздействовать на строку запроса, видоизменяя ее по своему усмотрению. Посмотрим, что произойдет, если вместо пароля ввести последовательность "fuck' or '1'= '1" (без кавычек): "select * from userTable where login = 'KPNC' and password = 'fuck' or '1' = '1'".

Смотри: кавычка, стоящая после fuck, замкнула пользовательский пароль, а весь последующий ввод попал в логическое выражение, навязанное базе данных атакующим. Поскольку один всегда равен одному, запрос будет считаться выполненным при любом введенном пароле и SQL-сервер возвратит все-все-все записи из таблицы (в том числе и не относящиеся к логину KPNC)!

Рассмотрим другой пример: "SELECT * FROM userTable WHERE msg='$msg' AND ID=669".

Здесь msg – номер сообщения, извлекаемого из базы, а ID – идентификатор пользователя, автоматически подставляемый скриптом в строку запроса и непосредственно не связанный с пользовательским вводом. Константная переменная использована по соображениям наглядности, в конечном скрипте будет, скорее всего, использована конструкция типа: ID='$userID'. Чтобы получить доступ к остальным полям базы (а не только к тем, чей ID равен 669), необходимо отсечь последнее логическое условие. Это можно сделать, внедрив в строку пользовательского ввода символы комментария ("--" и "/*" для MS SQL и MySQL соответственно). Текст, расположенный правее символов комментария, игнорируется. Если вместо номера сообщения ввести "1' AND ID=666 --", строка запроса примет следующий вид: "SELECT * FROM userTable WHERE msg='1' and ID= 666 --' AND ID=669" .

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

Причем одним лишь видоизменением полей SELECT'а дело не огранивается, и существует угроза прорыва за его пределы. Некоторые SQL-сервера поддерживают возможность задания нескольких команд в одной строке, разделяя их знаком ";", что позволяет атакующему выполнить любые SQL-команды, какие ему только заблагорассудится. Например, последовательность " '; DROP TABLE 'userTable' --", введенная в качестве имени пользователя или пароля, удаляет всю userTable!

Еще атакующий может сохранять часть таблицы в файл, подсовывая базе данных запрос типа "SELECT * FROM userTable INTO OUTFILE 'FileName'". Соответствующий ему URL уязвимого скрипта может выглядеть, например, так: www.victim.com/admin.php?op=login&pwd=123&aid=Admin'%20INTO%20OUTFILE%20'/path_to_file/pwd.txt, где path_to_file – путь к файлу pwd.txt, в который будет записан админовский пароль. Удобное средство для похищения данных, не так ли? Главное – размесить файл в таком месте, откуда его потом будет можно беспрепятственно утянуть, например, в одном из публичных WWW-каталогов. Тогда полный путь к файлу должен выглядеть приблизительно как: "../../../../WWW/myfile.txt" (точная форма запроса зависит от конфигурации сервера). Но это еще только цветочки! Возможность создания файлов на сервере позволяет засылать на атакуемую машину собственные скрипты (например, скрипт, дающий удаленный shell – "<? passthru($cmd) ?> "). Естественно, максимальный размер скрипта ограничен предельно допустимой длиной формы пользовательского ввода, но это ограничение зачастую удается обойти ручным формированием запроса в URL или использованием SQL-команды INSERT INTO, добавляющей новые записи в таблицу.

Назад на стр. 047-064-2  Содержание  Вперед на стр. 047-064-4