Skip to content

MASTG-TEST-0078: Determinando se Métodos Nativos São Expostos por meio de WebViews

Visão Geral

Análise Estática

Testando Pontes JavaScript para Nativo em UIWebView

Procure por códigos que mapeiam objetos nativos para o JSContext associado a um WebView e analise quais funcionalidades são expostas. Por exemplo, nenhum dado sensível deve ser acessível ou exposto para WebViews.

Em Objective-C, o JSContext associado a um UIWebView é obtido da seguinte forma:

[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]

Testando Pontes JavaScript para Nativo em WKWebView

Verifique se existe uma ponte JavaScript para nativo procurando por WKScriptMessageHandler e analise todos os métodos expostos. Em seguida, verifique como os métodos são chamados.

O seguinte exemplo de "Where's My Browser?" demonstra isso.

Primeiro vemos como a ponte JavaScript é habilitada:

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")
    }
}

Adicionar um manipulador de mensagens de script com o nome "name" (ou "javaScriptBridge" no exemplo acima) faz com que a função JavaScript window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage seja definida em todos os frames em todos os web views que usam o controlador de conteúdo do usuário. Ela pode então ser usada a partir do arquivo HTML desta forma:

function invokeNativeOperation() {
    value1 = document.getElementById("value1").value
    value2 = document.getElementById("value2").value
    window.webkit.messageHandlers.javaScriptBridge.postMessage(["multiplyNumbers", value1, value2]);
}

A função chamada reside em JavaScriptBridgeMessageHandler.swift:

class JavaScriptBridgeMessageHandler: NSObject, WKScriptMessageHandler {

//...

case "multiplyNumbers":

        let arg1 = Double(messageArray[1])!
        let arg2 = Double(messageArray[2])!
        result = String(arg1 * arg2)
//...

let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result)')"
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)

O problema aqui é que o JavaScriptBridgeMessageHandler não apenas contém essa função, mas também expõe uma função sensível:

case "getSecret":
        result = "XSRSOGKC342"

Análise Dinâmica

Neste ponto, você certamente identificou todos os WebViews potencialmente interessantes no aplicativo iOS e obteve uma visão geral da superfície de ataque potencial (por meio de análise estática, das técnicas de análise dinâmica que vimos em seções anteriores ou de uma combinação delas). Isso incluiria arquivos HTML e JavaScript, uso do JSContext / JSExport para UIWebView e WKScriptMessageHandler para WKWebView, bem como quais funções são expostas e presentes em um WebView.

Uma análise dinâmica adicional pode ajudá-lo a explorar essas funções e obter dados sensíveis que elas possam estar expondo. Como vimos na análise estática, no exemplo anterior foi trivial obter o valor secreto realizando engenharia reversa (o valor secreto foi encontrado em texto simples dentro do código-fonte), mas imagine que a função exposta recupere o segredo de um armazenamento seguro. Nesse caso, apenas a análise dinâmica e a exploração seriam úteis.

O procedimento para explorar as funções começa com a produção de um payload JavaScript e sua injeção no arquivo que o aplicativo está solicitando. A injeção pode ser realizada por meio de várias técnicas, por exemplo:

  • Se parte do conteúdo for carregada de forma insegura da Internet via HTTP (conteúdo misto), você pode tentar implementar um ataque MITM.
  • Você sempre pode realizar instrumentação dinâmica e injetar o payload JavaScript usando frameworks como Frida e as funções de avaliação JavaScript correspondentes disponíveis para os WebViews do iOS (stringByEvaluatingJavaScriptFromString: para UIWebView e evaluateJavaScript:completionHandler: para WKWebView).

Para obter o segredo do exemplo anterior do aplicativo "Where's My Browser?", você pode usar uma dessas técnicas para injetar o seguinte payload, que revelará o segredo escrevendo-o no campo "result" do WebView:

function javascriptBridgeCallBack(name, value) {
    document.getElementById("result").innerHTML=value;
};
window.webkit.messageHandlers.javaScriptBridge.postMessage(["getSecret"]);

Claro, você também pode usar o Exploitation Helper que ele fornece:

Veja outro exemplo de um aplicativo iOS vulnerável e função exposta para um WebView em [#thiel2] página 156.