Как работает атака SQL Injection

{title}

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

Термин « внедрение» относится к внедрению или добавлению операторов SQL в запрос, который приложение выполняет к базе данных, это выполняется с использованием любого ввода данных, который приложение запрашивает прямо или косвенно у пользователя, к которому мы непосредственно обращаемся. Пример для формирования полей, в которые пользователь вводит определенные данные, косвенно это могут быть параметры, которые передаются через URL (GET). Целью введения операторов SQL в запрос является изменение логики этого запроса для удобства или результата, который будет возвращен базой данных.

{title}

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

 $ username = $ _POST ['username']; $ password = $ _POST ['password']; $ sql = "SELECT * FROM пользователей WHERE username = '$ username' AND password = '$ password'"; 
Как мы видим, имя пользователя и пароль, введенные в переменных username и password, сначала сохраняются, затем эти значения включаются в запрос, который будет отправлен в базу данных, чтобы проверить, существует ли указанный пользователь. Предположим, что в нашем примере пользователь вводит в качестве имени пользователя admin и пароля pass123, когда форма отправляется, сформированный запрос будет следующим:
 ВЫБЕРИТЕ * ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ username = 'admin' И пароль = 'pass123' 
Как мы видим, при вводе входных данных они оставляются в одинарных кавычках, чтобы показать, что это текстовая строка. Этот запрос будет отправлен в базу данных и вернет результат с данными указанного пользователя, если он существует, и доступ к приватной области будет разрешен, в противном случае он вернет пустой результат, и в доступе будет отказано.

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

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

Давайте посмотрим, как формируется запрос, если мы введем следующий код SQL в поле пароля:

{title}

Когда запрос сформирован, он будет выглядеть следующим образом:

 ВЫБЕРИТЕ * ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ username = 'hacker' И пароль = '' или 1 = 1 # ' 
Важно обратить внимание, что вставленный код находится между одинарными кавычками, которые содержат пароль, одинарная кавычка в начале вставленного кода отвечает за завершение кавычки в части запроса password = ', таким образом, мы получаем Временно следующий запрос:
 ВЫБЕРИТЕ * ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ username = 'hacker' И пароль = '' 
Этот запрос не будет возвращать результаты в данный момент, потому что нет такого пользователя с такими учетными данными, однако давайте проанализируем остальную часть вставленного кода:
 или 1 = 1 # 
Предложение или 1 = 1 радикально меняет логику запроса, так как, как мы знаем, в запросе, сформированном условным ИЛИ, он вернет истину, когда хотя бы одно из двух выражений выполнено, в нашем случае первое выражение - username = 'hacker' И пароль = '', а второе или 1 = 1, последнее всегда выполняется, то есть 1 всегда равно 1, потому что запрос вернет верный результат.

Наконец, мы должны избавиться от кавычки, которая закрывает предложение, для этого мы можем использовать комментарии, используемые в SQL: #, - (двойной дефис) или / * * / . Таким образом, полный запрос:

 ВЫБЕРИТЕ * ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ username = 'hacker' И пароль = '' или 1 = 1 # ' 
Все после # будет учтено как комментарий и не будет частью запроса.

Чтобы получить действительный результат, в коде есть много других вариантов, которые мы можем вставить, например:

{title}