我通常是Android和Java的新手,我想检查特定应用程序的工作原理,因此我首先使用apktool
对应用程序进行反编译,然后使用jadx
浏览源代码文件,到目前为止一切都有意义,因此我添加了mitmproxy
来检查应用程序的网络流量。
我知道请求回复是JSON负载,但是可能使用mcrypt
或openssl
加密了其中的一些?因此跟踪方法将我引导至该文件。
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MC {
private IvParameterSpec a;
private SecretKeySpec b;
private Cipher c;
private native int getint();
public native String I6MOYF();
static {
System.loadLibrary("native-lib");
}
public MC(String str) {
this.a = new IvParameterSpec(str.getBytes());
this.b = new SecretKeySpec((I6MOYF() + String.valueOf(getint())).getBytes(), "AES");
try {
this.c = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
}
}
public byte[] encrypt(String str) throws Exception {
if (str == null || str.length() == 0) {
throw new Exception("Empty string");
}
try {
this.c.init(1, this.b, this.a);
return this.c.doFinal(a(str).getBytes());
} catch (Exception e) {
throw new Exception("[encrypt] " + e.getMessage());
}
}
private static String a(String str) {
int length = 16 - (str.length() % 16);
for (int i = 0; i < length; i++) {
str = str + 0;
}
return str;
}
public byte[] des(String str) throws Exception {
if (str == null || str.length() == 0) {
throw new Exception("Empty string");
}
try {
this.c.init(2, this.b, this.a);
Object doFinal = this.c.doFinal(hexToBytes(str));
if (doFinal.length > 0) {
int i = 0;
for (int length = doFinal.length - 1; length >= 0; length--) {
if (doFinal[length] == (byte) 0) {
i++;
}
}
if (i > 0) {
Object obj = new byte[(doFinal.length - i)];
System.arraycopy(doFinal, 0, obj, 0, doFinal.length - i);
return obj;
}
}
return doFinal;
} catch (Exception e) {
throw new Exception("[decrypt] " + e.getMessage());
}
}
public static byte[] hexToBytes(String str) {
byte[] bArr = null;
if (str != null && str.length() >= 2) {
int length = str.length() / 2;
bArr = new byte[length];
for (int i = 0; i < length; i++) {
bArr[i] = (byte) Integer.parseInt(str.substring(i * 2, (i * 2) + 2), 16);
}
}
return bArr;
}
}
我了解它使用OpenSSL“ AES / CBC / NoPadding”模式解密有效负载,但是我不知如何获取有效负载并手动进行操作。
这是服务器提供的有效负载的示例,应用程序发送密钥头,但是更改和删除它不会更改有效负载,因此我得出结论,它并未使用用于实际加密的密钥
AwFpdchYa7twLSEwN884uGQ/CNoLKrGBxtwIXGcL9OQTPPh96I1uhuh85HXLw3XUikVCmKaKgnssGorqYuvHQELce3nAhnaeHDcEsMFIykeitgDWLXeCed6f9UXHn+XF8nC3arHVbhMgIW8bUlWMq6KygRb4jeUufRHJzJ7LK0q6TvY+rF+utv3i//3NCuKfmbiiMlBvyDdMWPIL83YywkdjLujbBn0RNaeqUDjE0I7xqYypWPjwPXH1DZPbnGFYHemJgNS8QKtFnbtiRwEhpzx2sEoe/NBIgvcXsYkRSgrt+Q==
主要问题是,您将如何使用提供的代码手动解密有效载荷?
编辑:
如@Robert先生所建议,我试图查看如何调用本机函数,因此我在Android模拟器上安装了frida-server
,这是一个有趣的调用,不确定该怎么做>
/* TID 0x10b1 */
15066 ms open(pathname="/data/app/com.friga.gameapp-lPtwMqeZ36x47-Yo8YDzOg==/lib/x86/libnative-lib.so", flags=0x0)
我猜这应该是关键吗? -lPtwMqeZ36x47-Yo8YDzOg==
答案 0 :(得分:0)
我通过遵循11x256博客的“ Frida hooking android part 5: Bypassing AES encryption”帖子,成功地使用frida
解决了问题