WordPress или вагон 0day уязвимостей. Продолжаем хак популярнейшего движкаМаг (icq 884888, http://wap-chat.ru) Рамки предыдущей статьи не позволили мне рассказать еще о нескольких интереснейших неопубликованных уязвимостях и банальных недоработках WordPress. Так что сейчас ты сможешь прочитать продолжение penetration-теста известнейшей блоговой платформы. Итак, поехали! СтатистикаДля начала я хочу привести некоторые статистические данные из исследования, которое было проведено мной в середине января сего года.
Можно понять, что наиболее популярными и представляющими для нас с тобой интерес ветками являются 2.3.x, 2.5.x, 2.6.x, 2.7.x (2.4.x разработчики пропустили по определенным причинам). В то же время, в этих ветках найдено и опубликовано очень малое количество уязвимостей (напомню, что последняя sql-инъекция была в паблике в 2.2.2 версии). Шутка юмораПредставь, что на нужном нам блоге присутствует пост с адресом Для начала детально разберем механизм постинга комментария в последней на момент написания статьи версии 2.7.1. 1. Файлик wp-comments-post.php (а также wp-trackback.php), через который проходят все комментарии имеет в себе следующий код:
2. Эту функцию мы можем легко отыскать в ./wp-includes/comment.php:
3. Там же проводим небольшой реверсинг:
4. Action edit_post определен в ./wp-includes/default-filters.php: 5. Находим нужную нам функцию в ./wp-includes/post.php:
6. И, собственно, зачем весь этот код нам был нужен, ./wp-includes/query.php:
Из анализа вышеприведенного кода следует вывод: если в БД для определенного поста присутствует значение «_wp_old_slug», то по нему проводится редирект на настоящий адрес поста. Чтобы добавить это значение, твой комментарий должен быть зааппрувлен. Как оставлять комментарии без проверки модератора, ты уже знаешь по первой части статьи :). Теперь, наконец-то, готовый эксплойт для нашей шутки:
В поле «Slug» вставляй новое имя для подходящего поста и показывай ссылку админу, наблюдая за его реакцией. Небезопасный SnoopyНастало время сделать еще один реверанс в сторону предыдущей статьи. Как ты, наверное, помнишь, WordPress 2.5.x-2.6.x позволял любому зарегистрированному пользователю с легкостью подменять RSS-фиды в Dashboard. Раскопав этот замечательный баг немного глубже, мы с легкостью сможем добиться выполнения произвольного кода на сервере, где установлен блог. Итак, вспомним об обнаруженной забугорными кодокопателями code exec уязвимости в классе Snoopy, который присутствует также и в вордпрессе. Сама уязвимость в вордпрессовском Snoopy была пропатчена с помощью escapeshellcmd еще в 1.5.x ветке, но, тем не менее, разработчики взяли и испортили вполне работоспособный код непонятным патчем в версии 2.6.3. Я догадываюсь, чем они думали, смотря на пост девблога с такими словами: А также при сравнении кода Snoopy из WordPress <= 2.6.2: – с кодом Snoopy из WordPress <= 2.6.5: Второй код - это официальный патч разработчиков Snoopy, который закрывает предыдущий code exec (но не закрывает новый). Забавно, не правда ли? Зачем патчить то, что и так было неплохо пропатчено? Ответы на эти вопросы мы вряд ли узнаем. Такая халатность разработчиков открыла мне путь к замечательной уязвимости. Но обо всем по порядку. 1. Способом из первой части статьи редактируй любую RSS-ленту на главной странице админки, причем адрес ставь на свой хитрый скрипт, например, http://lamer.com/code-exec.php; 2. Скрипт code-exec.php должен содержать следующий код:
После совершения этих нехитрых действий на нужный блог в ./wp-content/test.php зальется шелл. Теперь разберем, где и почему это возможно: 1. Только на WordPress 2.6.3, 2.6.5 (2.6.4 просто не было, а в 2.7 Snoopy уже практически не используется) с открытой регистрацией, необходимой для редактирования рсс-фидов; 2. Только на системах, где curl установлен в /usr/local/bin/curl (наиболее распространенная система с таким конфигом - FreeBSD), так как этот самый пресловутый путь жестко прописан в ./wp-includes/class-snoopy.php, плюс бинарник курла проверяется на существование и исполнимость:
3. Это работает, потому что Snoopy поддерживает переадресацию (до 5 раз по дефолту). Во время нее он может установить кукисы и другие хэдеры, которые пошлет серверный скрипт. Как можно понять из псевдопатча, над фильтрацией хэдеров при передаче их в exec() никто, конечно же, не задумывался. 4. Это работает не только в кукисах, но и во многих других заголовках. Например, мы сможем передать произвольный код в заголовке HOST следующим образом:
Хитрый uploadНа очереди – замечательная SQL-инъекция, обнаруженная товарищем Электом больше года назад во всех вордпрессах версий 2.2.x-2.3.x. Для ее использования юзер должен обладать правами «upload_files» (то есть, роль Автора/Редактора). Рассмотрим исходный код интерфейса для удаленной публикации в WordPress - xmlrpc.php (да-да, именно в этом файле было обнаружено наибольшее число SQL-инъекций движка). В интерфейсе присутствует метод metaWeblog.newMediaObject, являющийся прямой отсылкой к функции mw_newMediaObject. Проведем небольшой реверсинг: 1. ./xmlrpc.php
2. ./wp-includes/post.php
Проследив весь путь переменной $type, ты поймешь, что никто не позаботился о ее фильтрации перед вставкой в SQL-запрос :). Поэтому мы легко сможем проинжектить UPDATE запрос, например, послав такой POST-пакет к xmlrpc.php:
После отправки пакета на блог жертвы поторопись пройти в админку: Manage => Uploads. В поле «URL» в случае удачного срабатывания эксплойта ты увидишь хеш и пароль админа. Фокусы с курломПредставляю твоему вниманию очередную уязвимость WordPress (найденную не без помощи Электа), которая заключается в проверке существования любого файла на уязвимом блоге. Подвержены все версии движка, начиная с 2.7. Для начала нужно сказать, что это не совсем уязвимость вордпресса, а, скорее, фича curl, php-библиотеку которого как раз и юзает WordPress вместо ушедшего в небытие Snoopy. Итак, уязвимость курла заключается в том, что он с радостью может прочитать для тебя не только удаленные файлы по http, но и локальные с помощью префикса «file://»! Но, как правило, префиксы проверяются скриптами еще на входе и, казалось бы, «file://» заюзать невозможно. Однако никто не подумал о том, что curl поддерживает переадресацию с помощью флага «CURLOPT_FOLLOWLOCATION». То есть, – подставив курлу вполне обычный http, на выходе мы можем получить чтение произвольного локального файла (подробное advisory от первооткрывателя ищи в сносках)! В вордпрессе множество файлов юзают класс ./wp-includes/http.php, но сейчас мы рассмотрим лишь один из наиболее доступных pre-auth способов эксплуатациии баги (найти другие способы в админке - твое домашнее задание:)). 1. ./wp-includes/http.php
Да-да! Ты видишь тот самый флаг, отвечающий за поддержку редиректа! Дальше опустим заумный код, но скажу лишь, что по дефолту (всего возможны четыре варианта) в качестве транспорта http-данных вордпресс выбирает курл:
2. Функция, приведенная выше, используется в ./wp-includes/functions.php:
3. И, наконец, эта же функция используется в уже полюбившемся тебе интерфейсе xmlrpc:
Теперь у нас есть все необходимое для написания эксплойта, – к чему мы сейчас и приступим. А был ли файл?Как ты уже понял, действовать мы будем через механизм пингбэков, про который я уже неоднократно рассказывал в предыдущих номерах ][.
Для работы нам понадобятся два файла, доступных по http. Например, такие: 1. ./ping1/index.php
2. ./ping2/index.php
В этом примере первый файл сможет пропинговать второй, благодаря еще одной недоработке вордпресса. Смотри в механизм пингов xmlrpc.php: В этой проверке вовсе не нужно, чтобы второй пингуемый сайт обязательно был текущим блогом, так как мы можем обойти проверку, вставив адрес этого самого блога. Например, в конце URL после решетки. Все готово для проверки наличия файла c:\boot.ini на тестируемой системе. Для эксплуатации уязвимости тебе необходимо лишь послать следующий POST-пакет для сервера xmlrpc:
После отсылки пакета ты сможешь получить два ответа от сервера: 1. Если файл c:\boot.ini существует, то блог пришлет такой ответ – 2. Если такого файла нет, то жди такого ответа – Кстати, этим способом вполне было бы возможно прочитать содержимого любого файла системы, если бы пингбэк не урезался до очень малого количества символов. Так что, в комментарии-пингбэке ты увидишь лишь что-то вроде: Содержимое c:\boot.ini остается где-то под катом :). Описанный способ эксплуатации уязвимости не является единственным. В админке ты сможешь найти и другие вызовы функции wp_get_http(), которые и позволят тебе читать файлы на системе. Найти их - уже твоя задача. To be continued...Ну что, ты все еще считаешь WordPress безопасным движком? Не забывай: злостные кодокопатели ежедневно вдоль и поперек мучают WordPress codebase. Как говорится, «Продолжение следует...» :). INFOСпасибо Raz0r за написание code exec эксплойта для WordPress 2.6.x, а также Elekt за предоставленные уязвимости. Ссылки по теме
|