关于爬虫:升级版加密HOOK盲狙

4次阅读

共计 6771 个字符,预计需要花费 17 分钟才能阅读完成。

import frida  # 导入 frida 模块
import sys  # 导入 sys 模块

jscode = """
function showStacks() {Java.perform(function() {send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
    });
}

function bytesToHex(arr) {
    var str = "";
    for (var i = 0; i < arr.length; i++) {var tmp = arr[i];
        if (tmp < 0) {tmp = (255 + tmp + 1).toString(16);
        } else {tmp = tmp.toString(16);
        }
        if (tmp.length == 1) {tmp = "0" + tmp;}
        str += tmp;
    }
    return str;
}
function bytesToBase64(e) {
    var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    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 bytesToString(arr) {if (typeof arr === 'string') {return arr;}
    var str = '',
    _arr = arr;
    for (var i = 0; i < _arr.length; i++) {var one = _arr[i].toString(2),
        v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {var bytesLength = v[0].length;
            var store = _arr[i].toString(2).slice(7 - bytesLength);
            for (var st = 1; st < bytesLength; st++) {store += _arr[st + i].toString(2).slice(2);
            }
            str += String.fromCharCode(parseInt(store, 2));
            i += bytesLength - 1;
        } else {str += String.fromCharCode(_arr[i]);
        }
    }
    return str;
}

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);
        send("======================================");
        send("算法名:" + b + "|Dec 密钥:" + bytesToString(a));
        send("算法名:" + b + "|Hex 密钥:" + bytesToHex(a));
        return result;
    }
    
    var mac = Java.use('javax.crypto.Mac');
    mac.getInstance.overload('java.lang.String').implementation = function (a) {showStacks();
        var result = this.getInstance(a);
        send("======================================");
        send("算法名:" + a);
        return result;
    }
    mac.update.overload('[B').implementation = function (a) {showStacks();
        this.update(a);
        send("======================================");
        send("update:" + bytesToString(a))
    }
    mac.update.overload('[B','int','int').implementation = function (a,b,c) {showStacks();
        this.update(a,b,c)
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
    }
    mac.doFinal.overload().implementation = function () {showStacks();
        var result = this.doFinal();
        send("======================================");
        send("doFinal 后果 (hex):" + bytesToHex(result));
        send("doFinal 后果 (base64):" + bytesToBase64(result));
        return result;
    }
    mac.doFinal.overload('[B').implementation = function (a) {showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal 参数:" + bytesToString(a));
        send("doFinal 后果 (hex):" + bytesToHex(result));
        send("doFinal 后果 (base):" + 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();
        send("======================================");
        send("算法名:" + a);
        return this.getInstance(a, b);
    }
    md.getInstance.overload('java.lang.String').implementation = function (a) {showStacks();
        send("======================================");
        send("算法名:" + a);
        return this.getInstance(a);
    }
    md.update.overload('[B').implementation = function (a) {showStacks();
        send("======================================");
        send("update_md5_01:" + bytesToString(a))
        return this.update(a);
    }
    md.update.overload('[B','int','int').implementation = function (a,b,c) {showStacks();
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
        return this.update(a,b,c);
    }
    md.digest.overload().implementation = function () {showStacks();
        send("======================================");
        var result = this.digest();
        send("digest 后果 (hex)_1:" + bytesToHex(result));
        send("digest 后果 (base64)_1:" + bytesToBase64(result));
        return result;
    }
    md.digest.overload('[B').implementation = function (a) {showStacks();
        send("======================================");
        send("a:"+a);
        send("digest 参数:" + bytesToString(a));
        var result = this.digest(a);
        send("result:" + result);
        send("digest 后果 (hex)_2:" + bytesToHex(result));
        send("digest 后果 (base64)_2:" + 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);
        send("======================================");
        send("iv 向量:" + bytesToString(a));
        send("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);
        send("======================================");
        send("模式填充:" + a);
        return result;
    }
    cipher.update.overload('[B').implementation = function (a) {showStacks();
        var result = this.update(a);
        send("======================================");
        send("update:" + bytesToString(a));
        return result;
    }
    cipher.update.overload('[B','int','int').implementation = function (a,b,c) {showStacks();
        var result = this.update(a,b,c);
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
        return result;
    }
    cipher.doFinal.overload().implementation = function () {showStacks();
        var result = this.doFinal();
        send("======================================");
        send("doFinal 后果 (hex):" + bytesToHex(result));
        send("doFinal 后果 (base64):" + bytesToBase64(result));
        return result;
    }
    cipher.doFinal.overload('[B').implementation = function (a) {showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal 参数:" + bytesToString(a));
        send("doFinal 后果 (hex):" + bytesToHex(result));
        send("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);
        send("======================================");
        send("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);
        send("======================================");
        //send("RSA 密钥:" + bytesToBase64(a));
        send("RSA 密钥 N:" + a.toString(16));
        send("RSA 密钥 E:" + b.toString(16));
        return result;
    }
});
"""


def on_message(message, data):  # js 中执行 send 函数后要回调的函数
    if message["type"] == "send":
        print("[*] {0}".format(message["payload"]))
    else:
        print(message)


fv = frida.get_usb_device(-1)
front_app = fv.get_frontmost_application()  # 获取在前台运行的 APP 这样就不须要每次去改
print("=== 正在运行的利用为:", front_app)
process = fv.attach(front_app.pid)
# frida 版本 15 之后 这里传过程名或者过程 id
script = process.create_script(jscode)
script.on('message',on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()
正文完
 0