_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №9/2015 ISSN 2410-700Х_
УДК 004.492.2
Шелягов Сергей Александрович
магистрант СевГУ г. Севастополь, РФ E-mail: apollo-master@yandex.ru Кудрявченко Иван Владимирович канд. техн. наук, доцент СевГУ, г. Севастополь, РФ E-mail: inform_kaf@mail.ru
АНАЛИЗ ПРИМЕНЕНИЯ МЕХАНИЗМА SQL-ИНЪЕКЦИИ ДЛЯ ПОЛУЧЕНИЯ
НЕСАНКЦИОНИРОВАННОГО ДОСТУПА К ИНФОРМАЦИИ НА ОСНОВЕ УСЕЧЕНИЕ
ДАННЫ1Х В SQL
Аннотация
Рассматривается вариант атаки на основе уязвимости СУБД, связанной с усечением данных в SQL. Предлагаются пути предотвращения уязвимостей подобного рода в web-ориентированных системах
Ключевые слова SQL-инъекция, несанкционированный доступ, СУБД MySQL
За последнее время востребованность web-приложений значительно возросла, что привело к их усложнению как в плане архитектуры, так и реализации. Всё это выдвинуло новые требования к вопросам, касающимся безопасности. Разумеется, в первую очередь разработка web-приложений связана с обеспечением функционала системы, а безопасность может не являться приоритетной задачей. Это приводит к появлению различного рода уязвимостей, одной из которых является SQL-инъекция [1,с. 167], представляющая собой разновидность атаки для несанкционированного входа в базу данных (БД). Цель такой атаки - получения доступа к конфиденциальной информации и функциональным возможностям СУБД (например, получение доступа к операционной системе сервера, на котором функционирует СУБД). Для осуществления атаки злоумышленник производит вставку вредоносного кода в строки, которые впоследствии передаются на сервер СУБД для дальнейшего синтаксического анализа и выполнения.
В таблицах БД любой столбец имеет свою максимальную длину. При превышении установленного значения длины столбца оставшаяся часть данных усекается без вывода каких-либо предупреждений, если иное не указано в конфигурационном файле [2, с.210].
Для пояснения работы указанной особенности рассмотрим пример управления СУБД MySQL, который показывает, что если злоумышленник обеспечивает усечение данных, передавая СУБД непредвиденно длинные строки, он получает возможность манипулировать результатом.
Создадим БД с таблицей users, имеющей следующую структуру
1) uid, тип - int(11);
2) username, тип - varchar(20);
3) password, тип - varchar (150);
4) status, тип - varchar(50).
Далее напишем скрипт, осуществляющий регистрацию пользователя в системе, в котором выполняется два запроса: первый - проверяющий имя пользователя на существование и второй - добавляющий нового пользователя, если результат первого запроса отрицательный
<?php
include 'connect.php'; if(!isset($_POST['submit'])) {
_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №9/2015 ISSN 2410-700Х_
?>
<h 1>Регистрация<^ 1> <form method="POST"> Логин:
<input type="text" name="username" /> Пароль:
<input type="password" name="password" />
<input type="submit" name="submit" value-'Зарегистрироваться" /> </form> <?php } else {
$username = mysql_escape_string($_POST['username']);
$password = mysql_escape_string($_POST['password']);
$r = $db->query("SELECT * FROM users WHERE username='$username'");
if($r->num_rows) die(мПользователь уже зарегистрирован!");
else {
if($db->query("INSERT INTO users (uid,username,password,status) VALUES (",'$username','".MD5($password)."','user')")) { echo "Регистрация прошла успешно!";
} } }
?>
Предположим, что root — это логин существующего пользователя (рис. 1а), имеющего статус администратора системы.
*—'"Г—► ▼ uid use mame password status
□ J? ¥ X 1 root 827c с ЬО e e a8 a70 6c4c 34a 1EJ 8 91 f84 e 7b admin
а)
▼ uid usemame password status
□ # ¥ X 1 root 827c с ЬО e e a8 a70 Бс4с 34a168 Э1 f84 e 7b admin
□ j/ ¥ X 20 I a709909b1ea5c2bee24248203b1728 a5 user
б)
Рисунок 1 - Вид данных в таблице users: начальных (а) и после успешного выполнения второго
запроса(б)
Для столбца usemame в нашем случае установлена максимальная длина в 20 символов (байт). При регистрации пользователя (рис. 2) с логином «root », записанным с пробелом, первый запрос, выполнится успешно и вернет данные об уже существующем пользователе в БД, т.к. для MySQL «root » с пробелом и «root» — это равнозначные строковые значения. Но если передать строковое значение, содержащее «root» (4 байта) и 16 пробелов (16 байт), к которым добавить любое количество различных символов (в примере добавлен один символ «z» , что дает значение 21 байт), то первый запрос вернет ЛОЖЬ, т.к. пользователя с указанным именем не существует. А вот второй запрос успешно выполнится, причем символ «z» будет отсечен и в таблице users появится новая запись, содержащая имя пользователя root с шестнадцатью пробелами (рис. 1б).
МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №9/2015 ISSN 2410-700Х
Рисунок 2 - Регистрация пользователя root с шестнадцатью пробелами
Дальнейшая реализация данной уязвимости будет зависеть от способа осуществления авторизации пользователей. Если первым запросом проверяется соответствие пароля, а вторым извлекаются данные пользователя и впоследствии назначается его сессия, то уязвимость имеет место. Т.е. код скрипта авторизации атакующего (поддельного «админа») будет примерно следующий: <?php
include 'connect.php';
if(!isset($_POST['submit'])) {
?>
<h 1>Авторизация<^ 1> <form method="POST"> Логин:
<input type="text" name="username" /> Пароль:
<input type="password" name="password" />
<input type="submit" name="submit" value-'Войти" />
</form>
<?php
} else {
$username = mysql_escape_string($_POST['username']); $password = mysql_escape_string($_POST['password']); $userdata = null;
$query = $db->query("SELECT username FROM users WHERE username = '$username'
AND password ='".MD5($password)......);
if ($query->num_rows) { $query = $db->query("SELECT * FROM users WHERE username = '$username'"); $userdata = $query->fetch_array();
}
echo "<pre>"; print_r($userdata);
echo "</pre>"; }
Таким образом, проверка на соответствие пароля будет проведена только для атакующего, а вот второй запрос вернет уже две записи, причем первым элементом в массиве будет запись настоящего администратора, что приведет к повышению прав поддельного «админа» (рис. 3).
МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №9/2015 ISSN 2410-700Х ^ fl php.lc/login.php
Array (
[G] => 1 [uid] => 1
[1] => icct [username] => icct
[2] => S27ccbGeea5a706c4c34al6B91f54e7b [password] => E27ccbDeea3a7D6c4c34al6B91f34e7b
[3] => admin [status] => admin
)
Рисунок 3 - Вывод данных при успешной авторизации
Рассмотренный вид уязвимости может возникнуть в самых неожиданных местах, т.к. веб-разработчики обычно недостаточно знакомы с особенностями языков C и C++, на которых написаны интерпретаторы PHP.
Главной мерой, направленной на предотвращение подобного рода уязвимостей, является проверка данных на длину перед осуществлением запроса. Кроме этого, неуязвимы перед данной атакой уникальные поля (UNIQUE KEY) и поля с индексами [2, c. 65]. Список использованной литературы:
1. Фленов М. Е. Web-сервер глазами хакера / М.Е. Фленов. - 2-е изд., перераб. и доп. - СПб.: БХВ-Петербург, 2009. - 320 с.
2. Гольцман В.И. MySQL 5.0. Библиотека программиста / В.И. Гольцман - СПб.: Питер, 2010. - 253 с.
© С.А. Шелягов, И.В. Кудрявченко, 2015