February 15, 2023

SQLi для начинающих by artrone

Всех приветствую! Сегодня разберем такое понятие, как SQL injection. Для хоть какого-то понимания рекомендуются базовые знания языка SQL.

Итак, что же такое SQL инъекция?

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

SQLi бывают двух видов:

  1. Обычная SQLi
  2. Слепая SQLi

В чем отличие?

При обычной инъекции мы видим результат выполнений запросов, а при слепой- нет.

В рамках данной статьи будет рассмотрен 1-й вид.

Предлагаю рассмотреть пример:

В качестве уязвимого сервиса я буду использовать DVWA из сервиса Metasploitbale2.

Мы имеем страницу с вводом id для получения некой информации.

Как мы видим, на вывод идет 3 колонки: ID, name и surname.

Самая первая вещь, которая должна быть при SQLi, - проверка на уязвимость с помощью базового приема - дописать символ '

Видим, что получили ошибку синтаксиса. Отлично, ведь это значит, что существует уязвимость.

Но как же выглядит стандартный запрос к базе данных?

Если по-русски, то мы говорим: "Выбери имя и фамилию из нашей базы, где id пользователя = 1"

Стоит отметить, что названия аргументов не являются правильными. Это просто демонстрация процесса.

Когда мы разобрались с этим, идем дальше:

Нам нужно узнать количество столбцов на выходе. Сделать это можно следующими способами:

1. Order by возвращает столбцы в отсортированном виде. Если столбов будет больше, чем используется в запросе, то возникнет ошибка.

Как выглядит наш запрос в данном случае?

Опять же словами: "Выбери то-то то-то из такой-то таблицы и отсортируй по колонками 1 и 2"

2. Group by возвращает столбцы в сгруппированном виде. Аналогия та же: если столбцов больше- ошибка

3. Union select null . Аналогия, опять же такая же, но есть важное отличие: если количество столбцов указанное в нашей инъекции (количество null) совпадает с верным количеством изначального запроса, то вывод будет пустым:

Ну и сам запрос выглядит так:

Думаю, с этим понятно.

На данном шаге может возникнуть простой вопрос: "Что такое union?"

Union / Union all - это операторы, которые позволяют объединить 2 разных запроса в 1.

Отличие Union и Union all заключается в конечном результате- при Union all в выводе будут присутствовать повторяющиеся строки.

Проверка уязвимых столбцов также является важным моментом:

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

Если бы у нас было, допустим, 3 колонки и была уязвима лишь одна (пусть это будет вторая колонка), то при запросе 1'union select 1111,2222,3333— - вывелась бы лишь та колонка, которая является уязвимой - 2222.

Применяем наши знания

Давайте узнаем название нашей БД и ее версию:

Я проговорю запрос для понимания:

"Выбери то-то то-то из такой-то таблицы И выбери название и версию БД"

Сейчас будут страшные и непонятные вещи, поэтому готовьтесь))))

Давайте упростим запрос, указав нашу БД - "dvwa", ограничив показ результатов:

Что это такое? Всё просто: тут мы вывели таблицы из нашей базы данных.

Как выглядит запрос?

1'union select table_name,2 from information_schema.tables where table_schema = database()— -

"Выбери имя таблицы, 2 из наших таблиц, где table_schema(Этот столбец содержит название базы данных, которой принадлежит таблица)= названию БД"

Важный момент!!!!

Вместо database() мы можем написать "dvwa" и ничего не изменится.

А что такое information_schema?

Это таблица, которая содержит в себе информацию о других таблицах.

Если приводить пример из жизни, то представим такую ситуацию:

У меня есть друг, у которого я хочу спросить какой-то вопрос, но его нет рядом. Тогда я спрашиваю у его мамы его местоположение, чтобы задать этот вопрос. В данном случае- information_schema - это мама друга. Да, тупо, но понятно, я надеюсь)))

В итоге то что?

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

В качестве таблицы, как вы могли увидеть, была таблица "users"

После успешного выполнения запроса, мы замечаем колонки user и password.

Давайте выведем их содержимое:

Тут, я думаю все понятно, но есть один тоже важный момент:
Если, допустим, у вас одна уязвимая колонка (вспоминаем пример с order by) и вы хотите получить данные за 1 запрос, то можно использовать функцию CONCAT()

Вот вам пример:

2 колонки вывелись в одну и отделяются двоеточиями. Удобно, правда?)

Вывод:

SQLi не такая уж и сложная вещь. Всего-то нужно понять смысл запросов и знать, что ты хочешь получить от него.

Данный пример можно было разобрать с помощью того же SQLMap, что было бы гораздо быстрее, но целью данного урока было объяснить вам основные моменты. Надеюсь, мне это удалось и вы что-то поняли. Удачи вам)))
Наш ТГ-канал: https://t.me/hackerblog