Я новичок в 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, я попытался увидеть, как вызывается нативная функция, поэтому я установил frida-server
на эмуляторе Android, и вот интересный вызов, не знаю, что с этим делать
/* TID 0x10b1 */
15066 ms open(pathname="/data/app/com.friga.gameapp-lPtwMqeZ36x47-Yo8YDzOg==/lib/x86/libnative-lib.so", flags=0x0)
Полагаю, это ключ? -lPtwMqeZ36x47-Yo8YDzOg==