一个脚本让你的app自动吐出密钥信息

VSole2021-08-09 17:57:22

背景

火线某个私密项目中涉及到一个app的测试,打开一看,证书校验--不让抓包,信息加密-无法篡改,遇到这种情况怎么,正常我这种小菜鸡都是直接放弃了,奈何厂家奖金给的高啊,我还是得想办法搞一搞,虽然到最后低危都没有捡到一个,但是还是分享给没有做过app的大佬参考一下。

一、 frida安装

01 Frida概述

Frida是一款轻量级HOOK框架,可用于多平台上,例如android、windows、ios等。

frida分为两部分,服务端运行在目标机上,通过注入进程的方式来实现劫持应用函数,另一部分运行在系统机器上。

frida上层接口支持js、python、c等。

Frida官方github地址为:

https://github.com/frida

02 Frida安装

1 、安装python3.7并配置好环境变量(官方推荐python3以上版本至少为3.7),python安装包官方下载地址:

https://www.python.org/downloads/

2 、安装frida模块,命令为pip install frida(配置了多个python版本环境的可以使用命令python -m pip install frida防止用pip install frida命令报错)。

3、安装frida-tools模块,命令同上,pip install frida-tools或者python -m pip install frida-tools。

4、下载运行在目标机上的frida-sever端

官方下载地址:https://github.com/frida/frida/releases后面可以跟版本14.2.2

下载时要选择对应的版本下载,例如我的机器为arm32为架构,就选择frida-server-14.2.2-android-arm.xz下载。(可以在adb使用命令cat /proc/cpuinfo查询)

5、将第四步下载好的文件解压,然后通过命令adb push 你的电脑是存放位置 /data/local/tmp将文件传输到手机中,然后通过adb shell进入手机端,给文件赋权777,并于root权限启动。

6、做完以上几步后,新开一个命令行输入命令frida-ps -U查看手机进程,如果出现以下结果,则frida安装成功。

可以看到进程了

二、使用Frida脚本绕过抓包限制

设置burp证书

先在burp里设置本机代理

访问代理地址并下载burp证书

将下载的burp证书导入到手机中/data/local/tmp目录下,并重命名为cert-der.crt(此名称在接下来的fridascript.js脚本中使用,如果该名字命名为其他则脚本中相对应的地方也需要进行替换)

adb push cacert.der /data/local/tmp/cert-der.crt

模拟器设置代理,在安卓手机设置->wlan选择对应网络设置代理

打开你想抓包的软件,使用frida-ps -U命令列出设备上运行的服务,找到对应的包名

在本地新建一个js文件,并将一下内容写入

/*    Android SSL Re-pinning frida script v0.2 030417-pier 
   $ adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt   $ frida -U -f it.app.mobile -l frida-android-repinning.js --no-pause
   https://techblog.mediaservice.net/2017/07/universal-android-ssl-pinning-bypass-with-frida/      UPDATE 20191605: Fixed undeclared var. Thanks to @oleavr and @ehsanpc9999 !*/
setTimeout(function(){    Java.perform(function (){      console.log("");      console.log("[.] Cert Pinning Bypass/Re-Pinning");
      var CertificateFactory = Java.use("java.security.cert.CertificateFactory");      var FileInputStream = Java.use("java.io.FileInputStream");      var BufferedInputStream = Java.use("java.io.BufferedInputStream");      var X509Certificate = Java.use("java.security.cert.X509Certificate");      var KeyStore = Java.use("java.security.KeyStore");      var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");      var SSLContext = Java.use("javax.net.ssl.SSLContext");
      // Load CAs from an InputStream      console.log("[+] Loading our CA...")      var cf = CertificateFactory.getInstance("X.509");            try {        var fileInputStream = FileInputStream.$new("/data/local/tmp/cert-der.crt");      }      catch(err) {        console.log("[o] " + err);      }            var bufferedInputStream = BufferedInputStream.$new(fileInputStream);      var ca = cf.generateCertificate(bufferedInputStream);      bufferedInputStream.close();
    var certInfo = Java.cast(ca, X509Certificate);      console.log("[o] Our CA Info: " + certInfo.getSubjectDN());
      // Create a KeyStore containing our trusted CAs      console.log("[+] Creating a KeyStore for our CA...");      var keyStoreType = KeyStore.getDefaultType();      var keyStore = KeyStore.getInstance(keyStoreType);      keyStore.load(null, null);      keyStore.setCertificateEntry("ca", ca);            // Create a TrustManager that trusts the CAs in our KeyStore      console.log("[+] Creating a TrustManager that trusts the CA in our KeyStore...");      var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();      var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);      tmf.init(keyStore);      console.log("[+] Our TrustManager is ready...");
      console.log("[+] Hijacking SSLContext methods now...")      console.log("[-] Waiting for the app to invoke SSLContext.init()...")
       SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation = function(a,b,c) {         console.log("[o] App invoked javax.net.ssl.SSLContext.init...");         SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").call(this, a, tmf.getTrustManagers(), c);         console.log("[+] SSLContext initialized with our custom TrustManager!");       }    });},0);

脚本里的30行其中对应的就是burp证书的信息

将fridascript.js注入到目标应用程序中

frida -U -f com.xxxx.app.ui -l C:\Users\xxx\Desktop\fridascript.js --no-pause

-f选项表示强制启动一个应用程序,-l选项表示加载指定脚本,–no-pause选项表示不中断应用程序的启动,如下所示代表运行成功

咱们可以看到,已经能抓到包了

但是包的内容进行了加密

三、使用Frida脚本让他自己吐出密钥信息

还需要再本地建一个新的js文件,代码如下:

var N_ENCRYPT_MODE = 1var N_DECRYPT_MODE = 2
function showStacks() {    var Exception = Java.use("java.lang.Exception");    var ins = Exception.$new("Exception");    var straces = ins.getStackTrace();
    if (undefined == straces || null == straces) {        return;    }
    console.log("============================= Stack strat=======================");    console.log("");
    for (var i = 0; i < straces.length; i++) {        var str = "   " + straces[i].toString();        console.log(str);    }
    console.log("");    console.log("============================= Stack end=======================\r");    Exception.$dispose();}
//工具相关函数 var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',    base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1));
function stringToBase64(e) {    var r, a, c, h, o, t;    for (c = e.length, a = 0, r = ''; a < c;) {        if (h = 255 & e.charCodeAt(a++), a == c) {            r += base64EncodeChars.charAt(h >> 2),                r += base64EncodeChars.charAt((3 & h) << 4),                r += '==';            break        }        if (o = e.charCodeAt(a++), a == c) {            r += base64EncodeChars.charAt(h >> 2),                r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),                r += base64EncodeChars.charAt((15 & o) << 2),                r += '=';            break        }        t = e.charCodeAt(a++),            r += base64EncodeChars.charAt(h >> 2),            r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),            r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),            r += base64EncodeChars.charAt(63 & t)    }    return r}function base64ToString(e) {    var r, a, c, h, o, t, d;    for (t = e.length, o = 0, d = ''; o < t;) {        do            r = base64DecodeChars[255 & e.charCodeAt(o++)];        while (o < t && r == -1);        if (r == -1)            break;        do            a = base64DecodeChars[255 & e.charCodeAt(o++)];        while (o < t && a == -1);        if (a == -1)            break;        d += String.fromCharCode(r << 2 | (48 & a) >> 4);        do {            if (c = 255 & e.charCodeAt(o++), 61 == c)                return d;            c = base64DecodeChars[c]        } while (o < t && c == -1);        if (c == -1)            break;        d += String.fromCharCode((15 & a) << 4 | (60 & c) >> 2);        do {            if (h = 255 & e.charCodeAt(o++), 61 == h)                return d;            h = base64DecodeChars[h]        } while (o < t && h == -1);        if (h == -1)            break;        d += String.fromCharCode((3 & c) << 6 | h)    }    return d}function hexToBase64(str) {    return base64Encode(String.fromCharCode.apply(null, str.replace(/\r|/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));}function base64ToHex(str) {    for (var i = 0, bin = base64Decode(str.replace(/[ \r]+$/, "")), hex = []; i < bin.length; ++i) {        var tmp = bin.charCodeAt(i).toString(16);        if (tmp.length === 1)            tmp = "0" + tmp;        hex[hex.length] = tmp;    }    return hex.join("");}function hexToBytes(str) {    var pos = 0;    var len = str.length;    if (len % 2 != 0) {        return null;    }    len /= 2;    var hexA = new Array();    for (var i = 0; i < len; i++) {        var s = str.substr(pos, 2);        var v = parseInt(s, 16);        hexA.push(v);        pos += 2;    }    return hexA;}function bytesToHex(arr) {    var str = '';    var k, j;    for (var i = 0; i < arr.length; i++) {        k = arr[i];        j = k;        if (k < 0) {            j = k + 256;        }        if (j < 16) {            str += "0";        }        str += j.toString(16);    }    return str;}function stringToHex(str) {    var val = "";    for (var i = 0; i < str.length; i++) {        if (val == "")            val = str.charCodeAt(i).toString(16);        else            val += str.charCodeAt(i).toString(16);    }    return val}function stringToBytes(str) {    var ch, st, re = [];    for (var i = 0; i < str.length; i++) {        ch = str.charCodeAt(i);        st = [];        do {            st.push(ch & 0xFF);            ch = ch >> 8;        }        while (ch);        re = re.concat(st.reverse());    }    return re;}//将byte[]转成String的方法function bytesToString(arr) {    var str = '';    arr = new Uint8Array(arr);    for (var i in arr) {        str += String.fromCharCode(arr[i]);    }    return str;}function bytesToBase64(e) {    var r, a, c, h, o, t;    for (c = e.length, a = 0, r = ''; a < c;) {        if (h = 255 & e[a++], a == c) {            r += base64EncodeChars.charAt(h >> 2),                r += base64EncodeChars.charAt((3 & h) << 4),                r += '==';            break        }        if (o = e[a++], a == c) {            r += base64EncodeChars.charAt(h >> 2),                r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),                r += base64EncodeChars.charAt((15 & o) << 2),                r += '=';            break        }        t = e[a++],            r += base64EncodeChars.charAt(h >> 2),            r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),            r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),            r += base64EncodeChars.charAt(63 & t)    }    return r}function base64ToBytes(e) {    var r, a, c, h, o, t, d;    for (t = e.length, o = 0, d = []; o < t;) {        do            r = base64DecodeChars[255 & e.charCodeAt(o++)];        while (o < t && r == -1);        if (r == -1)            break;        do            a = base64DecodeChars[255 & e.charCodeAt(o++)];        while (o < t && a == -1);        if (a == -1)            break;        d.push(r << 2 | (48 & a) >> 4);        do {            if (c = 255 & e.charCodeAt(o++), 61 == c)                return d;            c = base64DecodeChars[c]        } while (o < t && c == -1);        if (c == -1)            break;        d.push((15 & a) << 4 | (60 & c) >> 2);        do {            if (h = 255 & e.charCodeAt(o++), 61 == h)                return d;            h = base64DecodeChars[h]        } while (o < t && h == -1);        if (h == -1)            break;        d.push((3 & c) << 6 | h)    }    return d}//stringToBase64 stringToHex stringToBytes//base64ToString base64ToHex base64ToBytes//               hexToBase64  hexToBytes    // bytesToBase64 bytesToHex bytesToString

Java.perform(function () {    var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');    secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) {        showStacks();        var result = this.$init(a, b);        console.log("======================================");        console.log("算法名:" + b + "|str密钥:" + bytesToString(a));        console.log("算法名:" + b + "|Hex密钥:" + bytesToHex(a));        return result;    }
    var DESKeySpec = Java.use('javax.crypto.spec.DESKeySpec');    DESKeySpec.$init.overload('[B').implementation = function (a) {        showStacks();        var result = this.$init(a);        console.log("======================================");        var bytes_key_des = this.getKey();        console.log("des密钥  |str " + bytesToString(bytes_key_des));        console.log("des密钥  |hex " + bytesToHex(bytes_key_des));        return result;    }
    DESKeySpec.$init.overload('[B', 'int').implementation = function (a, b) {        showStacks();        var result = this.$init(a, b);        console.log("======================================");        var bytes_key_des = this.getKey();        console.log("des密钥  |str " + bytesToString(bytes_key_des));        console.log("des密钥  |hex " + bytesToHex(bytes_key_des));        return result;    }
    var mac = Java.use('javax.crypto.Mac');    mac.getInstance.overload('java.lang.String').implementation = function (a) {        showStacks();        var result = this.getInstance(a);        console.log("======================================");        console.log("算法名:" + a);        return result;    }    mac.update.overload('[B').implementation = function (a) {        //showStacks();        this.update(a);        console.log("======================================");        console.log("update:" + bytesToString(a))    }    mac.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {        //showStacks();        this.update(a, b, c)        console.log("======================================");        console.log("update:" + bytesToString(a) + "|" + b + "|" + c);    }    mac.doFinal.overload().implementation = function () {        //showStacks();        var result = this.doFinal();        console.log("======================================");        console.log("doFinal结果: |str  :"     + bytesToString(result));        console.log("doFinal结果: |hex  :"     + bytesToHex(result));        console.log("doFinal结果: |base64  :"  + bytesToBase64(result));        return result;    }    mac.doFinal.overload('[B').implementation = function (a) {        //showStacks();        var result = this.doFinal(a);        console.log("======================================");        console.log("doFinal参数: |str  :"     + bytesToString(a));        console.log("doFinal参数: |hex  :"     + bytesToHex(a));        console.log("doFinal结果: |str  :"     + bytesToString(result));        console.log("doFinal结果: |hex  :"     + bytesToHex(result));        console.log("doFinal结果: |base64  :"  + bytesToBase64(result));        return result;    }
    var md = Java.use('java.security.MessageDigest');    md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {        //showStacks();        console.log("======================================");        console.log("算法名:" + a);        return this.getInstance(a, b);    }    md.getInstance.overload('java.lang.String').implementation = function (a) {        //showStacks();        console.log("======================================");        console.log("算法名:" + a);        return this.getInstance(a);    }    md.update.overload('[B').implementation = function (a) {        //showStacks();        console.log("======================================");        console.log("update:" + bytesToString(a))        return this.update(a);    }    md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {        //showStacks();        console.log("======================================");        console.log("update:" + bytesToString(a) + "|" + b + "|" + c);        return this.update(a, b, c);    }    md.digest.overload().implementation = function () {        //showStacks();        console.log("======================================");        var result = this.digest();        console.log("digest结果 |hex:" + bytesToHex(result));        console.log("digest结果 |base64:" + bytesToBase64(result));        return result;    }    md.digest.overload('[B').implementation = function (a) {        //showStacks();        console.log("======================================");        console.log("digest参数 |str:" + bytesToString(a));        console.log("digest参数 |hex:" + bytesToHex(a));        var result = this.digest(a);        console.log("digest结果: |hex" + bytesToHex(result));        console.log("digest结果: |base64" + bytesToBase64(result));        return result;    }
    var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');    ivParameterSpec.$init.overload('[B').implementation = function (a) {        //showStacks();        var result = this.$init(a);        console.log("======================================");        console.log("iv向量: |str:" + bytesToString(a));        console.log("iv向量: |hex:" + bytesToHex(a));        return result;    }
    var cipher = Java.use('javax.crypto.Cipher');    cipher.getInstance.overload('java.lang.String').implementation = function (a) {        //showStacks();        var result = this.getInstance(a);        console.log("======================================");        console.log("模式填充:" + a);        return result;    }    cipher.init.overload('int', 'java.security.Key').implementation = function (a, b) {        //showStacks();        var result = this.init(a, b);        console.log("======================================");        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
        var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));        return result;    }    cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (a, b) {        //showStacks();        var result = this.init(a, b);        console.log("======================================");                if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
        return result;    }    cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (a, b, c) {        //showStacks();        var result = this.init(a, b, c);        console.log("======================================");                if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }             var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
        return result;    }    cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (a, b, c) {        //showStacks();        var result = this.init(a, b, c);        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }        return result;    }    cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (a, b, c) {        //showStacks();        var result = this.init(a, b, c);        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
         var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));        return result;    }    cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (a, b, c) {        //showStacks();        var result = this.init(a, b, c);        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
        var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));        return result;    }    cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (a, b, c, d) {        //showStacks();        var result = this.init(a, b, c, d);        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
        var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));        return result;    }    cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (a, b, c, d) {        //showStacks();        var result = this.init(a, b, c, d);        if (N_ENCRYPT_MODE == a)         {            console.log("init  | 加密模式");            }        else if(N_DECRYPT_MODE == a)        {            console.log("init  | 解密模式");            }
         var bytes_key = b.getEncoded();        console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));        console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));        return result;    }
    cipher.update.overload('[B').implementation = function (a) {        //showStacks();        var result = this.update(a);        console.log("======================================");        console.log("update:" + bytesToString(a));        return result;    }    cipher.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {        //showStacks();        var result = this.update(a, b, c);        console.log("======================================");        console.log("update:" + bytesToString(a) + "|" + b + "|" + c);        return result;    }    cipher.doFinal.overload().implementation = function () {        //showStacks();        var result = this.doFinal();        console.log("======================================");        console.log("doFinal结果: |str  :"     + bytesToString(result));        console.log("doFinal结果: |hex  :"     + bytesToHex(result));        console.log("doFinal结果: |base64  :"  + bytesToBase64(result));        return result;    }    cipher.doFinal.overload('[B').implementation = function (a) {        //showStacks();        var result = this.doFinal(a);        console.log("======================================");        console.log("doFinal参数: |str  :"     + bytesToString(a));        console.log("doFinal参数: |hex  :"     + bytesToHex(a));        console.log("doFinal结果: |str  :"     + bytesToString(result));        console.log("doFinal结果: |hex  :"     + bytesToHex(result));        console.log("doFinal结果: |base64  :"  + bytesToBase64(result));        return result;    }
    var x509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec');    x509EncodedKeySpec.$init.overload('[B').implementation = function (a) {        //showStacks();        var result = this.$init(a);        console.log("======================================");        console.log("RSA密钥:" + bytesToBase64(a));        return result;    }
    var rSAPublicKeySpec = Java.use('java.security.spec.RSAPublicKeySpec');    rSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (a, b) {        //showStacks();        var result = this.$init(a, b);        console.log("======================================");        //console.log("RSA密钥:" + bytesToBase64(a));        console.log("RSA密钥N:" + a.toString(16));        console.log("RSA密钥E:" + b.toString(16));        return result;    }
    var KeyPairGenerator = Java.use('java.security.KeyPairGenerator');    KeyPairGenerator.generateKeyPair.implementation = function ()     {        //showStacks();        var result = this.generateKeyPair();        console.log("======================================");                var str_private = result.getPrivate().getEncoded();        var str_public = result.getPublic().getEncoded();        console.log("公钥  |hex" + bytesToHex(str_public));        console.log("私钥  |hex" + bytesToHex(str_private));
        return result;    }
    KeyPairGenerator.genKeyPair.implementation = function ()     {        //showStacks();        var result = this.genKeyPair();        console.log("======================================");
        var str_private = result.getPrivate().getEncoded();        var str_public = result.getPublic().getEncoded();        console.log("公钥  |hex" + bytesToHex(str_public));        console.log("私钥  |hex" + bytesToHex(str_private));
        return result;    }});

在新建一个窗口

frida -U -f com.xxxx.app.ui -l C:\Users\xxx\Desktop\333.js --no-pause

如上图所示,已经在开始自动解密了

密钥信息已经出来啦,只需要到网上找对应的脚本进行解密就可以了。

des算法var
本作品采用《CC 协议》,转载必须注明作者和本文链接
frida复现某app算法
2023-01-11 10:44:51
获取数据某app的登录界面抓包,发现参数都加密了查验一下壳,未加壳,可以进行反编译使用jadx进行反编译,尝试搜索一下参数名”Encrypt”,发现两个JsonRequest类的方法存在运用frida及其下面的代码在java层进行hook,发现只调用了addRequestMap方法Java.perform(function (){. 跟进addRequestMap方法,了解其使用des加密,hook该方法可获取明文及加密结果hook代码Java.perform(function () {
APP协议分析心得
2023-07-18 09:23:41
对脱壳流程有不明白的可参考我之前写的文章:[原创]ART环境下dex加载流程分析及frida dump dex方案。var magic_Hex = [0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00];var dex_path = "/data/data/" + apk_Name + "/" + dex_size + ".dex";
RDP凭证本机RDP密码抓取本机RDP密码是一个我们常遇到的场景,通常使用mimikatz抓取RDP密码。当系统为win10或2012R2以上时,默认在内存缓存中禁止保存明文密码,这时抓取的明文密码为空。上不了线的情况下,也可以在webshell中来dump内存,保存到本地解密即可。
这个样本是在2019年5月中使用的一个powershell样本。背景Turla,也被称为 Snake,是一个
定位把整个apk拖入jadx-gui后,初始化检索之后可以直接通过网址进行定位。!看到此处,它判断的这3个URL接口名称,恰是支付的,估计是它排除掉不是它的接口。结果就是,该HOOK代码并没有触发,也就是并没有执行到此处,但是我们发现当前class处几乎每个函数都是加密相关,我对他们进行了逐一HOOK,最终发现encypt函数有了反应。
首先使用jadx对apk进行逆向。?搜索关键字 QDSign,可以直接找到对应的类,可以看到参数经过加密得到。??进一步跟踪,发现了c类中有如下三个so方法,还有3个loadlibrary,分别进行了hook,发现c-lib动态注册了sign,sos动态注册了s,没有发现crypto有动态注册。
可通过在控制台开启SSH服务进入Linux系统。关键字disabled可用于禁止给定类型的密码,无论其长度如何。N2:用于密码短语,除了满足此长度要求之外,密码短语还必须包含足够数量的单词。N3、N4用于由三个和四个字符类的字符组成的密码。⑥ enforce=none|users|everyone可以使用该模块配置警告仅限密码,但实际上不强制使用强密码。users代表除root账户。用disable_firstupper_lastdigit_check 禁止了这种识别。所以VMware ESXI 默认口令复杂度配置大致是这个规则。
火线某个私密项目中涉及到一个app的测试,打开一看,证书校验--不让抓包,信息加密-无法篡改,遇到这种情况怎么,正常我这种小菜鸡都是直接放弃了,奈何厂家奖金给的高啊,我还是得想办法搞一搞,虽然到最后低危都没有捡到一个,但是还是分享给没有做过app的大佬参考一下。
firefox批量get password
2022-08-23 15:56:55
firefox批量get password
WEB安全梳理-操作系统
2022-08-10 07:16:03
WEB安全梳理-操作系统
VSole
网络安全专家