Frida Tutorial 2

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert Red Team AWS de HackTricks)!

Astuce de prime de bug: inscrivez-vous à Intigriti, une plateforme de prime de bug premium créée par des pirates informatiques, pour des pirates informatiques**! Rejoignez-nous sur https://go.intigriti.com/hacktricks aujourd'hui, et commencez à gagner des primes allant jusqu'à 100 000 $!

Ceci est un résumé du post: https://11x256.github.io/Frida-hooking-android-part-2/ (Parties 2, 3 & 4) APKs et code source: https://github.com/11x256/frida-android-examples

La partie 1 est très facile.

Certaines parties du code original ne fonctionnent pas et ont été modifiées ici.

Partie 2

Ici, vous pouvez voir un exemple de comment accrocher 2 fonctions avec le même nom mais avec des paramètres différents. De plus, vous allez apprendre comment appeler une fonction avec vos propres paramètres. Enfin, il y a un exemple de comment trouver une instance d'une classe et la faire appeler une fonction.

//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 () { }
});
});

Vous pouvez voir que pour créer une chaîne de caractères, il a d'abord fait référence à la classe java.lang.String puis a créé un nouvel objet $new de cette classe avec une chaîne de caractères comme contenu. C'est la manière correcte de créer un nouvel objet d'une classe. Cependant, dans ce cas, vous pourriez simplement passer à this.fun() n'importe quelle chaîne de caractères comme ceci : this.fun("salut !")

Python

//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

Partie 3

Python

Maintenant, vous allez voir comment envoyer des commandes à l'application accrochée via Python pour appeler la fonction:

//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()

La commande "1" va quitter, la commande "2" va trouver une instance de la classe et appeler la fonction privée secret() et la commande "3" va accrocher la fonction secret() pour qu'elle retourne une chaîne différente.

Ainsi, si vous appelez "2", vous obtiendrez le vrai secret, mais si vous appelez d'abord "3" puis "2", vous obtiendrez le faux secret.

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
};

Partie 4

Ici, vous verrez comment faire interagir Python et JS en utilisant des objets JSON. JS utilise la fonction send() pour envoyer des données au client Python, et Python utilise les fonctions post() pour envoyer des données au script JS. Le JS bloquera l'exécution jusqu'à ce qu'il reçoive une réponse de Python.

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

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

Il y a une partie 5 que je ne vais pas expliquer car il n'y a rien de nouveau. Mais si vous voulez le lire, c'est ici : https://11x256.github.io/Frida-hooking-android-part-5/

Conseil de prime de bug : inscrivez-vous à Intigriti, une plateforme de prime de bug premium créée par des hackers, pour des hackers ! Rejoignez-nous sur https://go.intigriti.com/hacktricks aujourd'hui, et commencez à gagner des primes allant jusqu'à 100 000 $ !

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Dernière mise à jour