В этой части мы рассмотрим и продемонстрируем функциональные эксплойты для WinAPRS в Windows XP SP3 и Windows 10.
Ключевые моменты:
1. Windows XP легче эксплуатировать в данном случае из-за отсутствия ASLR.
2. Windows 10 можно эксплуатировать после обработки памяти кучи вредоносными радиопакетами.
3. WinAPRS, скорее всего, останется непропатченной.
В четвертой части этой серии мы создали трехэтапную полезную нагрузку шеллкода для преодоления проблем, возникающих из-за поврежденной памяти стека в процессе WinAPRS. Теоретически шелл-код порождает обратную оболочку и перенаправляет ее вывод на TNC радиолюбителя, откуда он затем передается по воздуху. Затем шелл-код будет прослушивать входящие команды с последовательного порта TNC.
В этом выпуске будет рассмотрен окончательный код эксплойта Python. Эксплойт будет передавать трехэтапный шеллкод в двух отдельных пакетах AX.25. Затем он прослушивает ответ от компьютера-жертвы и позволяет злоумышленнику отправлять команды обратно по любительскому радио. Затем мы вернемся к Windows 10 и найдем способ обойти защиту рандомизации адресного пространства (ASLR), чтобы создать рабочий эксплойт для более современной операционной системы.
Код эксплойта Python основан на общедоступном скрипте Python с именем send_kiss_frame.py , который позволяет создавать пользовательские пакеты AX.25. Три этапа шелл-кода собираются отдельно в строки байтов Python и вставляются в окончательный сценарий эксплойта.
Окончательная полезная нагрузка состоит из управляющих символов KISS для начала и завершения вредоносного пакета. Кроме того, существуют компоненты адресации AX.25, обеспечивающие правильную обработку пакета WinAPRS. Часть сообщения пакета APRS начинается с шеллкода первого этапа, за которым сразу следует второй этап. Затем эксплойт заполняет все пробелы символами «A», гарантируя, что адреса NSEH и SEH окажутся в правильных позициях. Затем добавляются адреса NSEH и SEH. NSEH содержит код перехода, который указывает процессору перепрыгнуть через адрес SEH и продолжить выполнение.
После SEH-адреса идет дополнительный код перехода, указывающий процессору на начало первого этапа шеллкода. Наконец, некоторые символы 'C' добавляются к концу, чтобы гарантировать, что длина пакета достаточна для запуска переполнения.
Эксплойт немедленно отправляет первый пакет, а затем ожидает ввода данных пользователем. Для срабатывания эксплойта и закрытия WinAPRS требуется несколько секунд. Затем злоумышленник может нажать Enter, чтобы отправить третий этап, а затем сидеть сложа руки и ждать своей оболочки.
Успех! Эксплойт сработал. Теперь у меня был функциональный эксплойт, который позволил мне взломать компьютер с Windows XP SP3, используя только радиолюбители. Эта целевая виртуальная машина имела подключение к Ethernet, но этот эксплойт все равно будет работать, даже если цель не подключена к обычной сети. Если в системе работает WinAPRS с KISS TNC, она по-прежнему уязвима для атаки.
Демо Windows XP
В третьей части я намекнул, что мне удалось заставить этот эксплойт работать в Windows 10. Он требует дополнительного шага и менее надежен, но он работает. Основная проблема с использованием этой уязвимости в современных версиях Windows — ASLR. Программная память WinAPRS содержит нулевой байт, что означает, что мы не можем указать EIP на какой-либо адрес в памяти WinAPRS. Поскольку Windows 10 использует ASLR, также нет надежного адреса для указания ЦП для инструкций POP, POP, RET в любых встроенных модулях Windows, поскольку базовый адрес встроенных модулей Windows меняется при каждой перезагрузке. Однако есть способ определить ненадежный адрес, содержащий полезную нагрузку нашего шелл-кода.
Я отправил несколько пакетов своей жертве WinAPRS и искал их в памяти процесса с помощью WinDbg.
Я обнаружил, что они все сгрудились рядом друг с другом. Я заметил, что их адрес памяти не содержит нулевого байта.
Я обнаружил, что это был кусок памяти в куче размером 1004 КБ, выделенный WinAPRS, по-видимому, для хранения данных этого пакета.
Я обнаружил, что при перезапуске WinAPRS этот адрес изменился. Иногда много, иногда немного. Казалось, что есть несколько областей памяти, с которых Windows «любила» начинать, а затем точное местоположение немного отличалось от них. Например, я видел этот кусок памяти, выделенный в диапазонах адресов 0x03128000-0x03296000, 0x05d8a000-0x05f7d000 и 0x08102000-08301000. Эти области памяти оставались неизменными между перезагрузками. Это означало, что выбранный адрес памяти кучи был несколько предсказуем.
Выделенный фрагмент памяти размером 1004 КБ был достаточно большим, чтобы перекрывать большие участки каждого из этих трех основных диапазонов. Если бы я мог заполнить весь кусок памяти собственными полезными нагрузками, содержащими инструкции POP, POP, RET, у меня был бы приличный шанс попасть в одну из них. Я утомительно провел более 30 тестов вручную и выбрал адрес 0x03216170. Судя по данным, которые мне удалось собрать, у него было наибольшее совпадение.
Следующим шагом было найти способ заполнить этот буфер кучи моими собственными пакетами. Я не собирался посылать их по воздуху для каждого теста. Это займет несколько часов на одну попытку. Вместо этого я написал скрипт Python, который эмулировал KISS TNC в Windows и отправлял пакеты KISS напрямую в WinAPRS, минуя радиоволны, чтобы просто доказать свою концепцию. Методом проб и ошибок я вычислил максимальное количество байтов, которое я мог бы поместить в свой пакет, и чтобы все они по-прежнему отображались в буфере. Я также обнаружил, что инструкция RET (0xC3) была отфильтрована WinAPRS и не может быть использована. Поэтому я заменил инструкции POP, POP, RET на инструкцию JMP [esp+0x08], которая имела тот же эффект, но без плохого символа. Остальная часть полезной нагрузки была заполнена NOP (0x90). Это называется «сани NOP». Если мой жестко запрограммированный адрес кучи попадает в любое место в цепочке NOP, ЦП просто пропускает каждую инструкцию NOP до тех пор, пока в конце не встретится эквивалентные инструкции POP, POP, RET. Я также обнаружил, что буфер может содержать около 10 000 пакетов, так что именно столько пакетов отправляет сценарий. Это максимально заполняет буфер и дает эксплойту больше шансов выполнить последовательность инструкций JMP [esp+0x08].
Первым шагом запуска эксплойта против Windows 10 является запуск этого скрипта heap spray против жертвы. В реальной атаке вам пришлось бы отправить эти 10 000 пакетов по воздуху один за другим, блокируя частоту от кого-либо еще. Это может сработать, но это не очень практично и, безусловно, привлечет внимание. Этот сценарий имитирует этот процесс, чтобы сэкономить время и подтвердить концепцию.
Эксплойт для Windows 10 работает аналогично эксплойту для Windows XP с некоторыми изменениями.
Во-первых, в куче нет структур, требующих «исправления» шелл-кодом. Кроме того, в Windows 10 я могу вызывать большинство API-интерфейсов Win32 прямо с первой полезной нагрузки. В Windows XP это было невозможно из-за поврежденной памяти стека. Однако в Windows 10 я не нашел надежного адреса памяти для получения дескриптора COM-порта. Это означает, что у меня нет надежного способа доступа к COM-порту для отправки или получения данных с атакующей машины. После долгих проб и ошибок я обнаружил, что самый простой способ освободить COM-порт — просто закрыть процесс WinAPRS. Однако это убьет полезную нагрузку эксплойта, поэтому я все еще застрял, используя несколько этапов шеллкода, внедренных во внешний процесс, как я сделал с Windows XP.
Еще одна проблема заключается в том, что Windows 10 — 64-разрядная операционная система. Explorer.exe — это 64-битный процесс. Мой шеллкод — 32-битный шеллкод. Это означает, что метод внедрения шелл-кода в explorer.exe в Windows XP больше не будет работать, если я не перепишу его для использования 64-битной сборки. Вместо того, чтобы заново изобретать велосипед, шеллкод первого этапа теперь вызывает CreateProcessA для запуска 32-разрядного процесса cmd.exe. Затем первый этап внедряет второй этап в этот процесс вместо explorer.exe, который затем будет использоваться для выполнения второго этапа. 32-битный процесс cmd.exe действует как контейнер для выполнения нашего 32-битного шелл-кода.
Шеллкод второй и третьей стадий почти идентичен шеллкоду Windows XP с одним упрощением. Для шеллкода Windows 10 я не закрываю COM-порт в конце второго этапа. Вместо этого я оставляю его открытым, и на третьем этапе используется тот же дескриптор, что и на втором.
Эксплойт для Windows 10 менее надежен, чем эксплойт для XP, потому что он зависит от выбора Windows адреса кучи памяти, который включает жестко запрограммированный адрес 0x03216170 в эксплойте. Если Windows выберет расположение кучи слишком далеко от этого места, мы не попадем в нашу NOP-цепочку, и WinAPRS просто рухнет. Я обнаружил, что эта техника срабатывает примерно в трети случаев, а может быть, и в немного меньшем количестве. Это также требует, чтобы злоумышленник потратил несколько часов, рассылая спам-пакеты жертве, чтобы очистить кучу. Но это показывает, что злоумышленник с достаточной решимостью все еще может использовать эту уязвимость в современной операционной системе.
Демо Windows 10
Я сообщил об этой и некоторых других ошибках авторам программного обеспечения 28 декабря 2020 г. Я не был уверен, что получу ответ, поскольку программное обеспечение не обновлялось с 2013 г., но был удивлен, услышав ответ от них почти сразу. У меня был отличный разговор с автором об обнаруженной мной ошибке и других категориях уязвимостей безопасности, которые их интересовали, связанных с новым проектом, над которым они работали. Я даже вдохновил их на поиск ошибок переполнения в их новом проекте! К сожалению, у автора больше нет среды, сконфигурированной для разработки WinAPRS, так что ошибки вряд ли когда-нибудь будут исправлены. К счастью, есть много других более современных вариантов программного обеспечения APRS для Windows, поэтому легко переключиться на что-то новое.
CVE были получены 9 февраля 2022 года.
Coalfire публично раскрывает эту ошибку в соответствии с нашей политикой раскрытия информации об уязвимостях. Полную информацию можно найти здесь: https://www.coalfire.com/vulnerability-disclosure-policy
Полный исходный код этих эксплойтов можно найти здесь: https://github.com/Coalfire-Research/WinAPRS-Exploits
PDF-версию этой серии блогов можно найти здесь: /documents/blog/Hacking-Ham-Radio-WinAPRS.
Перевод ЭТОЙ статьи
Ключевые моменты:
1. Windows XP легче эксплуатировать в данном случае из-за отсутствия ASLR.
2. Windows 10 можно эксплуатировать после обработки памяти кучи вредоносными радиопакетами.
3. WinAPRS, скорее всего, останется непропатченной.
В четвертой части этой серии мы создали трехэтапную полезную нагрузку шеллкода для преодоления проблем, возникающих из-за поврежденной памяти стека в процессе WinAPRS. Теоретически шелл-код порождает обратную оболочку и перенаправляет ее вывод на TNC радиолюбителя, откуда он затем передается по воздуху. Затем шелл-код будет прослушивать входящие команды с последовательного порта TNC.
В этом выпуске будет рассмотрен окончательный код эксплойта Python. Эксплойт будет передавать трехэтапный шеллкод в двух отдельных пакетах AX.25. Затем он прослушивает ответ от компьютера-жертвы и позволяет злоумышленнику отправлять команды обратно по любительскому радио. Затем мы вернемся к Windows 10 и найдем способ обойти защиту рандомизации адресного пространства (ASLR), чтобы создать рабочий эксплойт для более современной операционной системы.
Эксплойт
Эксплойт Windows XP SP3
Код эксплойта Python основан на общедоступном скрипте Python с именем send_kiss_frame.py , который позволяет создавать пользовательские пакеты AX.25. Три этапа шелл-кода собираются отдельно в строки байтов Python и вставляются в окончательный сценарий эксплойта.
Окончательная полезная нагрузка состоит из управляющих символов KISS для начала и завершения вредоносного пакета. Кроме того, существуют компоненты адресации AX.25, обеспечивающие правильную обработку пакета WinAPRS. Часть сообщения пакета APRS начинается с шеллкода первого этапа, за которым сразу следует второй этап. Затем эксплойт заполняет все пробелы символами «A», гарантируя, что адреса NSEH и SEH окажутся в правильных позициях. Затем добавляются адреса NSEH и SEH. NSEH содержит код перехода, который указывает процессору перепрыгнуть через адрес SEH и продолжить выполнение.
После SEH-адреса идет дополнительный код перехода, указывающий процессору на начало первого этапа шеллкода. Наконец, некоторые символы 'C' добавляются к концу, чтобы гарантировать, что длина пакета достаточна для запуска переполнения.
Эксплойт немедленно отправляет первый пакет, а затем ожидает ввода данных пользователем. Для срабатывания эксплойта и закрытия WinAPRS требуется несколько секунд. Затем злоумышленник может нажать Enter, чтобы отправить третий этап, а затем сидеть сложа руки и ждать своей оболочки.
Успех! Эксплойт сработал. Теперь у меня был функциональный эксплойт, который позволил мне взломать компьютер с Windows XP SP3, используя только радиолюбители. Эта целевая виртуальная машина имела подключение к Ethernet, но этот эксплойт все равно будет работать, даже если цель не подключена к обычной сети. Если в системе работает WinAPRS с KISS TNC, она по-прежнему уязвима для атаки.
Демо Windows XP
Эксплойт Windows 10
В третьей части я намекнул, что мне удалось заставить этот эксплойт работать в Windows 10. Он требует дополнительного шага и менее надежен, но он работает. Основная проблема с использованием этой уязвимости в современных версиях Windows — ASLR. Программная память WinAPRS содержит нулевой байт, что означает, что мы не можем указать EIP на какой-либо адрес в памяти WinAPRS. Поскольку Windows 10 использует ASLR, также нет надежного адреса для указания ЦП для инструкций POP, POP, RET в любых встроенных модулях Windows, поскольку базовый адрес встроенных модулей Windows меняется при каждой перезагрузке. Однако есть способ определить ненадежный адрес, содержащий полезную нагрузку нашего шелл-кода.
Я отправил несколько пакетов своей жертве WinAPRS и искал их в памяти процесса с помощью WinDbg.
Я обнаружил, что они все сгрудились рядом друг с другом. Я заметил, что их адрес памяти не содержит нулевого байта.
Я обнаружил, что это был кусок памяти в куче размером 1004 КБ, выделенный WinAPRS, по-видимому, для хранения данных этого пакета.
Я обнаружил, что при перезапуске WinAPRS этот адрес изменился. Иногда много, иногда немного. Казалось, что есть несколько областей памяти, с которых Windows «любила» начинать, а затем точное местоположение немного отличалось от них. Например, я видел этот кусок памяти, выделенный в диапазонах адресов 0x03128000-0x03296000, 0x05d8a000-0x05f7d000 и 0x08102000-08301000. Эти области памяти оставались неизменными между перезагрузками. Это означало, что выбранный адрес памяти кучи был несколько предсказуем.
Выделенный фрагмент памяти размером 1004 КБ был достаточно большим, чтобы перекрывать большие участки каждого из этих трех основных диапазонов. Если бы я мог заполнить весь кусок памяти собственными полезными нагрузками, содержащими инструкции POP, POP, RET, у меня был бы приличный шанс попасть в одну из них. Я утомительно провел более 30 тестов вручную и выбрал адрес 0x03216170. Судя по данным, которые мне удалось собрать, у него было наибольшее совпадение.
Следующим шагом было найти способ заполнить этот буфер кучи моими собственными пакетами. Я не собирался посылать их по воздуху для каждого теста. Это займет несколько часов на одну попытку. Вместо этого я написал скрипт Python, который эмулировал KISS TNC в Windows и отправлял пакеты KISS напрямую в WinAPRS, минуя радиоволны, чтобы просто доказать свою концепцию. Методом проб и ошибок я вычислил максимальное количество байтов, которое я мог бы поместить в свой пакет, и чтобы все они по-прежнему отображались в буфере. Я также обнаружил, что инструкция RET (0xC3) была отфильтрована WinAPRS и не может быть использована. Поэтому я заменил инструкции POP, POP, RET на инструкцию JMP [esp+0x08], которая имела тот же эффект, но без плохого символа. Остальная часть полезной нагрузки была заполнена NOP (0x90). Это называется «сани NOP». Если мой жестко запрограммированный адрес кучи попадает в любое место в цепочке NOP, ЦП просто пропускает каждую инструкцию NOP до тех пор, пока в конце не встретится эквивалентные инструкции POP, POP, RET. Я также обнаружил, что буфер может содержать около 10 000 пакетов, так что именно столько пакетов отправляет сценарий. Это максимально заполняет буфер и дает эксплойту больше шансов выполнить последовательность инструкций JMP [esp+0x08].
Первым шагом запуска эксплойта против Windows 10 является запуск этого скрипта heap spray против жертвы. В реальной атаке вам пришлось бы отправить эти 10 000 пакетов по воздуху один за другим, блокируя частоту от кого-либо еще. Это может сработать, но это не очень практично и, безусловно, привлечет внимание. Этот сценарий имитирует этот процесс, чтобы сэкономить время и подтвердить концепцию.
Эксплойт для Windows 10 работает аналогично эксплойту для Windows XP с некоторыми изменениями.
Во-первых, в куче нет структур, требующих «исправления» шелл-кодом. Кроме того, в Windows 10 я могу вызывать большинство API-интерфейсов Win32 прямо с первой полезной нагрузки. В Windows XP это было невозможно из-за поврежденной памяти стека. Однако в Windows 10 я не нашел надежного адреса памяти для получения дескриптора COM-порта. Это означает, что у меня нет надежного способа доступа к COM-порту для отправки или получения данных с атакующей машины. После долгих проб и ошибок я обнаружил, что самый простой способ освободить COM-порт — просто закрыть процесс WinAPRS. Однако это убьет полезную нагрузку эксплойта, поэтому я все еще застрял, используя несколько этапов шеллкода, внедренных во внешний процесс, как я сделал с Windows XP.
Еще одна проблема заключается в том, что Windows 10 — 64-разрядная операционная система. Explorer.exe — это 64-битный процесс. Мой шеллкод — 32-битный шеллкод. Это означает, что метод внедрения шелл-кода в explorer.exe в Windows XP больше не будет работать, если я не перепишу его для использования 64-битной сборки. Вместо того, чтобы заново изобретать велосипед, шеллкод первого этапа теперь вызывает CreateProcessA для запуска 32-разрядного процесса cmd.exe. Затем первый этап внедряет второй этап в этот процесс вместо explorer.exe, который затем будет использоваться для выполнения второго этапа. 32-битный процесс cmd.exe действует как контейнер для выполнения нашего 32-битного шелл-кода.
Шеллкод второй и третьей стадий почти идентичен шеллкоду Windows XP с одним упрощением. Для шеллкода Windows 10 я не закрываю COM-порт в конце второго этапа. Вместо этого я оставляю его открытым, и на третьем этапе используется тот же дескриптор, что и на втором.
Эксплойт для Windows 10 менее надежен, чем эксплойт для XP, потому что он зависит от выбора Windows адреса кучи памяти, который включает жестко запрограммированный адрес 0x03216170 в эксплойте. Если Windows выберет расположение кучи слишком далеко от этого места, мы не попадем в нашу NOP-цепочку, и WinAPRS просто рухнет. Я обнаружил, что эта техника срабатывает примерно в трети случаев, а может быть, и в немного меньшем количестве. Это также требует, чтобы злоумышленник потратил несколько часов, рассылая спам-пакеты жертве, чтобы очистить кучу. Но это показывает, что злоумышленник с достаточной решимостью все еще может использовать эту уязвимость в современной операционной системе.
Демо Windows 10
Раскрытие информации
Я сообщил об этой и некоторых других ошибках авторам программного обеспечения 28 декабря 2020 г. Я не был уверен, что получу ответ, поскольку программное обеспечение не обновлялось с 2013 г., но был удивлен, услышав ответ от них почти сразу. У меня был отличный разговор с автором об обнаруженной мной ошибке и других категориях уязвимостей безопасности, которые их интересовали, связанных с новым проектом, над которым они работали. Я даже вдохновил их на поиск ошибок переполнения в их новом проекте! К сожалению, у автора больше нет среды, сконфигурированной для разработки WinAPRS, так что ошибки вряд ли когда-нибудь будут исправлены. К счастью, есть много других более современных вариантов программного обеспечения APRS для Windows, поэтому легко переключиться на что-то новое.
CVE были получены 9 февраля 2022 года.
- CVE-2022-24702
- CVE-2022-24701
- CVE-2022-24700
Coalfire публично раскрывает эту ошибку в соответствии с нашей политикой раскрытия информации об уязвимостях. Полную информацию можно найти здесь: https://www.coalfire.com/vulnerability-disclosure-policy
Полный исходный код этих эксплойтов можно найти здесь: https://github.com/Coalfire-Research/WinAPRS-Exploits
PDF-версию этой серии блогов можно найти здесь: /documents/blog/Hacking-Ham-Radio-WinAPRS.
Перевод ЭТОЙ статьи
Like