有影
试着做了 2W班试题11. 完成对APP的算法分析2. 实现注册机,对任意用户名可以生成对应的密钥,并验证通过import javax.crypto.BadPaddingExcept ...
2W班试题2:
1. 刚刚开始分析由于我自己的 redmi note 7 pro (Android 10) 运行出错,用了静态分析,Java层面算法答案是:“i-hate-r0ysue”。反向代码如下。
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decrypt {
public static byte[] su = {-66, -81, 25, -66, 122, -8, 42, -10, 78, -117, 104, -17, 118, -27, 40, -80, -20, 40, -60, -80, -11, -5, 75, 5, 100, 47, -48, 42, -119, -60, -66, 113};
public static void main(String[] args) {
int[] passwordArr = decrypt(su);
String password = decryptPassword(passwordArr);
System.out.println(password);
}
public static String decryptPassword(int[] passwordArr) {
String ming1 = Integer.toString(passwordArr[0], 16);
String ming2 = Integer.toString(passwordArr[1], 16);
String ming3 = Integer.toString(passwordArr[2], 16);
String ming4 = Integer.toString(passwordArr[3], 16);
String mingwen = ming1 + ming2 + ming3 + ming4;
return hex2String(mingwen);
}
public static int[] decrypt(byte[] byteContent) {
String password = "r0ysue-yyds";
while (password.length() < 16) {
password += "0";
}
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] result = cipher.doFinal(byteContent);
String content = new String(result);
int[] arr = new int[4];
arr[0] = Integer.parseInt(content.substring(0, 8),16);
arr[1] = Integer.parseInt(content.substring(8, 16),16);
arr[2] = Integer.parseInt(content.substring(16, 24),16);
arr[3] = Integer.parseInt(content.substring(24, 26),16);
return arr;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static String hex2String(String hexString) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < hexString.length(); i+=2) {
sb.append((char) Integer.parseInt(hexString.substring(i, i + 2), 16));
}
return sb.toString();
}
}
2. 后来借了朋友的Nexus 5X(Android 8.1)成功运行后,才发现是错误的。
3. 之后查看了 libnative-lib.so 反编译后的代码,才发现public int encrypt(int a, int b, int c, int d) 被 ART JNI 替换了。
4. 真正的加密函数是在sub_272C和sub_2128上,sub_2128函数反编译的代码和一些常量数组看着像 DES 加密。
对于sub_2128函数破解(DES加密,也有可能不是),我目前的能力有限。还无法破解。望大佬给个破解思路。
楼下8楼已经给出思路,再次谢谢大佬。
------------------------------------------------------------------------------------------------------------------------------------------
5. 先上 Frida Hook 观察sub_272C和sub_2128调用。
/// <reference path="frida-gum.d.ts" />
function hook_java() {
Java.perform(function () {
const mainActivity = Java.use("com.r0ysue.test.MainActivity");
mainActivity.string2hex.implementation = function (string) {
string = "abceefghijkln";
console.log("called string2hex - ", string)
var result = this.string2hex(string);
console.log("return - ", result);
return result
}
})
}
function hook_native() {
var libnative_lib_addr = Module.getBaseAddress("libnative-lib.so")
var sub_2128_fun_addr = libnative_lib_addr.add(0x2128)
var sub_272C_fun_addr = libnative_lib_addr.add(0x272C)
Interceptor.attach(sub_2128_fun_addr, {
onEnter: function (args) {
console.log("called sub_2128 ", args[0])
},
onLeave: function (retval) {
console.log("sub_2128 retval ", retval);
// retval.replace(1)
}
})
Interceptor.attach(sub_272C_fun_addr, {
onEnter: function (args) {
console.log("called sub_272C ", args[2], args[3], args[4], args[5]);
},
onLeave: function (retval) {
console.log("sub_272C retval ", retval)
// retval.replace(1)
}
})
}
setTimeout(hook_native, 1000)
setImmediate(hook_java)
// frida -U -f com.r0ysue.test -l hook.js --no-pause
确认了 sub_2128 返回1是成功。
6. 根据8楼给出的DES代码(https://github.com/dhuertas/DES/blob/master/des.c),尝试在frida和DES的程序中输入一些值,确认是DES加密算法了。
frida
des.c
7. 使用 des.c里的解密算法完成解密。
8. hex to string 。
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decrypt2 {
public static void main(String[] args) {
System.out.println(
hex2String("692d6c6f") +
hex2String("76652d72") +
hex2String("30797375") +
hex2String("65")
); // i-love-r0ysue
}
public static String hex2String(String hexString) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < hexString.length(); i += 2) {
sb.append((char) Integer.parseInt(hexString.substring(i, i + 2), 16));
}
return sb.toString();
}
}
最后于 2021-11-17 19:37
被有影编辑
,原因: