Parte 4
- Hemos terminado con pew, ahora es el turno de usar crypt:
1 | frida-boot:~/code$ cp ../software/crypt.c . |
- Correremos crypt para ver como funciona:
1 | ./crypt |
Supongamos que no tenemos el código fuente de crypt, procederemos analizarlo con:
Reporte de análisis de crypt:
- La condición correcta printeará Pwnd!!
- test_pin debería devolver true (0x1) será satisfactoria.
- test_pin testea el valor 0xd64.
(usando la herramienta cutter)
Vamos a hacer un análisis dinámico de test_pin.
- Usaremos interceptor.attach() en test_pin.
- ¿Cuáles son los valores de los argumentos y de return?
1
2
3
4
5
6
7
8
9
10var testPin = DebugSymbol.getFunctionByName("test_pin");
Interceptor.attach(testPin, {
onEnter: function(args) {
console.log("test_pin(" + args[0] + ")");
},
onLeave: function(retval) {
console.log(" => ret: " + retval);
}
});Vamos ha hacer un hexdump de la dirección del primer argumento
1 | onEnter: function(args){ |
1 | test_pin(0x7ffd83bf4952) |
- Podemos printear el string también:
1 | onEnter: function(args) { |
¿Por tanto, es una situación sencilla?
◇ Cambiamos el valor a 0x1.
◇ Podría usarse retval.replace(ptr(“0x1”));
Como se puede observar lo que he hecho ha sido cambiar el valor de retorno de la función test_pin, de tal forma que si meto cualquier número en este caso 123, pues el programa concluya por el flujo true!!.
Esto está genial porque hemos cambiado el brach del programa, pero ¿Cuál es el verdadero pin?
- ¿Y su pudiesemos llamar a test_pin() por nosotros mismos?, sabríamos el argumento y el tipo de retorno.
- Otra nueva API de frida, reconstruye el comportamiento de la función:
1
new NativeFunction(address, returnType, argTypes[, abi]);
(Nos arroja 0 debido a que hemos testeado “1111“ y este número no es un pin válido).
Por lo tanto, vamos a hacer un loop para hacer fuerza bruta al ping
1
2
3
4
5
6
7
8
9
10
11
12var testPinPtr = DebugSymbol.getFunctionByName("test_pin");
var testPin = new NativeFunction(testPinPtr, "int", ["pointer"]); //Reconstruye la funcion
for(var i = 0; i <= 9999; i++){
console.log("Trying: " + i.toString());
var pin = Memory.allocUtf8String(i.toString());
var r = testPin(pin);
if(r == 1){
console.log("Pin is: " + i.toString());
break;
}
}
Hecho!!!, tenemos el pin.