腾讯做网站,上海网站建设 推荐站霸网络,wordpress安装 用户名已存在哪里,有没有返利网站做京东的前言#xff1a; ♛ frida hook android Android 逆向神器 前几天在学习 Android 逆向的时候发现了一个神器#xff1a;通过 frida hook 我们可以 “劫持” 一些函数 为我们所用#xff0c; 今天就和大家上手一个 加密函数的劫持 让打印出#xff1a; 加密秘钥 …前言 ♛ frida hook android Android 逆向神器 前几天在学习 Android 逆向的时候发现了一个神器通过 frida hook 我们可以 “劫持” 一些函数 为我们所用 今天就和大家上手一个 加密函数的劫持 让打印出 加密秘钥 密文 效果如下可以很直观的看出 加密算法以及秘钥 准备工作 安装运行环境(因为我这里都装过来 你们自己对照着来) python 环境 C:\Users\Administratorpython --version
Python 3.10.6 frida C:\Users\Administratorpip install frida
Requirement already satisfied: frida in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (16.1.3)
Requirement already satisfied: typing-extensions in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida) (4.7.1)[notice] A new release of pip available: 22.2.1 - 23.2.1
[notice] To update, run: python.exe -m pip install --upgrade pipC:\Users\Administratorfrida
usage: frida [options] target
frida: error: target must be specified firda-tools C:\Users\Administratorpip install frida-tools
Requirement already satisfied: frida-tools in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (12.2.1)
Requirement already satisfied: prompt-toolkit4.0.0,2.0.0 in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida-tools) (3.0.39)
Requirement already satisfied: colorama1.0.0,0.2.7 in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida-tools) (0.4.6)
Requirement already satisfied: pygments3.0.0,2.0.2 in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida-tools) (2.15.1)
Requirement already satisfied: frida17.0.0,16.0.9 in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida-tools) (16.1.3)
Requirement already satisfied: typing-extensions in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from frida17.0.0,16.0.9-frida-tools) (4.7.1)
Requirement already satisfied: wcwidth in c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages (from prompt-toolkit4.0.0,2.0.0-frida-tools) (0.2.6)[notice] A new release of pip available: 22.2.1 - 23.2.1
[notice] To update, run: python.exe -m pip install --upgrade pip 下载一个 frida server Releases · frida/frida · GitHub 下载地址 https://github.com/frida/frida/releases 因为 我用的是模拟器所有下载这个版本,可以使用 命令查看对于的类型 C:\Users\Administratoradb shell getprop ro.product.cpu.abi
x86_64 adb C:\Users\Administratoradb devices
List of devices attached
emulator-5558 device 实操上手 ⒈建立注入环境运行 frida server 不要关闭 把刚刚下载的 解压发送到 手机 /data/local/ 目录下 我这里重命名为 f86(应为一些加壳软件会监测是否使用 frifa) 执行 f86, 记得要给权限chmod 777 f86 C:\Users\Administratoradb shell
star2qltechn:/ $ su
star2qltechn:/ # cd /data/lcoal
/system/bin/sh: cd: /data/lcoal: No such file or directory
2|star2qltechn:/ # cd /data/local
star2qltechn:/data/local # ls
cfg-zeiag f86 file-cache temp-zeiag tmp traces
star2qltechn:/data/local # chmod 777 f86
star2qltechn:/data/local # su
star2qltechn:/data/local # ./f86 2 建立端口转发 一共两个端口 不要关闭 adb forward tcp:27043 tcp:27043adb forward tcp:27042 tcp:27042 C:\Users\Administratoradb forward tcp:27043 tcp:27043
27043C:\Users\Administratoradb forward tcp:27042 tcp:27042
27042 3 运行我们的 hook.js 代码 不要关闭 frida -U -F -l C:\Users\Administrator\Desktop\py\hook.js -U 指的的我们的 USB设备-F 指的是我们最手机 最上层运行的APP-l 指定我们脚本路径 运行这App的时候 跑起来我们的脚本 4 奇迹就发生了 hook.js 脚本 var N_ENCRYPT_MODE 1
var N_DECRYPT_MODE 2function 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\n);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;) {dor base64DecodeChars[255 e.charCodeAt(o)];while (o t r -1);if (r -1)break;doa 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|\n/g, ).replace(/([\da-fA-F]{2}) ?/g, 0x$1 ).replace(/ $/, ).split( )));
}
function base64ToHex(str) {for (var i 0, bin base64Decode(str.replace(/[ \r\n]$/, )), 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);elseval 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;) {dor base64DecodeChars[255 e.charCodeAt(o)];while (o t r -1);if (r -1)break;doa 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 bytesToStringJava.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结果: |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结果: bytesToHex(result));console.log(digest结果: bytesToBase64(result));return result;}md.digest.overload([B).implementation function (a) {//showStacks();console.log();console.log(digest参数: bytesToString(a));var result this.digest(a);console.log(digest结果: bytesToHex(result));console.log(digest结果: 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.update(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结果: |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 hook 的原理 是直接劫持java加密函数 不需要去逆向代码直接 效率很高 对于使用 java 原生开发的应用 效率很高 但是相对于 flutter 开发的应用效果就比较差了 后面抽空研究研究 fiida 在 flutter 身上的新姿势