hacktricks/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md
2023-06-06 18:56:34 +00:00

14 KiB

Tutorial Frida 2

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Se você está interessado em carreira de hacking e hackear o impossível - estamos contratando! (fluência em polonês escrito e falado é necessária).

{% embed url="https://www.stmcyber.com/careers" %}

De: https://11x256.github.io/Frida-hooking-android-part-2/ (Partes 2, 3 e 4)
APKs e código-fonte: https://github.com/11x256/frida-android-examples

A parte 1 é muito fácil.

Algumas partes do código original não funcionam e foram modificadas aqui.

Parte 2

Aqui você pode ver um exemplo de como interceptar 2 funções com o mesmo nome, mas com parâmetros diferentes.
Além disso, você vai aprender como chamar uma função com seus próprios parâmetros.
E, finalmente, há um exemplo de como encontrar uma instância de uma classe e fazê-la chamar uma função.

//s2.js
console.log("Script loaded successfully ");
Java.perform(function x() {
    console.log("Inside java perform function");
    var my_class = Java.use("com.example.a11x256.frida_test.my_activity");
    //Hook "fun" with parameters (int, int)
    my_class.fun.overload("int", "int").implementation = function (x, y) { //hooking the old function
        console.log("original call: fun(" + x + ", " + y + ")");
        var ret_value = this.fun(2, 5);
        return ret_value;
    };
    //Hook "fun" with paramater(String)
    var string_class = Java.use("java.lang.String");
    my_class.fun.overload("java.lang.String").implementation = function (x) { //hooking the new function
        console.log("*")
        //Create a new String and call the function with your input.
        var my_string = string_class.$new("My TeSt String#####");
        console.log("Original arg: " + x);
        var ret = this.fun(my_string);
        console.log("Return value: " + ret);
        console.log("*")
        return ret;
    };
    //Find an instance of the class and call "secret" function.
    Java.choose("com.example.a11x256.frida_test.my_activity", {
        onMatch: function (instance) {
            console.log(tring, and the it has"Found instance: " + instance);
            console.log("Result of secret func: " + instance.secret());
        },
        onComplete: function () { }
    });
});

Você pode ver que para criar uma String primeiro foi referenciada a classe java.lang.String e depois foi criado um objeto $new dessa classe com uma String como conteúdo. Esta é a maneira correta de criar um novo objeto de uma classe. Mas, neste caso, você poderia simplesmente passar para this.fun() qualquer String como: this.fun("olá!")

//loader.py
import frida
import time

device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1) #Without it Java.perform silently fails
session = device.attach(pid)
script = session.create_script(open("s2.js").read())
script.load()

#prevent the python script from terminating
raw_input()
python loader.py

Parte 3

Python

Agora você vai aprender como enviar comandos para o aplicativo conectado via Python para chamar funções:

//loader.py
import time
import frida

def my_message_handler(message, payload):
    print message
    print payload


device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1)  # Without it Java.perform silently fails
session = device.attach(pid)
with open("s3.js") as f:
    script = session.create_script(f.read())
script.on("message", my_message_handler)
script.load()

command = ""
while 1 == 1:
    command = raw_input("Enter command:\n1: Exit\n2: Call secret function\n3: Hook Secret\nchoice:")
    if command == "1":
        break
    elif command == "2":
        script.exports.callsecretfunction()
    elif command == "3":
        script.exports.hooksecretfunction()

O comando "1" irá sair, o comando "2" irá encontrar e instanciar a classe e chamar a função privada secret() e o comando "3" irá interceptar a função secret() para que ela retorne uma string diferente.

Então, se você chamar "2", você obterá o segredo real, mas se você chamar "3" e depois "2", você obterá o segredo falso.

JS

console.log("Script loaded successfully ");
var instances_array = [];
function callSecretFun() {
    Java.perform(function () {
        if (instances_array.length == 0) { // if array is empty
            Java.choose("com.example.a11x256.frida_test.my_activity", {
                onMatch: function (instance) {
                    console.log("Found instance: " + instance);
                    instances_array.push(instance)
                    console.log("Result of secret func: " + instance.secret());
                },
                onComplete: function () { }

            });
        }
        else {//else if the array has some values
            console.log("Result of secret func: " + instances_array[0].secret());
        }

    });
}

function hookSecret() {
    Java.perform(function () {
        var my_class = Java.use("com.example.a11x256.frida_test.my_activity");
        var string_class = Java.use("java.lang.String");
        my_class.secret.overload().implementation = function(){
            var my_string = string_class.$new("TE ENGANNNNEEE");
            return my_string;
        }
    });
}
rpc.exports = {
    callsecretfunction: callSecretFun,
    hooksecretfunction: hookSecret
};

Parte 4

Aqui você verá como fazer a interação entre Python e JS usando objetos JSON. O JS usa a função send() para enviar dados para o cliente Python, e o Python usa a função post() para enviar dados para o script JS. O JS bloqueará a execução até receber uma resposta do Python.

//loader.py
import time
import frida

def my_message_handler(message, payload):
    print message
    print payload
    if message["type"] == "send":
        print message["payload"]
        data = message["payload"].split(":")[1].strip()
        print 'message:', message
        data = data.decode("base64")
        user, pw = data.split(":")
        data = ("admin" + ":" + pw).encode("base64")
        print "encoded data:", data
        script.post({"my_data": data})  # send JSON object
        print "Modified data sent"


device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("s4.js") as f:
    script = session.create_script(f.read())
script.on("message", my_message_handler)  # register the message handler
script.load()
raw_input()

JS

Introdução

O JavaScript (JS) é uma linguagem de programação interpretada, de alto nível e orientada a objetos. É amplamente utilizada para criar páginas web interativas e dinâmicas, mas também pode ser usada em outras áreas, como desenvolvimento de jogos, aplicativos de desktop e até mesmo em servidores.

O JS é executado no lado do cliente, o que significa que é executado no navegador do usuário. Isso permite que os desenvolvedores criem páginas web interativas e dinâmicas que respondem às ações do usuário em tempo real.

Injeção de código JS com Frida

O Frida é uma ferramenta poderosa para injetar código em aplicativos em execução. Isso pode ser usado para modificar o comportamento do aplicativo, interceptar chamadas de API e muito mais.

Para injetar código JS em um aplicativo Android usando o Frida, primeiro precisamos criar um script JS que será injetado. O script JS pode ser usado para modificar o comportamento do aplicativo, interceptar chamadas de API e muito mais.

Aqui está um exemplo de um script JS simples que exibe uma mensagem de alerta quando o aplicativo é iniciado:

Java.perform(function() {
  console.log('Hello, world!');
  var MainActivity = Java.use('com.example.app.MainActivity');
  MainActivity.onCreate.implementation = function() {
    console.log('onCreate()');
    this.onCreate();
    alert('Hello, world!');
  };
});

Este script injetará um código JS no método onCreate() da classe MainActivity do aplicativo. Quando o método onCreate() é chamado, o script exibirá uma mensagem de alerta com o texto "Hello, world!".

Para injetar o script JS em um aplicativo Android em execução, primeiro precisamos iniciar o aplicativo e obter seu processo ID. Isso pode ser feito usando o comando frida-ps -U.

$ frida-ps -U
 PID  Name
----  ----
 123  com.example.app

Neste exemplo, o processo ID do aplicativo é 123. Agora podemos injetar o script JS no aplicativo usando o comando frida -U -p <PID> -l <script.js>.

$ frida -U -p 123 -l script.js

Isso injetará o script JS no aplicativo e exibirá a mensagem de alerta quando o aplicativo é iniciado.

Conclusão

O JavaScript é uma linguagem de programação poderosa que pode ser usada para injetar código em aplicativos Android usando o Frida. Isso pode ser usado para modificar o comportamento do aplicativo, interceptar chamadas de API e muito mais.

console.log("Script loaded successfully ");
Java.perform(function () {
    var tv_class = Java.use("android.widget.TextView");
    tv_class.setText.overload('java.lang.CharSequence').implementation = function (x) {
        var string_to_send = x.toString();
        var string_to_recv = "";
        send(string_to_send); // send data to python code
        recv(function (received_json_object) {
            string_to_recv = received_json_object.my_data;
        }).wait(); //block execution till the message is received
        console.log("Final string_to_recv: "+ string_to_recv)
        return this.setText(string_to_recv);
    }
});

Existe uma parte 5 que não vou explicar porque não há nada de novo. Mas se você quiser ler, está aqui: https://11x256.github.io/Frida-hooking-android-part-5/

Se você está interessado em carreira de hacking e hackear o inquebrável - estamos contratando! (fluência em polonês escrita e falada é necessária).

{% embed url="https://www.stmcyber.com/careers" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥