Продвинутые JavaScript-инъекции

Продвинутые JavaScript-инъекции

От автора: простая JavaScript инъекция, такая как ‘-alert(1)-’ или даже \’-alert(1)//, как правило, справляется с тем, чтобы выскочило окно предупреждения об уязвимой странице, когда отражение input происходит внутри блока скрипта и HTML-инъекция невозможна.

Но есть случаи, когда точка инъекции находится в середине более сложного кода JS: внутри функций и условий (if или if+else), вложенных друг в друга. Давайте рассмотрим пример такой инъекции, шаг за шагом.

Вам будет легко сделать это с помощью взаимодействия с пользователем, но все может стать сложнее, если вы не имеете навыков JS. Итак, у нас есть следующая точка отражения. Он находится в середине некоторого кода JS (keyword=aaaaa).

Затем мы пытаемся выполнить простую инъекцию JS, но перед каждой двойной кавычкой она экранируется обратной косой чертой.

Payload: “-confirm1-”

Как мы знаем из Основных примеров XSS (пример #7), следующая хитрость — добавить обратную косую черту перед нашей первой кавычкой, чтобы «предотвратить предотвращение». Также необходимо закомментировать остальную часть строки.

Payload: \”-confirm1//

Это работает, если мы изменим (через взаимодействие с пользователем) элемент select на странице.

Но есть лучший способ сделать это, так как эта «функция» будет доступна не во всех случаях, а также для этого требуется взаимодействия с пользователем.

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

Мы начинаем нашу новую попытку с \”}})}) , которые являются последними 3 строками нашего фрагмента кода (без точек с запятой), чтобы закрыть «if », функцию «on+change» и функцию «document.ready». Остальное остается таким же, как и в предыдущей попытке.

Payload: \”}})})-confirm1//

Конечно, это не работает, так как выполняется только половина построения полезной нагрузки (самая простая часть). Но ошибки, возвращаемые в консоли JS (в инструментах разработчика браузера нажмите F12), помогут нам разобраться.

Нажав на ссылку в правой части сообщения, мы обнаружим проблему.

Ошибка возникает в строке «else», потому что ее там не должно быть. Мы уже закрыли оператор if вместе с двумя функциями, поэтому нам нужно от нее избавиться.

В данном конкретном случае мы имеем дело с двойным отражением, поэтому мы попытаемся собрать их вместе, чтобы они стали единым целым, открыв комментарий в первом отражении и закрыв его во втором. Этого будет достаточно, чтобы избавиться от кода между этими двумя отражениями: строкой «else» и атрибуцией «document.location».

Многострочные комментарии в JS обозначаются /* и */, поэтому простое /* / в конце выполнит эту работу (оно парсируется, как /* в 1-м отражении и как */ во 2-м).

Payload: \”}})})-confirm1/*/

Давайте проверим, что может означать эта ошибка.

Как мы видим, конец первого отражения до конца второго теперь отображается зеленым цветом. Таким образом, в конце нашего confirm1 код продолжается &pageIndex=1&startFrom=0, что интерпретируется как побитовый оператор AND (&) с недопустимым назначением переменной (pageIndex = 1).

Это можно просто решить, закомментировав оставшуюся часть строки с помощью // , добавленных в конец текущей полезной нагрузки. В результате мы получаем (с добавлением точки с запятой):

Payload: \”}})})-confirm1;/*///

Теперь все, как и ожидалось, весь код после нашей введенной точки с запятой и до закрывающей «}» из оператора «if» комментируется. Итак, давайте добавим «{» в конец нашей полезной нагрузки, прямо перед комментарием.

Payload: \”}})})-confirm1;{/*///

Бинго, парсер перешел на следующую строку с ошибкой в следующем закрытии!

Итак, давайте продолжим, пытаясь исправить «})», открыв новый с содержимым «({» перед «{», чтобы соблюдать синтаксис.

Payload: \”}})})-confirm1;({{/*///

Что случилось? Из-за нового добавленного «({«, теперь наш первый «{» перестает работать, как «исправление» для оператора «if». Вернемся к экспериментам с добавленным «if ()» между «( {» а также «{«.

Payload: \”}})})-confirm1;({if(){/*///

Отлично, мы сейчас на последней строчке! Мы просто повторяем то, что сделали на предыдущем шаге, добавляя еще одни «({» сразу после точки с запятой и перед «({if () {«.

Payload: \”}})})-confirm1;({({if(){/*///

Что мы испортили на этот раз? Это происходило и раньше, мы просто сломали предыдущее «исправление». Чтобы исправить это, давайте добавим «function()» между недавно добавленными «(» и «{«.

Payload: \”}})})-confirm1;(function(){({if(){/*///

Круто, мы только что разобрались с этим! Теперь мы сократим нашу полезную нагрузку.

Мы удаляем точку с запятой (заставляя синтаксический анализатор выдавать «непонятную ошибку», но все еще выполняться), и заменяем «if()» на метку «b:», а «function ()» на параметр функции стрелки «a =>». Имена «а», и «б» абсолютно произвольны.

Final Payload: \”}})})-confirm1(a=>{({b:{/*///

Полный блок JS выглядит, как показано выше. Миссия выполнена.

Источник: https://brutelogic.com.br/

Редакция: Команда webformyself.