Análisis de un algoritmo de firma de firma de aplicaciones de comercio electrónico (6)

1. Metas

El parámetro de entrada de sign está encriptado, pero tiene dos características obvias, una es el final de == y la otra es el comienzo de R4iSK .

Con estas dos características, podemos empezar.

rc1.png

Dos pasos

Comience con Base64

== Lo más probable es que los datos al final sean Base64, conectémoslos primero

// Base64
var Base64Class = Java.use("android.util.Base64");
Base64Class.encodeToString.overload("[B", "int").implementation = function(a,b){
    var rc =  this.encodeToString(a,b);        
    console.log(">>> Base64 " + rc);
    return rc;
}

correr

rc2.png

Resultó estar allí, pero no es lo que queríamos, así que guardémoslo por ahora, tal vez se use en el futuro.

Coincide con el comienzo de R4iSK

Estamos muy familiarizados con esta rutina.

// 靠字符串去定位
var strCls = Java.use("java.lang.StringBuilder");
strCls.toString.implementation = function(){
    var result = this.toString();

    if(result.toString().indexOf("R4iSK") == 0 && result.toString().length < 200)
    {
        console.log(result.toString());

        var stack = threadinstance.currentThread().getStackTrace();
        console.log("Rc Full call stack:" + Where(stack));

    }
    return result;
}

carrera feliz

rc3.png

Lo atrapé esta vez, aunque el nombre de clase de este CrashReport es un poco extraño

Función de manejo de gancho

var OperCls = Java.use("com.jxxxxong.sdk.xxcrashreport.a.a.a");
OperCls.a.overload('[B').implementation = function(a){
        var result = this.a(a);

        var StrCls = Java.use('java.lang.String');
        var inStr = StrCls.$new(a);

        console.log(inStr + " >>> " + result);

        return result;
}

El parámetro de entrada es un byte[], y el valor devuelto es algo que se parece a Base64 pero probablemente no sea Base64

Hay dos opciones para imprimir byte[], una es convertirla directamente en una cadena hexadecimal y escribirla, y la otra es apostar a que en realidad es una cadena, convertirla directamente en una cadena e imprimirla. Intentemos convertirlo a String primero

 >>> R4iSKKKKKKKKKBC0CtGnLKMgYWz/LGKKKK==

El resultado impreso es así, el parámetro de entrada no se imprime, lo que indica que el parámetro de entrada no es un simple String.getBytes().

Retroceder en la pila

Seguimos rastreando la pila, buscando la función init de ao ,

sub1.png

Se encontró que el byte[] ingresado como parámetro ha experimentado el bautismo de la función xxcrashreport.aaab .

Haga clic y verá que resultó ser una compresión zip. No digas nada, primero engancha la función b

OperCls.b.implementation = function(a){
        var StrCls = Java.use('java.lang.String');
        var inStr = StrCls.$new(a);

        console.log(inStr + " >>> ");

        var result = this.b(a);			
        return result;
}

Ejecutalo de nuevo, y el resultado sale.

{"msg":[{"appId":"fba8ae5a5078417d90ae1355af234d4f","clientVersion":"10.3.2","buildCode":"92141","appArch":"32"}]} >>> 
 >>> R4iSKKKKKKKKKK3Ckm6NCKyP4XpntPMcsmTiVIdoeOlPYBLNS1PK0O4e747X79c5P3zFQbh3LbJlFUCRaaIQTPKmipOYkJUu6OAqZT1xx6MMacwy/v5yxRvbdYAwdhXVCF7zmi+DHbQ16PPDpn/R9PPnPifGbirJeG9yKKKK

Llámalo un día ~ Hace demasiado frío, por lo que no serviremos cerveza fresca, sino Erguotou.

3. Resumen

El String original llama a getBytes() una vez y luego lo convierte a byte[], luego llama a la función b para hacer una compresión zip y finalmente llama a la función a para realizar una modificación mágica de la operación Base64.

El único defecto de la aplicación esta vez es que el comienzo del texto cifrado permanece sin cambios, por lo que intentamos asegurarnos de que el resultado sea diferente cada vez que se cifra, y el texto cifrado debe ser irregular.

ffshow.png

Señor es la raíz, la raíz se establece y nace el Tao

Supongo que te gusta

Origin blog.csdn.net/fenfei331/article/details/122486548
Recomendado
Clasificación