hacktricks/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md
2024-02-11 01:46:25 +00:00

12 KiB

Samouczek Fridy 2

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Jeśli interesuje Cię kariera hakerska i hakowanie niemożliwych do zhakowania rzeczy - zatrudniamy! (wymagane biegłe posługiwanie się językiem polskim w mowie i piśmie).

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

To jest streszczenie posta: https://11x256.github.io/Frida-hooking-android-part-2/ (Części 2, 3 i 4)
APK i kod źródłowy: https://github.com/11x256/frida-android-examples

Część 1 jest bardzo prosta.

Niektóre części oryginalnego kodu nie działają i zostały zmodyfikowane tutaj.

Część 2

Tutaj możesz zobaczyć przykład, jak hakować 2 funkcje o tej samej nazwie, ale z różnymi parametrami.
Dowiedziesz się również, jak wywołać funkcję z własnymi parametrami.
Na koniec jest przykład, jak znaleźć instancję klasy i sprawić, aby wywołała funkcję.

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

Możesz zauważyć, że aby utworzyć String, najpierw odwołuje się do klasy java.lang.String, a następnie tworzy obiekt $new tej klasy z zawartością jako String. To jest poprawny sposób tworzenia nowego obiektu klasy. Jednak w tym przypadku możesz po prostu przekazać do this.fun() dowolny String, na przykład: this.fun("hej!")

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

Część 3

Python

Teraz zobaczysz, jak wysyłać polecenia do podłączonej aplikacji za pomocą Pythona, aby wywołać funkcję:

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

Polecenie "1" zakończy działanie, polecenie "2" znajdzie i wywoła instancję klasy oraz wywoła prywatną funkcję secret(), a polecenie "3" przechwyci funkcję secret() tak, aby zwracała innego stringa.

Jeśli wywołasz polecenie "2", otrzymasz prawdziwy sekret, ale jeśli wywołasz najpierw polecenie "3", a następnie "2", otrzymasz fałszywy sekret.

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

Część 4

Tutaj zobaczysz, jak sprawić, aby Python i JS współdziałały za pomocą obiektów JSON. JS używa funkcji send() do wysyłania danych do klienta Pythona, a Python używa funkcji post() do wysyłania danych do skryptu JS. JS zablokuje wykonanie do momentu otrzymania odpowiedzi od Pythona.

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

JavaScript (JS) jest językiem programowania, który jest często używany do tworzenia interaktywnych stron internetowych. Jest również szeroko stosowany w aplikacjach mobilnych, w tym w systemie Android. W kontekście pentestingu aplikacji Android, znajomość JS może być przydatna do analizy i manipulacji kodu JavaScript w aplikacji.

Frida to narzędzie, które umożliwia dynamiczną analizę i manipulację aplikacjami mobilnymi. Może być używane do pentestingu aplikacji Android, a także do innych celów, takich jak reverse engineering i debugowanie.

W przypadku pentestingu aplikacji Android, Frida może być używana do wstrzykiwania kodu JavaScript w aplikację, co umożliwia monitorowanie i manipulację jej działaniem. Może być również używana do analizy i manipulacji danych przesyłanych między aplikacją a serwerem.

Aby rozpocząć korzystanie z Fridy, należy zainstalować narzędzie na urządzeniu mobilnym lub emulatorze Android. Następnie można użyć Fridy w połączeniu z narzędziami takimi jak adb (Android Debug Bridge) lub frida-server, aby nawiązać połączenie z aplikacją i rozpocząć analizę.

Po nawiązaniu połączenia z aplikacją, można użyć Fridy do wstrzykiwania kodu JavaScript w aplikację. Ten kod może być używany do monitorowania i manipulacji różnych aspektów działania aplikacji, takich jak wywoływanie funkcji, zmiana wartości zmiennych i przechwytywanie danych.

Frida oferuje również wiele funkcji, które ułatwiają analizę aplikacji, takie jak dostęp do obiektów i funkcji aplikacji, monitorowanie wywołań funkcji, przechwytywanie danych sieciowych i wiele innych.

Ważne jest, aby pamiętać, że korzystanie z Fridy do pentestingu aplikacji Android wymaga odpowiednich uprawnień i zrozumienia zasad legalności. Należy zawsze działać zgodnie z obowiązującymi przepisami i uzyskać odpowiednie zezwolenia przed rozpoczęciem pentestingu.

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

Istnieje część 5, której nie zamierzam wyjaśniać, ponieważ nie ma w niej nic nowego. Ale jeśli chcesz przeczytać, jest tutaj: https://11x256.github.io/Frida-hooking-android-part-5/

Jeśli interesuje Cię kariera hakera i hakowanie niemożliwych do zhakowania rzeczy - zatrudniamy! (wymagane biegłe posługiwanie się językiem polskim w mowie i piśmie).

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

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!