- [Квест] Как хакнуть форму? Sql инъекции.
- SQL инъекции
- «Слепые» инъекции
- Более серьезные способы
- _GET параметры
- Экранирование символов в строке
- Защита
- Использование mysql_real_escape_string
- Использование MySQLi
- Использование PDO
- Использование ORM
- Выводы
- Последние посты
- 5 главных уязвимостей PHP безопасности
- SQL Injection
- Cross site scripting
- Откровения в исходном коде
- Удаленный запуск файлов
- Угон сессий
[Квест] Как хакнуть форму? Sql инъекции.
Эта статья является статьёй-квестом. Мы желаем вам успехов в его прохождении. Итоги вашего прохождения будут опубликованы позже (следите за новостями в соц. сетях), а также всем прошедшим в дальнейшем будет выслан инвайт для регистрации на сайте.
Ставьте лайки, делитесь с друзьями и коллегами, репостите в соц.сетях.
Все программисты читали или по крайней мере слышали о методах взлома безопасности веб-сайта. Или даже столкнулись с этой проблемой. С другой стороны, бесконечна фантазия тех, кто хочет сломать сайт, поэтому все узкие места должны быть хорошо защищены. Вот почему я хотел бы начать серию коротких статей, где будут представлены основные методы и приемы взлома веб-сайтов.
В первой статье я хотел бы описать и разъяснить некоторые общие методы взлома одного из самых уязвимых частей сайта — форм. Я буду подробно останавливаться на том, как использовать эти методы и как предотвратить атаки, а также расскажу о тестировании безопасности.
SQL инъекции
SQl-инъекция — это такая техника, когда злоумышленник вводит команды SQL в input поле на веб-странице. Этим imput`ом может быть что угодно — текстовое поле в форме, параметры _GET и _POST, cookies и т. д. Этот метод был весьма эффективным до появления фреймворков в мире PHP. Но этот способ взлома может быть по-прежнему опасен, если вы не используете ORM или какие-либо еще расширения для data object. Почему? Из-за способа передачи параметров в SQL запрос.
«Слепые» инъекции
Давайте начнем с классического примера SQL-statement`а, возвращающего пользователя по его логину и хешу от пароля (страница входа)
mysql_query('SELECT id, login FROM users WHERE login = ? and password = hash(?)');
Я подставил вопросительные знаки в выражение из-за различных вариаций этого решения. Первый вариант, на мой взгляд, самый уязвимый:
mysql_query('SELECT id, login FROM users WHERE login = "' . $login . '" and password = hash("' . $password . '")');
В этом случае в коде нет проверки на ввод неправильных данных. Значения передаются прямо из формы ввода в SQL запрос. В самом лучшем случае пользователь введет здесь свои логин и пароль. Что случится в худшем случае? Давайте попробуем хакнуть эту форму. Это можно сделать, передав «подготовленные» данные. Попытаемся войти как первый пользователь из базы данных, а в большинстве случаев — это админский аккаунт. Для этого, передадим специальную строку вместо ввода логина:
Первая кавычка может быть и одинарной, поэтому одной попыткой взлома можно не обойтись. В конце стоят точка с запятой и два дефиса, чтобы всё, что идёт после превратилось в комментарий. В результате будет выполнен следующий SQL запрос:
SELECT id, login FROM users WHERE login = “;” OR 1=1 LIMIT 0,1; – and password = hash(“;Some password”)
Он вернет первого пользователя из базы данных и, возможно, залогинится под ним в приложении. Хорошим ходом будет добавить LIMIT, чтобы входить под каждым отдельным пользователем. Это единственное, что нужно, чтобы пройти по каждому значению.
Более серьезные способы
В предыдущем примере всё не так уж страшно. Возможности в админской панели управления всегда имеют ограничения и потребуется реально много работы, чтобы поломать сайт. А вот атака через SQL инъекции может привести к куда большим повреждениям системы. Задумайтесь, сколько приложений создаются с главной таблицей ‘users’ , и что будет, если злоумышленник введет такой код в незащищённую форму:
My favorite login'; DROP TABLE users; --
Таблица ‘users’ будет удалена. Это одна из причин почаще делать бэкапы баз данных.
_GET параметры
Все параметры, заполненные через форму, передаются на сервер одним из двух методов — GET или POST. Наиболее распространенный параметр, передаваемый через GET — id. Это одно из самых уязвимых мест для атак, при этом неважно, какого вида урл вы используете — ` http://example.com/users/?id=1 `, или ` http://example.com/users/1 `, или ` http://. /. /post/35 `.
Что произойдет, если мы подставим в урл следующий код?
http://example.com/users/?id=1 AND 1=0 UNION SELECT 1,concat(login,password), 3,4,5,6 FROM users WHERE --
Вероятно, такой запрос вернет нам логин пользователя и. хеш от его пароля. Первая часть запроса `AND 1=0` превращает то, что перед ним в false, соответственно никаких записей не будет получено. А вторая часть запроса вернет данные в виде prepared data. А так как первым параметром идет id, следующим будет логин пользователя и хеш его пароля и еще сколько-то параметров. Существует множество программ, с помощью брутфорса декодирующих такой пароль, как в примере. А так как пользователь может использовать один и тот же пароль для разных сервисов, можно получить доступ и к ним.
И вот что любопытно: от такого способа атаки совершенно невозможно защититься методами вроде `mysql_real_escape_string`, `addslashes` и.т. д. В принципе, нет способа избежать такой атаки, поэтому, если параметры будут передаваться так:
'SELECT id, login, email, param1 FROM users WHERE . addslashes($_GET['id']);'
Экранирование символов в строке
Когда я был новичком в программировании, мне было тяжело работать с кодировками. Я не понимал, в чем между ними различие, зачем использовать UTF-8, когда нужно UTF-16, почему база данных постоянно устанавливает кодировку в latin1. Когда я наконец начал всё это понимать, то обнаружил, что проблем станет меньше, если хранить всё в одном стандарте кодирования. Разбираясь со всем этим, я заметил также и проблемы безопасности, возникающие при преобразовании из одной кодировки в другую.
Проблем, описанных в большинстве предыдущих примеров, можно избежать, используя одинарные кавычки в запросах. Если вы используете addslashes() , атаки через SQL-инъекции, построенные на использовании одинарных кавычек, экранируемых обратным слэшем, потерпят неудачу. Но такая атака может пройти, если просто подставить символ с кодом 0xbf27 , addslashes() преобразует его в символ с кодом 0xbf5c27 – а это вполне валидный символ одинарной кавычки. Другими словами, `뼧` пройдет через addslashes() , а потом маппинг MySQL конвертирует его в два символа 0xbf (¿) и 0x27 (‘).
"SELECT * FROM users WHERE login = '"; . addslashes($_GET['login']) . ";'";
Этот пример можно хакнуть, передав 뼧 or 1=1; — в поле логина в форме. Движок SQL сгенерит конечный запрос так:
SELECT * FROM users WHERE login = '¿' OR 1=1; --
И вернет первого пользователя из БД.
Защита
Как же защитить приложение? Есть куча способов, применение которых не сделает приложение совсем неуязвимым, но хотя бы повысит его защищенность.
Использование mysql_real_escape_string
Функция addslashes() ненадежна, так как не предусматривает многие случаи взлома. У mysql_real_escape_string нет таких проблем
Использование MySQLi
Это расширение для MySQL умеет работать со связанными параметрами:
$stmt = $db->prepare('update uets set parameter = ? where $name, $id); $stmt->execute();
Использование PDO
Длинный способ подстановки параметров:
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)'); $stmt->bindParam(':name', $name); $stmt->bindParam(':value', $value); // insert one row $name = 'one'; $value = 1; $stmt->execute();
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->prepare('UPDATE people SET name = :new_name WHERE array('new_name' => $name, 'id' => $id) );
Использование ORM
Используйте ORM и PDO и связывайте (используйте bind) параметры. Избегайте SQL в коде, если вы видите в коде SQL, значит, с ним что-то не так.
ORM позаботится о безопасности в самых узких местах в коде и о валидации параметров.
Выводы
Цель этой серии не предоставить полное руководство по взлому сайтов, а обеспечить безопасность приложения и предотвращение атак из любого источника. Я постарался написать эту статью не только для программистов — они должны быть в курсе любых угроз в коде и знать пути, как предотвратить их, но также и для инженеров по качеству — потому, что их работа заключается в том, чтобы отследить и сообщить такие моменты.
Последние посты
- 2023-02-03Новая мажорная версия Flysystem
- 2020-12-31Конечные автоматы для Eloquent
- 2020-12-30Создаём REST API с помощью Laravel Orion
- 2020-12-29При разработке локально используйте queue:listen вместо queue:work
- 2020-12-28Laravel Desktop Notifier
5 главных уязвимостей PHP безопасности
Учитывая тот факт, что взлом некоторых сайтов может принести немалую выгоду, а для того, чтобы его осуществить, преступнику даже не нужно выходить из дома, можно сделать вывод, что взлом сайта – очень заманчивое занятие для преступника. В дополнение к этому, злоумышленники в интернете очень редко несут наказания за свои деяния.Но для того, чтобы взломать ресурс, хакер должен найти уязвимости в его работе. Пяти главным уязвимостям php и будет посвящена данная статья.
SQL Injection
Очень популярным методом взлома сайта среди хакеров является вставка SQL фрагмента вместо URL. В таком случае злоумышленник получает доступ к именам ваших таблиц. Чтобы избежать такого взлома, следует очень внимательно отслеживать все данные, которые присылают вам пользователи. Для борьбы с такими взломами обычно применяют PDO.
Cross site scripting
Так называемый XSS тоже является очень популярным способом взлома. Злоумышленники внедряют опасный код, обычно это JavaScript, в код вашего скрипта PHP. Это становится возможным в случае, когда отображены входные данные пользователей, которые были посланы вам из различных форм, блогов, форумов, чатов и т.д. Если в этих данных содержится вредоносный код, то ваш сайт может быть взломан.
Откровения в исходном коде
Еще одна уязвимость сайтов php – когда злоумышленники, в случае сбоя настроек Apache, могут видеть содержимое и названия ваших файлов. В нормальной ситуации PHP выполняется на стороне сервера, но в случае сбоя код может стать видим обычным пользователям. Этого нельзя допускать, так как прочитав его, злоумышленники могут увидеть доступные файлы или базы данных с важной информацией, такой как, например, учетные данные.
Чтобы не допустить такого взлома, следует более внимательно отнестись к структуре каталогов вашего ресурса. Ни в коем случае не допускайте хранения важных файлов в каталогах, которые доступны всем пользователям, чтобы не допустить возможности, что их увидит кто-то, кроме вас.
Удаленный запуск файлов
Если ваш сайт содержит удаленные файлы, это тоже может стать причиной взлома, если эти файлы не доверенные. Если сайт, на котором хранятся ваши удаленные файлы, был взломан, то их код может быть заменен на вредоносный, который поможет хакерам во взломе вашего сайта. Поэтому нужно очень внимательно относиться к безопасности всех ресурсов, где располагаются ваши файлы.
Если же все-таки взлом стороннего ресурса произошел, то есть довольно простой способ устранить опасность. Для этого вам нужно в php.ini проверить состояние следующих флажков:
— allow_url_fopen. Эта настройка отвечает за то, могут ли внешние файлы быть включены в ваш сайт. По умолчанию это разрешено, чтобы это изменить, кликните по флажку.
— allow_url_include. Вторая настройка определяет, могут ли встроенные функции ссылаться на файлы, расположенные удаленно на других ресурсах.
Угон сессий
Угон случается, когда злоумышленник украл чужой идентификатор сессии и воспользовался им. Этот идентификатор играет роль ключа в защищенном соединении между клиентом и веб-сервером. В PHP этот идентификатор хранится у пользователя. Если ключ был украден, но во время сеанса пользователем не было совершено никаких важных действий, то ничего особо страшного не произойдет. Но если во время сессии пользователь осуществляет, скажем, аутентификацию, это может привести к неприятным последствиям, ведь хакер может завладеть данными для входа в аккаунт. Это особенно важно, если пользователь, совершающий вход, является администратором сайта.
ID сессии очень часто крадут с помощью описанного выше XSS скрипта. Поэтому защита от взлома с помощью XSS убьет сразу двух зайцев, и защитит вас еще и от угона сессий. Хорошим способом защиты именно от угона идентификаторов сессии является их регулярная смена. И чем чаще, тем лучше. Для того, чтобы сменить идентификатор в php вам нужно воспользоваться session_regenerate_id.
В случае, если вы используете PHP 5.2 или выше, то для защиты от угона идентификатора вы можете воспользоваться таким функциями, как:
session.cookie.httpolny и session_set_cookie_parms.
Для того, чтобы обеспечить безопасность вашему проекту, регулярно проводите поиск уязвимостей на php сайте. Ведь, если у вашего ресурса не будет уязвимостей, то хакерам не за что будет зацепиться и вероятность взлома будет крайне мала.
И, конечно, не забывайте, что защита вашего сайта определяется также надёжностью вашего хостинга. АдминВПС всегда заботится о безопасности ваших проектов, независимо от того, располагаются они на виртуальном хостинге или выделенных серверах.