ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Jolah Molivski ---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09 для поднятия ноды ETHEREUM и тестов
XMPP
XMPP
XMPP
● Позволяет включать контролируемый пользователем XML как часть строф
● XML- код, включенный таким образом, должен быть хорошо сформирован так как сервер отбрасывает XML, который он не считает хорошо сформированным
XML pipeline
А что не так на этой схеме, спросите вы???????
1 Пользовательский XML отправляется по всему конвейеру
2 Парсеры XML имеют свои особенности
Что такое контрабанда строф XMPP?
В действительности нет ни одного типа ошибок
XMPP XML pipeline (Zoom)
Как узнать, что Zoom работает на их серверах?
Пример ошибки №1: кодировка UTF-8
1-байтовые, 2-байтовые, 3-байтовые и 4-байтовые последовательности символов
● 1-байтовые, 2-байтовые, 3-байтовые и 4-байтовые последовательности символов
● Например, 0xEB = 11101011b - это начало 3-байтовой последовательности символов
0xEB 0x3C 0x3E - недопустимая последовательность (во втором и третьем байте должен быть установлен старший бит)
Пример ошибки #1: кодировка UTF-8
● Парсер Expat: 0xEB 0x3C 0x3E - один 3-байтовый символ
● Парсер Gloox: 0xEB 0x3C 0x3D - 3 символа
Полный эксплойт: <aaa /> <? ?/><xml><iq>...</iq></xml>
Expat: <aaa /> <? ?/><xml><iq>...</iq></xml>
Gloox: <aaa /> <? ?/><xml><iq>...</iq></xml>
Злоупотребляем тем, что <?xml ?> или <?foo ?><xml> сбрасывая состояние парсера Gloox
Пример ошибки #2: Разделитель пространства имен Expat
Ejabberd / fast_xml использует Expat следующим образом:
Пример:
<tag xmlns="namespace">.
Пользователь получает: namespace\ntag
С префиксами:
<prefix
ag xmlns:prefix="namespace">
Пользователь получает: namespace\ntag\nprefix
Что если:
<foo xmlns="bar
baz">.
Результат: bar\nbaz\nfoo
У пользователя нет возможности отличить триплет от пространства имен, содержащего разделитель
Можно вводить произвольные символы в имя тега. Деформированное имя выводится, когда
элемент сериализуется
А теперь попробуем зафаззить это.
Fuzzing для конвейера Zoom
Я использовал Jackalope (https://github.com/googleprojectzero/Jackalope)
Мой первоначальный тест не содержал последовательностей типа 

И не содержал свойств имен типа xmlns
Эксплуатация "контрабанды" строф
● Подделка сообщений
● Перенаправление соединения на другой сервер
Из спецификации ядра XMPP:
Пользовательские реализации
■ Пользовательская строфа <error> (Zoom)
■ Другие пользовательские строфы, например <redir> (Kik Messenger)
Пользовательские расширения XMPP
○ Zoom определяет >50 пользовательских расширений
Недоступные проблемы с повреждением памяти
○ Из статьи pwn2own 2021 Zoom: "Хотя клиент ожидает эту строфу только от сервера, можно отправить ее из другой учетной записи пользователя".
Эксплуатация Zoom
Пользовательское изменение обработки строфы <stream:error> в Gloox
Мы получаем HTTP POST запрос для /clusterswitch.
Давайте проксируем его! (mitmproxy в режиме обратного прокси)
Как предотвратить проблемы с "контрабандой" строф XMPP
● Проверка кода, фаззинг
● Использование одного и того же парсера XML на клиенте и сервере может предотвратить некоторые проблемы, но не все
● Валидация XML (?)
Заключение
● Парсеры XML в реализации XMPP представляют собой недостаточно изученную поверхность атаки
● Конструкция протокола XMPP делает его уязвимым для причуд парсера
● Потенциальное воздействие включает в себя раскрытие частной информации и 0-щелчок RCE
● Фаззинг является практическим способом обнаружения не только ошибок повреждения памяти, но и также логических ошибок в парсерах
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Jolah Molivski ---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09 для поднятия ноды ETHEREUM и тестов
XMPP
Код:
<?xml version='1.0' ?><stream:stream to='xmpp.zoom.us' xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams' xml:lang='en' version='2.0'>
<message from='zt5aygods8mzcclqhpn-ag@xmpp.zoom.us/ZoomChat_pc'
to='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us'
id='{B0D067FD-F47A-47DF-9305-4C2B47489F06}' type='chat'><body>test
message</body><thread>gloox{F096A899-64D6-4B36-9D65-11BAD59E3D7D}</t
hread><active xmlns='http://jabber.org/protocol/chatstates'/><zmext
expire_t='1720173136000' t='1657014736331'><from n='Ivan Vctm'
res='ZoomChat_pc'/><msg_type>0</msg_type><to/><visible>true</visible
><msg_feature>4</msg_feature></zmext></message>
<iq from='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc'
to='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc'
id='{8D2152A9-422E-4510-86A3-F4B510D93AB6}' type='result'/>
</stream:stream>
XMPP
Код:
Sent:
<message xmlns='jabber:client' to='zt5aygods8mzcclqhpn-ag@xmpp.zoom.us' id='{...}' type=
'chat' from='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc'><body>hello</body><thread>
gloox{...}</thread><active xmlns='http://jabber.org/protocol/chatstates'/><zmext>
<msg_type>0</msg_type><from n='Ivan Attckr' res='ZoomChat_pc'/><to/><visible>true
</visible><msg_feature>4</msg_feature></zmext></message>
Received:
<message from='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc' to=
'zt5aygods8mzcclqhpn-ag@xmpp.zoom.us' id='{...}' type='chat'><body>hello</body>
<thread>gloox{...}</thread><active xmlns='http://jabber.org/protocol/chatstates'/>
<zmext expire_t='1720185046000' t='1657026646132'><from n='Ivan Attckr'
res='ZoomChat_pc'/><msg_type>0</msg_type><to/><visible>true</visible><msg_feature>4
</msg_feature></zmext></message>
XMPP
Код:
Sent:
<message xmlns='jabber:client' to='zt5aygods8mzcclqhpn-ag@xmpp.zoom.us' id='{...}' type=
'Chat' from='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc'>
<body>hello<foo>bar</foo></body><thread>gloox{...}</thread><active
xmlns='http://jabber.org/protocol/chatstates'/><zmext><msg_type>0</msg_type><from
n='Ivan Attckr' res='ZoomChat_pc'/><to/><visible>true</visible><msg_feature>
4</msg_feature></zmext></message>
Received:
<message from='btdwxa1fssobpko9x_-j_a@xmpp.zoom.us/ZoomChat_pc' to=
'zt5aygods8mzcclqhpn-ag@xmpp.zoom.us' id='{...}' type='chat'>
<body>hello<foo>bar</foo></body> <thread>gloox{...}</thread><active
xmlns='http://jabber.org/protocol/chatstates'/><zmext expire_t='1720185046000'
t='1657026646132'><from n='Ivan Attckr' res='ZoomChat_pc'/><msg_type>0</msg_type>
<to/><visible>true</visible><msg_feature>4</msg_feature></zmext></message>
● Позволяет включать контролируемый пользователем XML как часть строф
● XML- код, включенный таким образом, должен быть хорошо сформирован так как сервер отбрасывает XML, который он не считает хорошо сформированным
XML pipeline
1 Пользовательский XML отправляется по всему конвейеру
2 Парсеры XML имеют свои особенности
Что такое контрабанда строф XMPP?
В действительности нет ни одного типа ошибок
XMPP XML pipeline (Zoom)
Как узнать, что Zoom работает на их серверах?
Пример ошибки №1: кодировка UTF-8
1-байтовые, 2-байтовые, 3-байтовые и 4-байтовые последовательности символов
● 1-байтовые, 2-байтовые, 3-байтовые и 4-байтовые последовательности символов
● Например, 0xEB = 11101011b - это начало 3-байтовой последовательности символов
0xEB 0x3C 0x3E - недопустимая последовательность (во втором и третьем байте должен быть установлен старший бит)
Код:
11101011 00111100 00111110
● Парсер Expat: 0xEB 0x3C 0x3E - один 3-байтовый символ
● Парсер Gloox: 0xEB 0x3C 0x3D - 3 символа
Полный эксплойт: <aaa /> <? ?/><xml><iq>...</iq></xml>
Expat: <aaa /> <? ?/><xml><iq>...</iq></xml>
Gloox: <aaa /> <? ?/><xml><iq>...</iq></xml>
Злоупотребляем тем, что <?xml ?> или <?foo ?><xml> сбрасывая состояние парсера Gloox
Пример ошибки #2: Разделитель пространства имен Expat
Ejabberd / fast_xml использует Expat следующим образом:
Пример:
<tag xmlns="namespace">.
Пользователь получает: namespace\ntag
С префиксами:
<prefix
Пользователь получает: namespace\ntag\nprefix
Что если:
<foo xmlns="bar
baz">.
Результат: bar\nbaz\nfoo
У пользователя нет возможности отличить триплет от пространства имен, содержащего разделитель
Можно вводить произвольные символы в имя тега. Деформированное имя выводится, когда
элемент сериализуется
А теперь попробуем зафаззить это.
Fuzzing для конвейера Zoom
Код:
void ProcessSample(const char *data, size_t size) {
string message(data, size);
message = string("<message>") + message + string("</message>");
std::string reparsed;
if(!fastxml_reparse(message.data(), message.size(), &reparsed))
return;
gloox::TagHandler th;
gloox::Parser gloox_parser(&th);
int gloox_ret = gloox_parser.feed(reparsed);
if(gloox_ret >= 0) {
crash[0] = 1;
}
}
Я использовал Jackalope (https://github.com/googleprojectzero/Jackalope)
Мой первоначальный тест не содержал последовательностей типа 

И не содержал свойств имен типа xmlns
Эксплуатация "контрабанды" строф
● Подделка сообщений
● Перенаправление соединения на другой сервер
Из спецификации ядра XMPP:
Пользовательские реализации
■ Пользовательская строфа <error> (Zoom)
■ Другие пользовательские строфы, например <redir> (Kik Messenger)
Пользовательские расширения XMPP
○ Zoom определяет >50 пользовательских расширений
Недоступные проблемы с повреждением памяти
○ Из статьи pwn2own 2021 Zoom: "Хотя клиент ожидает эту строфу только от сервера, можно отправить ее из другой учетной записи пользователя".
Эксплуатация Zoom
Пользовательское изменение обработки строфы <stream:error> в Gloox
Код:
<stream:error><revoke-token reason='1'
web-domain='...'></revoke-token></stream:error>
Мы получаем HTTP POST запрос для /clusterswitch.
Давайте проксируем его! (mitmproxy в режиме обратного прокси)
Как предотвратить проблемы с "контрабандой" строф XMPP
● Проверка кода, фаззинг
● Использование одного и того же парсера XML на клиенте и сервере может предотвратить некоторые проблемы, но не все
● Валидация XML (?)
Заключение
● Парсеры XML в реализации XMPP представляют собой недостаточно изученную поверхность атаки
● Конструкция протокола XMPP делает его уязвимым для причуд парсера
● Потенциальное воздействие включает в себя раскрытие частной информации и 0-щелчок RCE
● Фаззинг является практическим способом обнаружения не только ошибок повреждения памяти, но и также логических ошибок в парсерах
Последнее редактирование: