Перейти к содержимому
Назад к пути
Теория 3 мин чтения

3. Анатомия успешной атаки

Анатомия успешной атаки: Глазами SQL-парсера

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

Аналогия из реальной жизни: представь, что вы пишете текст контракта на бумажной форме, где для каждого поля выделено место. Поле «Получатель: ___», поле «Сумма: ___», поле «Назначение: ___». Если в поле «Получатель» можно вписать сколь угодно длинный текст без разделителей, то хитрый клиент впишет туда: «Иван Иванов, а также прошу провести второй перевод на $1000000 на счёт 12345». Когда бухгалтер обрабатывает контракт, он не видит границ полей — просто читает текст слева направо и выполняет все указания. SQL-инъекция работает ровно так же: атакующий «выходит за границы» поля username с помощью кавычки и комментария, и добавляет свои инструкции в сам текст SQL-запроса.

Разберем по шагам, как конструируется классическая полезная нагрузка и почему база данных послушно её исполняет.


Как это выглядит пошагово

Представьте эндпоинт Go для входа в систему. Он берет username и password, формирует строку через fmt.Sprintf и отправляет в базу:

// ❌ УЯЗВИМО: Конкатенация
query := fmt.Sprintf("SELECT id FROM users WHERE user='%s' AND pass='%s'", u, p)

Шаг 1: Нормальная работа (Ничего особенного)

  1. Пользователь вводит: user=admin, pass=12345
  2. Переменная query в Go: SELECT id FROM users WHERE user='admin' AND pass='12345'
  3. SQL-парсер видит два условия (username и password) и возвращает ID, если они совпали.

Шаг 2: Ввод хакера (Начало атаки)

  1. Хакер вводит в поле user: admin' -- (админ, кавычка, пробел, два тире).
  2. Хакер вводит в поле pass: чего-нибудь.

Шаг 3: Момент «склеивания» в Go

Переменная query теперь выглядит так: SELECT id FROM users WHERE user='admin' --' AND pass='чего-нибудь'

Обрати внимание на момент «склеивания» — это критическая точка. Go-runtime не делает никакой магической проверки безопасности. Функция fmt.Sprintf это обычная string formatter, как printf в C — она просто подставляет аргументы в шаблон. Нет никакого «сигнала из БД», что часть строки опасна. Уязвимость рождается в этой бесхитростной операции подстановки, и существует от момента её выполнения до отправки в базу. Дальше уже поздно — SQL-парсер базы получает готовую строку и просто исполняет.


Почему это сработало? (Роль кавычек и комментариев)

Разберем, как SQL-парсер разбирает эту строку:

Часть запроса Что видит парсер? Описание
SELECT id FROM users Команда Нужно достать данные
WHERE user='admin' Условие 1 Найти пользователя 'admin'
' Закрытие данных Хакер закрыл строку сам!
-- Комментарий ВСЁ ЧТО ДАЛЬШЕ — СМУСЛИ!
' AND pass=... Мусор Эти условия база проигнорирует

Визуализация: Исходный SQL vs Модифицированный

Хакер "обрезал" кусок вашего запроса прямо посреди выполнения. Теперь база данных выполнит только: SELECT id FROM users WHERE user='admin'

РЕЗУЛЬТАТ: АВТОРИЗАЦИЯ ВЫПОЛНЕНА БЕЗ ПАРОЛЯ. Вы только что пропустили хакера в аккаунт администратора.

Это authentication bypass — один из самых частых сценариев SQLi в реальных инцидентах. По данным OWASP, около 60% успешных SQL-инъекций в production-системах используются именно для обхода аутентификации, а не для извлечения данных. Логика проста: получив админский аккаунт, атакующий уже легитимно делает всё остальное через UI, не оставляя следов SQL-инъекции в логах. Это идеальное «прикрытие» для дальнейших действий.


Самые популярные символы атаки

Никогда не забывайте про эту троицу:

  • ' (одиночная кавычка) — выход за границы строковых данных.
  • -- (два тире и пробел) — комментарий в PostgreSQL/MySQL (все после этого игнорируется).
  • # (решетка) — комментарий в MySQL.

Дополнительные spec-символы: /* ... */ (block comment, работает во всех СУБД); ; (statement terminator — позволяет начать новый SQL-запрос внутри текущего); \x00 (null-byte — в некоторых старых драйверах обрывает строку); двойная кавычка " (в PostgreSQL — кавычка identifier, в MySQL — может быть строкой в зависимости от sql_mode). Понимание этих символов критично для написания payload, а для defender'а — для понимания, что blacklist-фильтр всегда что-нибудь упускает.


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

Defence: одна замена db.Query(fmt.Sprintf(...)) на db.Query("SELECT ... WHERE user = ? AND pass = ?", u, p) закрывает уязвимость полностью. Драйвер базы передаст параметры через bind-механизм, и любые кавычки/комментарии в значениях останутся внутри значений, не достигая парсера. Эта одна строка кода — разница между уязвимым и безопасным приложением. Соответствие стандартам: CWE-89 SQL Injection; OWASP Top 10 A03:2021; PCI-DSS 6.5.1.

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

Продолжить чтение

Что бы прочитать модуль полностью, зарегистрируйтесь/войдите на платформу

Когда закончишь — отметь раздел, чтобы продолжить.

🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru