Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Mikołajki z sekurakiem! od 2 do 8 grudnia!
Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Mikołajki z sekurakiem! od 2 do 8 grudnia!
Komponent WebView sprawia, że aplikacje mobilne mogą zostać wzbogacone o funkcję przeglądarki stron internetowych, co pozwala im na wyświetlanie stron, nawigację, wykonywanie kodu JavaScript, nawiązywanie połączeń szyfrowanych itp. Wszystkie powyższe czynności wykonywane są w kontekście aplikacji mobilnej, a nie w sandboxie przeglądarki takiej jak Chrome czy Firefox. Wraz z tymi dodatkowymi funkcjami pojawiają się dodatkowe zagrożenia i zwiększenie powierzchni ataku na aplikację mobilną. Co więcej, wg. badań z 2015 większość aplikacji bankowych korzysta z tego komponentu do wyświetlania stron HTML i przetwarza JavaScript za pomocą WebView. W tym artykule przedstawię wektory ataku na aplikacje mobilne poprzez WebView oraz sposoby na ograniczenie ryzyk z nimi związanych. W artykule przedstawione są przykłady dla platformy Android, jednakże analogiczne zagrożenia występują w Windows Phone i iOS.
Modele zagrożeń
Zagrożenia dla aplikacji mobilnej poprzez WebView możemy podzielić na dwie kategorie:
Użycie WebView i zagrożenia z tym związane
1. Java-to-JavaScript Interface
Deweloperzy korzystając z komponentu WebView muszą mieć świadomość, że niewłaściwa konfiguracja i złe użycie tego komponentu może doprowadzić do powstania krytycznych luk bezpieczeństwa.
Podstawowe użycie WebView w aplikacji mobilnej na Androidzie.
WebView webview = new WebView(this); setContentView(webview);
Kolejnym krokiem mogłoby być odwołanie się do zasobów w sieci web (http:// lub https://):
webview.loadUrl("http://good-website.com");
Atakujący, który ma kontrolę nad ruchem sieciowym w przejętej sieci WiFI posiada możliwość przekierowanie do innego zasobu i/lub modyfikacji danej strony poprzez wstrzyknięcie własnego kodu HTML. W przypadku aplikacji, które nie stosują takich mechanizmów jak cert pinning atakujący ma realne szanse modyfikacji ruchu https.
Często deweloperzy włączają różne dodatkowe opcje komponentu WebView poprzez klasę WebSettings, które domyślnie nie są uruchomione, jedną z najczęściej uruchamianych opcji jest włączenie obsługi kodu JavaScript.
WebSettings settings = webView.getWebSettings(); settings.setJavascriptEnabled(true);
Taka konfiguracja zwiększa dodatkowo ryzyka związane z atakami typu Cross-Site Scripting.
Platforma Android zapewnia również budowanie mostów łączących kod JavaScript z kodem Java aplikacji mobilnych – JavascriptInterface.
Funkcjonalność ta umożliwia dostęp z poziomu JavaScript do publicznych metod udostępnionego obiektu Javy. Na przełomie 2012 i 2013 zostały publicznie przedstawione sposoby wykorzystania tego mechanizmu do przejęcia kontroli nad aplikację poprzez wykorzystanie mechnizmu refleksji. Przygotowany został również PoC w postaci exploita dostępnego we frameworku Metasploit. Przykład użycia tego modułu: http://resources.infosecinstitute.com/android-hacking-security-part-7-attacks-android-webviews/
https://www.youtube.com/watch?v=gP8EcMUUymw
Użycie interfejsu JavaScript-to-Java dla API<17 (niebezpieczne)
webview.addJavascriptInterface(new JSbridge(), "JSbridge");
class JSbridge {
JSbridge () { }
public String getString() {
return "string";
}
}
Odwołanie w kodzie strony wyglądałoby następująco:
<script> var String = window.bridge.getString(); </script>
Atakujący wykrorzystując mechanizm refleksji może zmusić aplikację do wykonania dowolnego kodu Javy poprzez odwołanie się do obiektu Runtime i wykonanie polecenia systemowego Android lub poprzez odwołanie się do innych klas Android np. SmSManager, co może służyć do wysyłania SMS-ów premium. Podatność oznaczona numerem CVE-2012-6636 i CVE-2013-4710 daje szerokie możliwości wykorzystania przez atakującego.
<script>
cmd = ['/system/bin/sh', '-c', <tu podać dowolne polecenie powłoki Android> ];
window.JSbridge.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
<script>
Teoretycznie, podatność została załatana od wersji Androida 4.2, gdzie każda udostępniona przez JavaScriptInterface metoda musi być jawnie oznaczona za pomocą adnotacji @JavascriptInterface a w pliku manifestu należy wskazać SDK większe niż 16.
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="17"/>
Gdybyśmy zastosowali minSdkVersion mniejszą od 17, aby zapewnić uruchamianie aplikacji na większęj liczbie urządzeń należy liczyć się z tym, że w takim przypadku JavaScriptInterface jest nieaktywny i nie ma możliwości odwołania się do obiektów Javy z poziomu JavaScript.
W celu weryfikacji, czy aplikacja jest podatna na RCE poprzez JavaScriptInterface można użyć narzędzia do analizy aplikacji Android – Drozer. W tym celu należy doinstalować również odatkowy moduł checkjavascriptbridge.
dz> module install javascript Processing jubax.javascript... Done. Successfully installed 1 modules, 0 already installed dz> run scanner.misc.checkjavascriptbridge -a pl.poc.jsi Package: pl.poc.jsi - vulnerable to WebView.addJavascriptInterface + targetSdkVersion=16
Należy jednak pamiętać, że istnieje kilka ukrytych ryzyk związanych z tą podatnością:
@JavascriptInterface
public void sendSMS(String phonenumber, String text){
android.telephony.SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(phonenumber, null, text, null, null);
}
webview.addJavascriptInterface(new SMSbridge(), "SMSbridge");
atakujący poprzez wstrzyknięcie JavaScript
<script> SMSbridge.sendSMS(+123456789,'SMS PREMIUM'); </script>
wykorzysta urządzenie ofiary do wysyłania SMS-ów na podstawione numery.
2. Dostęp do zasobów lokalnych
Domyślnie klasa WebView może odwoływać się i przetwarzać pliki z lokalnych zasobów poprzez schemat file://
webView.loadUrl("file:///data/data/com.good.app");
w przypadku kodu aplikacji, w którym URI pobierany jest z Intencji, czyli jest możliwość wstrzyknięcia przez atakującego Intencji ze zmodyfikowanymi wartościami np.:
String url = getIntent().getStringExtra("URL");
webView.loadUrl(url);
zmodyfikowana Intencja wysłana przez złośliwą aplikację com.malicious.app,a odebrana przez filtr aplikacji com.good.app:
Intent intent = new Intent();
intent.putExtra("URI",“file:///data/data/com.malicious.app/evil.html”);
sendBroadcast(intent);
W pliku evil.html atakujący umieszcza złośliwy kod. Jest to przykład ataku XAS (CAS)- Cross Application Scripting.
Klasa WebSettings zapewnia jeszcze trzy metody, które w przypadku jawnego włączenia mogą zwiększyć skalę tego ataku:
Innym ciekawym przykładem ataku typu XAS jest odkryta podatność we frameworku Apache Cordova (silnie bazuje na WebView) przedstawiona w https://securityintelligence.com/apache-cordova-phonegap-vulnerability-android-banking-apps/
[youtube_sc url=”https://www.youtube.com/watch?v=_V0hPTYa6cg”]
3. Pluginy
WebView ma możliwość uruchomienia pluginów, które mogą zwiększyć powierzchnię ataku lub bezpośrednio przyczynić się do powstania krytycznej luki np. poprzez uruchomienie Flash’a
Domyślnie pluginy są w stanie OFF, a sama metoda setPluginState() została uznana za przestarzałą.
Zabezpieczanie WebView
Zamiast podsumowania, przedstawię szereg zaleceń mających ograniczyć ataki na aplikację mobilną poprzez WebView:
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
private static final String LOG_TAG = "MWRLabs";
Log.d(LOG_TAG, "[x] getHost: " + Uri.parse(url).getHost());
Log.d(LOG_TAG, "[x] getScheme: " + Uri.parse(url).getScheme());
Log.d(LOG_TAG, "[x] getPath: " + Uri.parse(url).getPath());
if (Uri.parse(url).getHost().equals("labs.mwrinfosecurity.com")){return true;}
return false;
}
}
lub poprzez nadpisanie bardziej uniwersalnej metody shouldInterceptRequest() z tej samej klasy. Ta metoda dodatkowo umożliwia przechwytywanie zapytań XmlHttpRequest lub odwołań do zasobów realizowanych poprzez atrybut src ze znaczników HTML.
@Override
public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
if (url.contains(".js")){return getWebResourceResponseFromString();}
else {return super.shouldInterceptRequest(view, url);}
}
Źródła:
Bartosz Jerzman
“Wprowadzenia adnotacji @JavascriptInterface (Android 4.2 API 17) do zablokowania użycia mechanizmu refleksji nie jest w stanie uchronić udostępnionej metody, przed złośliwym użyciem, jeśli została nieostrożnie zaimplementowana” – na czym polega tutaj ta nieostrożność, bo nie zrozumiałem? Z góry dziękuję za wyjaśnienie.
Nieostrożność w tym wypadku została przedstawiona w przykładowym kodzie udostępnionym poniżej tego opisu. Pomimo tego, że wykorzystywane jest API >= 17 i stosowane są adnotacje @JavascriptInterface, które chronią aplikacje przed atakiem z wykorzystaniem refleksji Javy, to jednak adnotacje nie ochronią przed złośliwym użyciem metod obiektów Javy udostępnionych dla JavaScript. W przedstawionym przykładzie deweloper udostępnił metodę sendSMS(), która przyjmuje dwa parametry: numer telefonu i treść wiadomości. Atakujący, który kontroluje ruch sieciowy np. w sieci WiFi, może wykorzystać udostępnione metody np. do wysłania wiadomości SMS na inne numery niż przewidywali twórcy aplikacji poprzez wstrzyknięcie własnych tagów HTML z kodem JavaScript. Jeśli niezbędne jest zastosowanie Java-to-JavaScript Interface, to należy zwrócić szczególną uwagę na to, czy potencjalny atakujący nie jest w stanie użyć udostępnionych metod w inny niż zamierzony sposób. Takie miejsca są często jednymi ze słabych punktów aplikacji i podlegają szczególnym sprawdzeniom.
Nie skumałem tak naprawdę, jak się ma SMSBridge do sendSMS, ale doczytałem to w dokumentacji Androida (zabrakło mi tu może sygnatury klasy na początku wycinka kodu). Ale dodatkowe uwagi również pomagają w zrozumieniu istoty problemu, więc dzięki za wyjaśnienie.
Świetny artykuł. Więcej takich poproszę.
W Lollipop Webview jest w osobnym apie i można go wyłączyć, ale nie wiem czy to dużo daje.