20.安卓逆向-frida基础-hook分析调试技巧2-hookDES
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
内容参考于:图灵Python学院
本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。
工具下载:
链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3
提取码:6tw3
复制这段内容后打开百度网盘手机App,操作更方便哦
上一个内容:19.安卓逆向-frida基础-hook分析调试技巧1-hookMD5
上一个内容里使用Frida hook了MD5算法并尝试了对一个app进行使用MD5hook找参数,本次接着继续
本次hook DES算法
下图是DES两种标准实现
package com.example.course1.suanfa;import android.util.Base64;import java.security.spec.AlgorithmParameterSpec;import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec;public class AES {public static String des_1(String args) throws Exception{/*** SecretKeyFactory.getInstance("DES") 获取一个DES* generateSecret初始化DES的加密钥匙,专业术语叫做KEY* 一个des算法需要获取的就死key、iv、明文,有了这些之后就可以对参数模拟加密了*/SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("123456789".getBytes()));/*** new IvParameterSpec("87654321".getBytes()); IV**/AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());/*** Cipher.getInstance("DES/CBC/PKCS5Padding"); 加密模式*/Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");/*** cipher.init(1, secretKey, iv); 初始化,1表示加密**/cipher.init(1, secretKey, iv);/*** cipher.update(args.getBytes()); 把明文放到缓存区准备加密*/cipher.update(args.getBytes());/*** cipher.doFinal() 加密*/return Base64.encodeToString(cipher.doFinal(), 0);}public static String des_2(String args) throws Exception{SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("123456789".getBytes()));AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");cipher.init(1, secretKey, iv);return Base64.encodeToString(cipher.doFinal(args.getBytes()), 0);}}
Frida hook脚本
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; }function main() {Java.perform(function () {var SecretKeyFactory = Java.use("javax.crypto.SecretKeyFactory")SecretKeyFactory.getInstance.overload('java.lang.String').implementation = function(str) {console.log(`算法是----》${str}《------------------------------------------------------------》`)return this.getInstance(str)}// 获取 keyvar DESKeySpec = Java.use("javax.crypto.spec.DESKeySpec")DESKeySpec.$init.overload('[B').implementation = function(str) {console.log(`DESKeySpec.$init.overload--》DES的Key bytesToString:${bytesToString(str)}`)console.log(`DESKeySpec.$init.overload--》DES的key bytesToHexKey:${bytesToHex(str)}`)return this.$init(str)}// 获取 ivvar IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec")IvParameterSpec.$init.overload("[B").implementation = function(str) {console.log(`DES IV bytesToString:${bytesToString(str)}`)console.log(`DES IV bytesToHex:${bytesToHex(str)}`)return this.$init(str)}var Cipher = Java.use("javax.crypto.Cipher")Cipher.getInstance.overload('java.lang.String').implementation = function(str) {console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String'):${str}`)return this.getInstance(str)}Cipher.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function(str1,str2) {console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String', 'java.lang.String') :${str1} || ${str2}`)return this.getInstance(str1, str2)}Cipher.update.overload('[B').implementation = function(str) {console.log(`DES 明文 Cipher.update.overload('[B') bytesToString:${bytesToString(str)}`)return this.update(str)}Cipher.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) {console.log(`DES 明文 Cipher.update.overload('[B', 'int', 'int') :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`)return this.update(str, i1, i2)}Cipher.doFinal.overload('[B').implementation = function(str) {console.log(`des密文入参 Cipher.doFinal.overload('[B') bytesToString:${bytesToString(str)}`)console.log(`des密文入参 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`)var m = this.doFinal(str)console.log(`des密文返回值 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`)console.log(`des密文返回值 Cipher.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`)return m}Cipher.doFinal.overload().implementation = function() {var m = this.doFinal()console.log(`des密文返回值 Cipher.doFinal.overload() bytesToHex:${bytesToHex(m)}`)console.log(`des密文返回值 Cipher.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`)return m}}) }main()
效果图:加密的key
然后是iv,如下图iv的构造方法有两个,如果为了全面可以把两个都给使用Frida hook了(其它的方法也是一样为了全面可以把所有相同名的方法全部hook)
iv效果图,下图的Frida hook脚本里把iv的入参从字节转成了字符串,有的app这个字节的内容它是十六进制数(也就是传过来的也是被加密之后的信息)
获取加密之后的数据
使用DES在线加密网站测试,可以正常根据hook到的key、iv、明文加密成正确的密文