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

4. Извлечение полезной нагрузки

Извлечение полезной нагрузки: Пароли на экране

Разведка завершена, структура запроса ясна. Теперь хакер переходит к финальной стадии — извлечению реальных данных из секретных таблиц. Мы увидим, как простая замена 'a' на осмысленные запросы превращает страницу вашего интернет-магазина в панель управления учетными записями.

После двух предыдущих уроков (определение количества колонок и поиск текстового типа) у атакующего есть всё необходимое: знание схемы запроса и точки внедрения. Финальный шаг — подставить вместо placeholder'ов конкретные SELECT'ы к интересующим его таблицам. С точки зрения базы данных, это абсолютно валидный SQL: UNION-оператор объединяет два SELECT с одинаковым количеством колонок и совместимыми типами, и СУБД возвращает объединённый result set приложению.

Аналогия: представь, что вы заказываете каталог товаров по почте, и почтальон по ошибке вкладывает в конверт ещё и страницы из закрытого справочника личных данных клиентов. Получатель получает «один пакет» — листает каталог, и среди описаний айфонов вдруг видит реальные логины и пароли. Технически конверт цел, печать не сломана — но содержимое содержит то, чего не должно было там быть. UNION-инъекция работает ровно так же: ответ от сервера структурно валиден (HTTP 200, JSON массив товаров), но среди ожидаемых данных подмешаны украденные строки из другой таблицы.

Разберем, как именно происходит подмена данных и почему Go-сервер беспрекословно выводит их пользователю.


1. Механика: "Финальный удар"

Представьте уязвимый запрос в Go-коде: SELECT id, name, price FROM products WHERE category = '%s' (через fmt.Sprintf).

Хакер уже знает, что в запросе 3 колонки, а вторая — текстовая. Он пишет: category = 'Electronics' UNION SELECT 1, password, 3.14 FROM users--

Что произойдет в Go-хендлере:

// ❌ Go просто склеивает...
query := fmt.Sprintf("SELECT id, name, price FROM products WHERE category = 'Electronics' UNION SELECT 1, password, 3.14 FROM users--'")
rows, _ := db.Query(query)
// ...и выводит строки в цикле на страницу

ИТОГ: Вместо названия "iPhone", на сайте напротив каждого товара появится реальный пароль одного из пользователей вашего сайта!

Точнее, на сайте появится bcrypt-хеш пароля (если разработчик хотя бы это сделал правильно) или, в худшем случае, plaintext-пароль (если хранят пароли в открытом виде — что встречается чаще, чем хотелось бы в 2025 году). Атакующий копирует хеш и запускает hashcat с словарём из 10 миллионов паролей — для слабых паролей восстановление занимает минуты. Plaintext-пароли — это мгновенная компрометация всех учёток, плюс credential stuffing атаки на другие сервисы (LinkedIn, корпоративная почта, банк) через переиспользование паролей пользователями.


2. Популярные цели в SQL Injection

Хакеры ищут следующие данные в ваших таблицах:

Цель SQL-код (через UNION) Описание
Версия БД UNION SELECT 1, version(), 3-- Какой эксплойт использовать?
Имена таблиц UNION SELECT 1, tablename, 3... Что еще есть интересного?
Логины UNION SELECT 1, username, 3... Кто администратор?
Пароли UNION SELECT 1, password, 3... Собственно, ключ от двери.

3. Почему это фатальная уязвимость?

Причина — в доверии к данным. Ваш Go-код ожидает, что в name придут данные из таблицы products. Но из-за UNION база подсунула данные из users. Go-сервер ничего не заподозрил и просто вывел этот текст в браузер (или в JSON-ответ приложения).

Это пример более общей проблемы под названием type confusion: код ожидает данные одного типа/источника, но получает данные другого. Похожая ошибка лежит в основе многих CVE: десериализация неподписанных JSON в Java (CVE-2017-9805 Struts2), приведение типов в PHP == сравнении (Type Juggling), prototype pollution в JavaScript. Везде источник — отсутствие явной проверки того, что данные соответствуют ожидаемой структуре. В случае SQLi: Go ожидает строку названия продукта, но в эту строку попадает пароль другого пользователя — и сериализуется в JSON без проверки.


4. Как это выглядит в логах SQL (PostgreSQL)

Если вы посмотрите SELECT * FROM pg_stat_activity, вы увидите эту "химеру" — запрос к товарам, скрещенный с запросом к пользователям. Это 100% признак активного взлома.

В production-средах для мониторинга SQL-аномалий используют pgAudit (расширение PostgreSQL) или Percona Audit Plugin для MySQL — они логируют ВСЕ запросы с пользователем-инициатором и source IP. SIEM (Splunk, ELK, Datadog) собирает эти логи и применяет правила детекции: «алерт, если SELECT содержит UNION с таблицей не из ожидаемого списка», «алерт, если запрос к таблице users приходит с endpoint /api/products». Эти правила требуют tuning под конкретное приложение, но дают возможность поймать инъекцию в реальном времени.


Извлечение нагрузки — это момент, когда хакер наконец-то открывает ваш "банк данных". Вся конфиденциальная информация теперь находится в его руках.

Соответствие стандартам: OWASP Top 10 A03:2021 Injection; CWE-89 SQL Injection; PCI-DSS 6.5.1; GDPR Article 32 «Security of Processing» — эксфильтрация персональных данных через UNION-инъекцию по GDPR обязывает уведомить регулятора в течение 72 часов и пострадавших пользователей в разумные сроки, плюс гарантирует штраф до 4% годового оборота при доказанной халатности.

Известные инциденты с UNION-based SQLi: Heartland Payment Systems 2008 (134 миллиона карт через UNION-инъекцию в payment processor); TalkTalk 2015 (4 миллиона клиентов через UNION в legacy формe); Yahoo Voices 2012 (450 тысяч plaintext-паролей); Sony Pictures 2011 (миллион учётных записей). Каждый из этих инцидентов мог бы быть предотвращён одной строкой кода — заменой fmt.Sprintf на параметризованный запрос.

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

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

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

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

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