3. Посимвольное извлечение (SUBSTRING, ASCII)
Посимвольное извлечение: Рецепт вытаскивания строк по битам
Посимвольное извлечение (Character Extraction) напоминает игру "Угадай слово", где можно задавать только вопросы "Да/Нет". С помощью SQL-функций SUBSTRING и ASCII хакер может по одной букве восстановить любую строку из вашей базы данных, будь то пароль администратора или секретный API-ключ.
Разберем, как работают эти инструменты и как они позволяют по крупицам собирать конфиденциальную информацию.
1. Механика: "Буква за буквой"
Представьте запрос в Go-коде:
SELECT id FROM users WHERE username = 'admin' AND password = '%s' (через fmt.Sprintf).
Хакер уже знает, что его инъекция работает ("Да/Нет"). Теперь он вытаскивает пароль в слепую:
AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1), 1, 1)) = 65(Первая буква пароля — 'A'?)ASCIIот буквы 'A' — это число 65.SUBSTRING— берет первую букву строки.
Если сервер вернул 200 OK — первая буква пароля найдена.
2. Различия в синтаксисе СУБД
Хакеры знают, как это делать во всех базах:
| СУБД | Функция | Пример |
|---|---|---|
| PostgreSQL | SUBSTRING(v, 1, 1) |
SUBSTRING(pass, 1, 1) |
| MySQL | SUBSTRING(v, 1, 1) |
SUBSTRING(pass, 1, 1) |
| SQLite | SUBSTR(v, 1, 1) |
SUBSTR(pass, 1, 1) |
3. Таблица работы: Процесс атаки
| Шаг | SQL-запрос (Payload) | Поведение страницы | Означает ли это? |
|---|---|---|---|
| 1 | ... ASCII(SUB(p,1,1))=65 |
404 Not Found |
Нет, не 'A' |
| 2 | ... ASCII(SUB(p,1,1))=66 |
200 OK |
ДА, это 'B' |
| 3 | ... ASCII(SUB(p,1,2))=65 |
200 OK |
ДА, вторая 'A' |
Хакер узнал, что пароль начинается на "BA...".
4. Как хакеры "наводят порядок" в запросах
С помощью LIMIT и OFFSET хакер может последовательно извлекать данные из каждой строки таблицы. В PostgreSQL это выглядит как LIMIT 1 OFFSET 0 (первый юзер), OFFSET 1 (второй) и так далее, что позволяет выгрузить всю базу целиком.
5. Сравнение через hex(): байт-безопасный приём для SQLite
Прямое сравнение через substr(...) = 'X' ломается, если значение содержит управляющие символы, многобайтовые UTF-8 последовательности или нестандартное quoting. Универсальный приём в SQLite — приводить и левую, и правую часть к hex-представлению (uppercase) и сравнивать как строки шестнадцатеричных байтов:
-- Вместо substr(secret, 1, 1) = 'a'
hex(substr(secret, 1, 1)) = '61'
-- 'a' в Python: 'a'.encode().hex().upper() = '61'
-- '{' в Python: '{'.encode().hex().upper() = '7B'
Зачем: SQLite hex() возвращает результат в верхнем регистре, тогда как Python bytes.hex() — в нижнем. При записи payload в скрипт всегда вызывайте .upper() для совпадения форматов. Этот трюк нужен для уверенного сопоставления любого ASCII/UTF-8 символа без боли с кавычками внутри payload и без потерь от кодировок.
6. Точка входа — не только URL и форма
Boolean-blind инъекция часто прячется в местах, где разработчик не ожидает пользовательского ввода: cookie (значение применённого купона, реферальный код), HTTP-заголовки, скрытые input-поля. Логика if cookie == valid_value без параметризации SQL-запроса проверки даёт двухпозиционный оракул не хуже чем 200/404.
Пример концептуального паттерна:
// ❌ Cookie вклеивается в SQL — разница в HTML-выводе становится оракулом
coupon, _ := r.Cookie("applied_coupon")
query := fmt.Sprintf("SELECT discount FROM coupons WHERE code='%s'", coupon.Value)
db.QueryRow(query).Scan(&d)
// Если discount > 0 → шаблон рендерит "Discount applied" → TRUE
// Если discount = 0 → текст отсутствует → FALSE
Атакующий вкладывает в значение cookie payload вида <valid_code>' AND <предикат> -- и читает HTML-разницу страницы корзины. Никаких ошибок SQL, никаких 404 — только присутствие/отсутствие конкретного DOM-элемента.
Посимвольное извлечение — процесс долгий, но при наличии уязвимости результат неизбежен.
Чтобы ускорить этот процесс, хакеры применяют поисковые алгоритмы. Узнаем, как бинарный поиск сокращает время подбора в десятки раз.
Продолжить чтение
Что бы прочитать модуль полностью, зарегистрируйтесь/войдите на платформу
Когда закончишь — отметь раздел, чтобы продолжить.