Хабрахабр

[Перевод] Провоцирование сбоев браузера при помощи поведенческого фаззинга

image

Обычно целью фаззинга является нахождение сбоя, указывающего на повреждение памяти, но моя цель заключается в другом: я хочу обнаружить неожиданную реакцию браузера. В этой статье я расскажу вам, как я использовал фаззинг, чтобы найти несколько сбоев в Firefox. Такое неожиданная реакция часто может быть использована для проведения XSS-атак, минуя фильтры безопасности и избегая песочницы JavaScript. Это могут быть символы, которые открывают или закрывают необычный тег, или, возможно, символы, которые игнорируются парсером JavaScript.

Если Вы читали спецификацию HTML, вы знаете, что комментарий можно закрыть с помощью --> или --!>. Первая ошибка, о которой я хочу поговорить — это как закрыть HTML-комментарий по-другому. Отличный вопрос для начала фаззинга! А как же сделать это иначе? Вам просто нужно сгенерировать код, который даст ответ.

Сегодня, в 2019 году все работает быстрее, поэтому мы можем фаззить намного чаще. Еще в 2008 году, когда я собрал Shazzer для фаззинга поведения браузера, я был ограничен примерно 10 000 направлениями на страницу. Стоит отметить, что это ненадежный подход, поскольку вы можете получить разные результаты. Кроме того, использование DOM ускоряет фаззинг, потому что вам больше не нужно добавлять каждое направление к текущему документу. Это все еще некритичные сбои, но вы не всегда можете доверять результатам, чтобы получить полное представление о том, что будет делать парсер HTML. Действительно, я нашел случаи, когда DOM допускает пустые значения (NULL) в аргументах атрибутов, таких как href, но парсер HTML так не делает. Однако в большинстве случаев он работает, и это гораздо быстрее, чем вывод HTML с серверной стороны.

Чтобы ответить на него, нам нужно использовать существующие символы, которые закроют HTML-комментарий и фаззить символы, которые мы не знаем. Первый шаг уже сделан — у нас есть вопрос: «Какие символы могут закрыть HTML-комментарий?». В моем случае я использую свой инструмент Hackvertor, но с помощью локального веб-сервера можно добиться тех же результатов. Следующий шаг — использование соответствующих программ для фаззинга. Так как нам нечего конвертировать, мы можем поместить наш код непосредственно в поле вывода. Идея этого инструмента заключается в том, чтобы поместить вводимые данные в поле ввода, немного преобразовать теги и сделать что-то с выводом. Поэтому нажмите на область вывода текста и создайте массив для хранения отфаззенных символов и элемент div для тестирования HTML:

log = [];
div=document.createElement('div');

Затем нам нужно отфаззить более 1000000 символов Юникода или, точнее, 0x10ffff. Простой цикл for – это все, что нам нужно:

for(i=0;i<=0x10ffff;i++){

Затем мы повторно используем элемент div, который мы создали для каждого символа. В этом случае я тестирую позицию после !, так что символ будет введен после!.. Затем я использую элемент img, чтобы увидеть, был ли фаззинг успешным. Если этот элемент существует, то HTML-комментарий был закрыт, и у нас есть некоторые интересные символы!

div.innerHTML = '<!-- --!'+String.fromCodePoint(i)+'><img>-->';

Наконец, с помощью querySelector мы проверяем, существует ли img и добавляем символы в логи. Затем я закрываю оператор if и цикл for. Наконец, ввожу результаты в поле ввода слева:

if(div.querySelector('img'))
}
input.value=log

Вот полная версия кода. Вам нужно открыть URL в Firefox, а затем поместить вводимые символы в поле вывода и нажать кнопку «Execute JS», чтобы фаззировать символы. После завершения фаззинга вы должны увидеть цифры в поле ввода, они соответствуют кодам символов, которые были успешными. На момент написания материала Firefox (версия 67) все еще допускает новые символы строки — \n и \r — после!, чтобы закрыть комментарий. Мне сообщили, что это исправлено в будущих версиях Firefox. Итак, последний этап фаззинга заключается в сборке вашей полезной нагрузки, это довольно просто. Вам нужно заменить код символа символом и добавить полезную нагрузку XSS:

<!-- --!
><img src=1 onerror=alert(1)> -->

Вы можете снова использовать Hackvertor для проверки его работы, вставив вышеуказанное в поле вывода, а затем нажав «Test HTML». Должно появиться окно предупреждения, потому что Firefox (версия 67) разрешает новую строку как часть заключительного комментария.

Давайте найдем ещё одну! Так что это позволило нам найти некритичную ошибку в парсере HTML Firefox. Вместо того, чтобы выйти за рамки существующего HTML-комментария, мы теперь будем использовать HTML-комментарий, чтобы выйти за рамки существующего атрибута HTML. Нам нужен новый вопрос: «Какие символы могут открыть HTML-комментарий?». Если символ успешно создает открывающий HTML-комментарий, он будет комментировать элемент div и, таким образом, выходить из атрибута title. Как я уверен, вы все знаете, что можно открыть HTML-комментарий с ">';
Таким образом, символ, который мы фаззим, будет находиться после первого дефиса. Код 45 ожидаем, потому что это символ дефиса, но 0 является NULL символом! На этот раз, когда мы запускаем «Execute JS», получаем два результата в Firefox (версия 67): «0,45». -NULL- как открытый комментарий. Это означает, что Firefox интерпретирует последовательность <! (я думаю, что поставщикам браузеров нужно проводить больше поведенческого фаззинга =) ). Дичь какая-то! Сделаем то же самое: снова заменим функцию String.fromCodePoint с символом NULL и XSS направлением: Чтобы закончить этот тестовый случай, теперь нам нужно создать наше направление.

document.body.innerHTML = '<!-\x00- ><div title="--><img src=1 onerror=alert(1)>"></div>';

Давайте перейдем на JavaScript вместо HTML. Я протестировал каждый браузер, и мне жаль Mozilla, но Firefox снова творит какую-то дичь. Я вдохновился тем, что фаззинг из твита jinmo123 использует новые интересные фичи ES6 для вызова функций без скобок. Вопрос, который я придумал для фаззинга, был: «какие символы разрешены после операторов in или instanceof?». Затем мы снова создаем код в Hackvertor, он следует аналогичному шаблону, но на этот раз не использует DOM. Сначала создаем массив и цикл for:

log = [];
for(i=0;i<=0x10ffff;i++){

Тогда мы будем использовать eval вместо innerHTML для фаззинга наших значений. Сначала нам нужно использовать блок try catch, чтобы обнаружить любые исключения, вызванные недопустимыми символами.

try{
eval("/a/"+String.fromCodePoint(i)+"instanceof function(){}");

Функция eval используется, чтобы увидеть, является ли наш JavaScript допустимым. Если да, то она перейдет к следующей строке, если нет, выдаст исключение, которое будет замечено, а затем перейдет к следующему символу. Следующая строка просто регистрирует символ, а потом закрывает блок try catch и цикл for. Затем функция выводит результаты в поле ввода.

log.push(i);
}catch(e){}
}
input.value=log

Если вы запустите этот код с помощью «Execute JS», вы получите кучу результатов! Firefox игнорирует множество символов. Если вы попробуете код на Chrome, вы получите более разумные результаты. Найдите код символа в поле ввода, который вы хотите использовать, в моем случае это было «1114110» или «0x10fffe» в hex. Теперь мы создадим наш вектор JavaScript:

eval("1337"+String.fromCodePoint(1114110)+"in"+String.fromCodePoint(1114110)+"alert(1337)");

Вы также можете представить его внутри скрипта SVG:

SH доступны новейшие двухпроцессорные конфигурации выделенных серверов с процессорами Intel Scalable 2019 года:
На DEDIC.

  • 2x Xeon Silver 4214 — суммарно 24 ядра
  • 2x Xeon Gold 5218 — суммарно 32 ядра
  • 2x Xeon Gold 6240 — конфигурация с 36 ядрами.

Стоимость сервера с двумя Xeon Silver 4214 — от 15210 руб/мес
Так же мы готовы собрать для Вас любую конфигурациюнапишите нам!

Если большие мощности выделенного сервера не требуются — VDS от 150 руб/мес — то, что вам нужно!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть