
Университетское задание, документирующее CVE-2020-8597 — переполнение буфера стека в EAP-парсере pppd, с демонстрацией эксплуатации удалённого выполнения кода с использованием настройки pppoe-server и клиента.
Шри-Ланкийский институт информационных технологий
Задание 1
M. P. D. M. Dias
IT19165530
MLB_WD_Y2S1_13.1
Уязвимость RCE в демоне Point to Point Protocol
(CVE-2020-8597)
Системное и сетевое программирование – IE2012
Содержание
Введение
Протокол Point-to-Point (PPP) — это полнодуплексный протокол, который позволяет инкапсулировать и передавать простые данные через инфраструктуру уровня 2 (канального уровня), начиная от коммутируемого доступа (dial-up) и широкополосных DSL-соединений и заканчивая виртуальными частными сетями (VPN) с SSL-шифрованием. Поскольку эти протоколы не поддерживают связь «точка-точка», PPP также используется для организации работы IP и TCP поверх двух напрямую соединённых узлов. Pppd — это демон, используемый в Unix-подобных операционных системах для управления установлением PPP-сеансов и их завершением между двумя узлами.
PPP — это протокол, используемый для создания интернет-соединений через коммутируемые модемы, DSL-соединения и некоторые другие виды соединений «точка-точка» через виртуальные частные сети (VPN), такие как протокол туннелирования «точка-точка» (PPTP). Программа pppd также может аутентифицировать узел, подключающийся к сети, и/или предоставлять узлу данные аутентификации с использованием различных протоколов аутентификации, таких как EAP.
Из-за ошибки в обработке пакета протокола расширяемой аутентификации (EAP) в демоне Point-to-Point Protocol (pppd) неаутентифицированный удалённый злоумышленник может вызвать переполнение буфера стека, что может позволить произвольное выполнение кода в целевой системе. Эта уязвимость вызвана ошибкой проверки размера входных данных перед копированием предоставленных данных в память. Поскольку проверка размера данных выполняется некорректно, в память могут быть скопированы случайные данные, что может вызвать утечку файлов и способствовать непреднамеренному выполнению кода.
Уязвимость кроется в логике кода разбора EAP, а именно в функциях eap_request() и eap_response() в файле eap.c, которые вызывает сетевой обработчик ввода. Эти функции принимают указатель и длину, используя первый байт как тип. Если типом является EAPT MD5CHAP(4), то функция обращается к встроенному полю длины размером 1 байт. Логика этого кода предназначена для проверки того, что встроенная длина меньше общей длины пакета. После этой проверки код пытается скопировать предоставленные данные (имя хоста), которые располагаются в локальном стековом буфере после поля встроенной длины. Эта проверка границ некорректна и допускает копирование в память данных произвольной длины.
Ещё одна логическая ошибка приводит к тому, что функция eap_input() не проверяет, был ли EAP согласован в процессе протокола управления линией (LCP). Это позволяет неаутентифицированному злоумышленнику отправлять EAP-пакет, даже если pppd отказался согласовывать аутентификацию из-за отсутствия поддержки EAP или из-за несоблюдения согласованной предварительно общей кодовой фразы на этапе LCP. В eap_input() небезопасный код pppd всё равно должен обработать EAP-пакет и вызвать переполнение буфера стека. Эти непроверенные данные неизвестного размера могут быть использованы для компрометации памяти целевого устройства. Кроме того, pppd работает с высокими привилегиями (системными или root) и взаимодействует с драйверами ядра.
Программа pppd также используется совместно с проектом lwIP (lightweight IP) для предоставления функциональности pppd на малых компьютерах. Стандартные установки lwIP не подвержены этому переполнению буфера. Однако если использовать исходный код lwIP и явно изменить его для разрешения EAP на этапе компиляции, программа может оказаться уязвимой к переполнению буфера.
CVE-2020-8597 — это ошибка переполнения буфера в pppd, вызванная логическим дефектом в обработчике пакетов протокола расширяемой аутентификации (EAP). Неавторизованный удалённый злоумышленник, отправляющий специально созданный EAP-пакет уязвимому PPP-клиенту или серверу, может вызвать отказ в обслуживании или произвольное выполнение кода. Поскольку pppd работает совместно с драйверами ядра и обладает высокими привилегиями, такими как device или даже core, любое выполнение кода также может быть осуществлено с теми же привилегиями.
Сведения об авторе обнаружения уязвимости
Критическая проблема, обнаруженная исследователем безопасности IOActive Ильёй ван Спрунделем (Ilja Van Sprundel), представляет собой ошибку переполнения буфера стека, возникающую из-за логической ошибки в анализаторе модуля протокола расширяемой аутентификации (EAP) приложения pppd — расширения, обеспечивающего поддержку дополнительных методов аутентификации в PPP-соединениях.
Эта уязвимость, отслеживаемая как CVE-2020-8597 с оценкой CVSS 9.8, может быть использована неавторизованными злоумышленниками для удалённого выполнения произвольного кода на затронутых устройствах и получения полного контроля над ними.
Как была обнаружена уязвимость
Эта уязвимость вызвана ошибкой проверки размера входных данных перед копированием данных в память. Поскольку проверка размера данных выполняется некорректно, в память могут быть скопированы случайные данные, что может вызвать повреждение памяти и, вероятно, способствовать выполнению неавторизованного кода.
Уязвимость находится в логике кода разбора EAP, а именно в функциях eap_request() и eap_response() в файле eap.c, которые вызываются сетевым обработчиком ввода.
Ошибочно полагать, что pppd защищён, если EAP не разрешён или если EAP не был инициирован удалённым узлом с использованием пароля или кодовой фразы. Это связано с тем, что неаутентифицированный злоумышленник всегда может отправить непрошеный EAP-пакет, чтобы вызвать переполнение буфера.
Уязвимость была выявлена в демоне протокола Point-to-Point (PPP), или pppd. PPP — это протокол уровня 2, используемый для установления соединений через коммутируемые модемы, DSL-подключения и многие другие физические сети, включая мобильные сети. PPP был расширен дополнительными протоколами, такими как протокол туннелирования «точка-точка» (PPTP), который используется в виртуальных частных сетях (VPN) для обеспечения зашифрованных соединений.
В этой ситуации команда SEI CERT объединила усилия с аналитиком безопасности Ильёй ван Спрунделем (IOActive), обнаружившим эту ошибку, и разработчиком Полом Маккеррасом (OZlabs), который сопровождает исходный код, чтобы детально изучить проблему и найти решение. Проблема заключалась в переполнении буфера в исходном коде pppd, вызванном ошибкой в булевом выражении и реализации условных операторов, ставших его следствием. Приведённый ниже оператор можно обмануть, заставив его принять входные данные неизвестной длины и скопировать их в стековый буфер. Это обычно называют переполнением стека или переполнением буфера стека.
if (vallen >= len + sizeof(rhostname)) { // Copy to buffer rhostname
Исправление уязвимости заключалось в простой замене приведённого выше оператора на следующее булево выражение.
if (len-vallen >= sizeof(rhostname)) { // Copy to buffer rhostname