Вступление
В январе этого года Google и Microsoft, опубликовали блоги, раскрывающие атаки на исследователей безопасности со стороны APT-группы из NK [1] [2]. Уязвимость в Internet Explorer, использованная в этой атаке, была исправлена как CVE-2021-26411 в патче Microsoft во вторник в этом месяце [3]. Уязвимость срабатывает, когда пользователи уязвимой версии Internet Explorer получают доступ к вредоносной ссылке, созданной злоумышленниками, что приводит к удаленному выполнению кода.
Анализ первопричин
POC, который может вызвать уязвимость, приведён ниже:
Процесс выполнения PoC:
Основываясь на приведенном выше анализе потока PoC, можно сделать вывод, что причиной сбоя является проблема двойного освобождения, вызванная функцией
1. Функция
2.
3. Когда индекс объекта атрибута найден, объект атрибута извлекается через
4. Когда индекс
5. Затем он дважды вызывает
6.
7.
Затем мы наблюдаем за процессом обратного вызова вопроса 1 и анализируем вопрос 2 с помощью динамической отладки
1. Макет памяти объекта элемента до входа в функцию узла
2. Результат двух вызовов функции
3.
4. Структура памяти объекта elem после вызова
Сравнивая c шагом 1, вы можете увидеть, что после
5.Когда обратный вызов возвращается, в первом вызове
После прохождения проверки индекса вызывается
6. Когда обратный вызов вернется, во втором вызове
Согласно статическому анализу функции
После возврата указатель объекта
Вот картинка, объясняющая весь процесс:
От разыменования нулевого указателя до примитива чтения/записи
Наконец, давайте обратимся к вопросу 3:
Как эксплуатировать это исключение разыменования нулевого указателя?
Как известно, исключение разыменования нулевого указателя в пользовательском режиме сложно эксплуатировать, но эта уязвимость имеет свою особенность. Из предыдущего анализа мы знаем, что исключение разыменования нулевого указателя возникает во второй операции
В это время первая операция
Итак, на самом деле проблема UAF скрыта исключением разыменования нулевого указателя.
Следующим шагом нужно подумать о том, как использовать этот UAF. Учитывая, что объект элемента DOM защищен изолированной кучей и механизмом отложенного освобождения, он должен выбрать объект, который может напрямую выделять память системным распределителем кучи, например чрезвычайно длинный BSTR.
Пересмотренный PoC:
Схема памяти элемента перед вызовом
После
В первой операции DeleteAt снова осуществляется доступ к памяти BSTR атрибута «zzz» с индексом = 2, что приводит к UAF:
Здесь мы можем получить дыру в памяти размером 0x20010 байтов, после обратного вызова valueOf clearAttributes():
Тогда есть два вопроса, на которые нужно ответить:
Наконец, после того, как возвращается элемент
Есть много путей для последующей эксплуатации. Основные идеи:
Вместо заключения
Microsoft удалила уязвимость браузера IE из программы вознаграждений за уязвимости и начала выпускать новый браузер Edge на основе Chromium. Однако в последние годы APT, использующие уязвимости браузера IE, все еще активны. От движка vbscript в 2018 году, движка jscript в 2019 году до движка jscript9 в 2020 году злоумышленники постоянно ищут новые поверхности для атак. Раскрытие CVE-2021-26411 снова привлекло внимание общественности к проблемам безопасности механизма mshtml, которые были обнаружены с большим количеством проблем UAF. Мы считаем, что атаки на Internet Explorer не остановлены.
Ссылки
[1] https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/
[2] https://www.microsoft.com/security/blog/2021/01/28/zinc-attacks-against-security-researchers/
[3] https://msrc.microsoft.com/update-guide/en-us/vulnerability/CVE-2021-26411
[4] https://enki.co.kr/blog/2021/02/04/ie_0day.html
От ТС
Оригинал тут.
Давно пытаюсь влится в тему экплуатации браузеров, эта статья мне безусловно помогла)
Перевод:
Azrv3l cпециально для xss.pro
В январе этого года Google и Microsoft, опубликовали блоги, раскрывающие атаки на исследователей безопасности со стороны APT-группы из NK [1] [2]. Уязвимость в Internet Explorer, использованная в этой атаке, была исправлена как CVE-2021-26411 в патче Microsoft во вторник в этом месяце [3]. Уязвимость срабатывает, когда пользователи уязвимой версии Internet Explorer получают доступ к вредоносной ссылке, созданной злоумышленниками, что приводит к удаленному выполнению кода.
Анализ первопричин
POC, который может вызвать уязвимость, приведён ниже:
JavaScript:
<script>
var elem = document.createElement('xxx');
var attr1 = document.createAttribute('yyy');
var attr2 = document.createAttribute('zzz');
var obj = {};
obj.valueOf = function() {
elem.clearAttributes();
return 0x1337;
};
attr1.nodeValue = obj;
attr2.nodeValue = 123;
elem.setAttributeNode(attr1);
elem.setAttributeNode(attr2);
elem.removeAttributeNode(attr1);
</script>
Процесс выполнения PoC:
- Создаётся 1 объект элемента HTML (
elem) и 2 объекта атрибута HTML (attr1иattr2) - Присваиватся значения двум объектам атрибута
nodeValue, гдеnodeValueattr1указывает на объект, функцияvalueOfкоторого перегружена. - Устанавливается значение Element object
elemдля двух объектов Attributeattr1иattr2. - Вызывается
elem.removeAttributeNode(attr1), чтобы удалитьattr1изelem. - Метод
removeAttributeNodeзапускает обратный вызов функцииvalueOf, во время которой вызываетсяclearAttributes()для очистки всех объектов атрибутов (attr1иattr2) объектаelem. - Когда обратный вызов
valueOfвозвращается, процесс IE Tab вылетает при разыменовании нулевого указателя:
Основываясь на приведенном выше анализе потока PoC, можно сделать вывод, что причиной сбоя является проблема двойного освобождения, вызванная функцией
clearAttributes() в обратном вызове valueOf. После очистки всех объектов атрибута объекта элемента он возвращается к интерпретатору (прерывая операцию атомарного удаления на уровне интерпретатора) и снова освобождает объект атрибута, что приводит к двойному освобождению. Но есть еще некоторые детали, которые нужно проработать:- Почему removeAttributeNode () запускает обратный вызов valueOf на уровне скрипта?
- Почему исключение разыменования нулевого указателя все еще возникает на объектах DOM, которые защищены изолированной кучей и механизмом отложенного освобождения?
- Как эксплуатировать это исключение разыменования нулевого указателя?
1. Функция
removeAttributeNode() в mshtml.dll обрабатывается функцией MSHTML!CElement::ie9_removeAttributeNode. Он вызывает внутри себя MSHTML!CElement::ie9_removeAttributeNodeInternal, который является основной реализацией removeAttributeNode():
2.
MSHTML!CElement::ie9_removeAttributeNodeInternal дважды вызывает CBase::FindAAIndexNS для поиска индексов объекта атрибута и объекта атрибута nodeValue в массиве VARINAT CAttrArray (+0x8)
3. Когда индекс объекта атрибута найден, объект атрибута извлекается через
CBase::GetObjectAt:
4. Когда индекс
nodeValue объекта атрибута найден, он вызывает функцию CBase::GetIntoBSTRAt для преобразования nodeValue в BSTR и сохраняет значение BSTR в CAttribute.nodeValue(+0x30). В это время будет запущен обратный вызов valueOf!
5. Затем он дважды вызывает
CBase::DeleteAt, чтобы удалить объект атрибута и объект атрибута nodeValuev(здесь необходимо обратить внимание на существование одного вызова CBase::FindAAIndexNS между двумя вызовами DeleteAt, чтобы снова найти индекс attr1.nodeValue):
6.
CBase::DeleteAt проверяет индекс объекта, который необходимо удалить. Если он не равен -1, он вызывает CAttrArray::Destroy для выполнения работы по очистке:
7.
CAttrArray::Destroy вызывает CImplAry::Delete, чтобы изменить счетчик CAttrArray(+0x4) и изменить порядок соответствующего массива VARIANT (+0x8), затем вызывает CAttrValue::Free, чтобы освободить объект атрибута в конце:
Затем мы наблюдаем за процессом обратного вызова вопроса 1 и анализируем вопрос 2 с помощью динамической отладки
1. Макет памяти объекта элемента до входа в функцию узла
removeAttribute:
2. Результат двух вызовов функции
CBase::FindAAIndexNS после ввода MSHTML!CElement::ie9_removeAttributeNodeInternal:
3.
CHase::GetIntoBSTRAt запускает значение Callback в скрипте:
4. Структура памяти объекта elem после вызова
clearAttributes() в обратном вызове valueOf:
Сравнивая c шагом 1, вы можете увидеть, что после
clearAttributes() значение elem.CAttrArray.count(+ 0x4) уменьшается до 1, и происходит операция копирования памяти в массиве CAttrArray VARIANT (+ 0x8): attr2 индекса 4 копируется в предыдущий индекс в порядке (сдвиг), который соответствует логике CImplAry::Delete:
5.Когда обратный вызов возвращается, в первом вызове
CBase::DeleteAt(): Он проверяет индекс объекта VARIANT, который сначала ожидал удаления. Вот значение индекса attr1 2, которое найдено в первом поиске CBase::FindAAIndexNS:
После прохождения проверки индекса вызывается
CAttrArray::Destroy для начала очистки.6. Когда обратный вызов вернется, во втором вызове
CBase::DeleteAt(): Вспоминая часть статического анализа, выполняется один CBase::FindAAIndexNS между двумя CBase::DeleteAt, чтобы снова найти индекс attr1.nodeValue. При нормальных обстоятельствах ожидается, что CBase::FindAAIndexNS вернет 1. Однако, поскольку обратный вызов прерывает атомарную операцию на уровне интерпретатора и заранее освобождает все атрибуты elem, здесь возвращается неожиданный -1:
Согласно статическому анализу функции
CBase::DeleteAt, для случая, когда индекс равен -1, будет выдано исключение:
После возврата указатель объекта
CAttrArray указывает на память, установленную как NULL, что, наконец, вызывает исключение разыменования нулевого указателя:
Вот картинка, объясняющая весь процесс:
От разыменования нулевого указателя до примитива чтения/записи
Наконец, давайте обратимся к вопросу 3:
Как эксплуатировать это исключение разыменования нулевого указателя?
Как известно, исключение разыменования нулевого указателя в пользовательском режиме сложно эксплуатировать, но эта уязвимость имеет свою особенность. Из предыдущего анализа мы знаем, что исключение разыменования нулевого указателя возникает во второй операции
DeleteAt, но первая операция DeleteAt уже имеет неверное предположение: массив VARIANT (+ 0x8), сохраненный в CAttrArray, был переназначен в обратном вызове:
В это время первая операция
DeleteAt с index = 2 по ошибке освободит объект attr2:
Итак, на самом деле проблема UAF скрыта исключением разыменования нулевого указателя.
Следующим шагом нужно подумать о том, как использовать этот UAF. Учитывая, что объект элемента DOM защищен изолированной кучей и механизмом отложенного освобождения, он должен выбрать объект, который может напрямую выделять память системным распределителем кучи, например чрезвычайно длинный BSTR.
Пересмотренный PoC:
JavaScript:
<script>
var elem = document.createElement('xxx');
var attr1 = document.createAttribute('yyy');
//var attr2 = document.createAttribute('zzz');
var obj = {};
obj.valueOf = function() {
elem.clearAttributes();
return 0x1337;
};
attr1.nodeValue = obj;
//attr2.nodeValue = 123;
elem.setAttributeNode(attr1);
//elem.setAttributeNode(attr2);
elem.setAttribute('zzz', Array(0x10000).join('A'));
elem.removeAttributeNode(attr1);
</script>
Схема памяти элемента перед вызовом
removeAttributeNode():
После
clearAttributes() массив VARIANT CAttryArray копируется вперед, а BSTR немедленно освобождается:
В первой операции DeleteAt снова осуществляется доступ к памяти BSTR атрибута «zzz» с индексом = 2, что приводит к UAF:
Здесь мы можем получить дыру в памяти размером 0x20010 байтов, после обратного вызова valueOf clearAttributes():
Тогда есть два вопроса, на которые нужно ответить:
- Какой объект можно выбрать, чтобы он занимал пустую память?
- Как обойти исключение разыменования нулевого указателя, вызванное проверкой «index = -1» во втором DeleteAt после успешного заполнения пустой памяти?
Наконец, после того, как возвращается элемент
elem.removeAttributeNode(attr1) , получается висящий указатель hd2.nodeValue размером 0x20010 байт.Есть много путей для последующей эксплуатации. Основные идеи:
- Используйте
Scripting.Dictionary.items(), чтобы занять дыру в памяти, и используйте висячий указательhd2.nodeValueдля утечки поддельного адреса ArrayBuffer - Воспользуйтесь утечкой метаданных поддельного ArrayBuffer, изменените ArrayBuffer buffer = 0, length = 0xffffffff и получите новый поддельного ArrayBuffer
- Создайте DataView, который ссылается на новый поддельный ArrayBuffer для достижения произвольного примитива чтения и записи в память
Вместо заключения
Microsoft удалила уязвимость браузера IE из программы вознаграждений за уязвимости и начала выпускать новый браузер Edge на основе Chromium. Однако в последние годы APT, использующие уязвимости браузера IE, все еще активны. От движка vbscript в 2018 году, движка jscript в 2019 году до движка jscript9 в 2020 году злоумышленники постоянно ищут новые поверхности для атак. Раскрытие CVE-2021-26411 снова привлекло внимание общественности к проблемам безопасности механизма mshtml, которые были обнаружены с большим количеством проблем UAF. Мы считаем, что атаки на Internet Explorer не остановлены.
Ссылки
[1] https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/
[2] https://www.microsoft.com/security/blog/2021/01/28/zinc-attacks-against-security-researchers/
[3] https://msrc.microsoft.com/update-guide/en-us/vulnerability/CVE-2021-26411
[4] https://enki.co.kr/blog/2021/02/04/ie_0day.html
От ТС
Оригинал тут.
Давно пытаюсь влится в тему экплуатации браузеров, эта статья мне безусловно помогла)
Перевод:
Azrv3l cпециально для xss.pro
Последнее редактирование: