TripleSec
static {
System.loadLibrary("fubar");
}
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
// Register methods with env->RegisterNatives.
return JNI_VERSION_1_6;
}
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
ImageViewer.java
public class ImageViewer extends AppCompatActivity {
LinearLayout imageList;
static {
System.loadLibrary("secure");
}
private native byte[] loadSecureResource(String var1);
@Override
protected void onCreate(Bundle bitmap) {
// [...]
for (int i = 0; i < 5; ++i) {
bitmap = this.loadSecureResource("cat00" + Integer.toString(i) + ".jpg.enc");
// [...]
}
}
}
Unlock.java - Part 1
public class Unlock extends AppCompatActivity {
//[...]
@Override
protected void onCreate(Bundle bundle) {
// [...]
this.checkButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View object) {
object = Unlock.this.serialText.getText().toString();
if (Unlock.this.checkSerial((String)object, Unlock.this.did)) {
// [...]
Unlock.this.launchImageViewer();
}
}
});
}
}
Unlock.java - Part 2
static {
System.loadLibrary("secure");
}
private native boolean checkSerial(String var1, String var2);
[panda@bamboo cat_images]$ unzip cat_image_enterprise_edition.apk
Archive: cat_image_enterprise_edition.apk
inflating: AndroidManifest.xml
inflating: META-INF/CERT.RSA
inflating: META-INF/CERT.SF
inflating: META-INF/MANIFEST.MF
extracting: assets/cat000.jpg.enc
[...]
[panda@bamboo cat_images]$ ls -la lib/armeabi-v7a/
total 16
drwxr-xr-x 2 panda panda 60 Oct 27 20:03 .
drwxr-xr-x 5 panda panda 100 Oct 27 20:03 ..
-rw-r--r-- 1 panda panda 13776 Dec 31 1979 libsecure.so
[panda@bamboo cat_images]$ file lib/armeabi-v7a/libsecure.so
lib/armeabi-v7a/libsecure.so: ELF 32-bit LSB shared object, ARM [...] stripped
When checkSerial is called, the registers hold the following values:
[panda@bamboo armeabi-v7a]$ readelf -d ./libsecure.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libandroid.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
[panda@bamboo armeabi-v7a]$ ls -la
total 14172
drwxr-xr-x 2 panda panda 80 Oct 28 00:07 .
drwxr-xr-x 5 panda panda 100 Oct 27 20:03 ..
-rw-r--r-- 1 panda panda 14493092 Oct 23 05:45 libgadget.so
-rw-r--r-- 1 panda panda 13776 Dec 31 1979 libsecure.so
[panda@bamboo armeabi-v7a]$ ipython
Python 3.7.0 (default, Sep 15 2018, 19:13:07)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import lief
...:
...: libnative = lief.parse("libsecure.so")
...: libnative.add_library("libgadget.so") # Injection!
...: libnative.write("libsecure.so")
[panda@bamboo armeabi-v7a]$ readelf -d ./libsecure.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libgadget.so] <--- \o/
0x00000001 (NEEDED) Shared library: [libandroid.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
{
"interaction": {
"type": "script",
"path": "/data/local/tmp/myscript.js",
"on_change": "reload"
}
}
keytool -genkey -v -keystore debug.keystore -alias \
key -storepass android -keypass android -keyalg RSA -validity 14000
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
-keystore debug.keystore cat_images.apk key
[panda@bamboo tmp]$ adb install ./cat_images.apk
./cat_images.apk: 1 file pushed. 6.6 MB/s (11900035 bytes in 1.714s)
pkg: /data/local/tmp/cat_images.apk
Success
'use strict';
Java.perform(function () {
Interceptor.attach(Module.findBaseAddress("libsecure.so").add(0x3131), {
onEnter: function(args) {
Log.v("keycat", "+-----------------------------------------------------------------------+");
Log.v("keycat", "Entering Java_eu_haxelion_CatImageEnterpriseEdition_Unlock_checkSerial");
Log.v("keycat", "args[0] = " + args[0].toString());
Log.v("keycat", "args[1] = " + args[1].toString());
Log.v("keycat", "args[2] = " + Memory.readCString(Memory.readPointer(args[2])));
Log.v("keycat", "args[2] = " + Memory.readCString(Memory.readPointer(args[3])));
Log.v("keycat", "+-----------------------------------------------------------------------+");
}
}
)
});
adb logcat -s "keycat:V"
V/keycat (14878): +-----------------------------------------------------------------------------+
V/keycat (14878): Entering Java_eu_haxelion_CatImageEnterpriseEdition_Unlock_checkSerial
V/keycat (14878): args[0] = 0xb4871240
V/keycat (14878): args[1] = 0xbedc3eec
V/keycat (14878): args[2] = �wp
V/keycat (14878): args[2] = �wp
V/keycat (14878): +-----------------------------------------------------------------------------+
V/keycat (14975): +-----------------------------------------------------------------------------+
V/keycat (14975): Entering sub_10ac
V/keycat (14975): args[0] = abcdef0987654321 <---- serial
V/keycat (14975):
V/keycat (14975): Leaving sub_10ac
V/keycat (14975): args[1] = 0xab, 0xcd, 0xef, 0x9, 0x87, 0x65, 0x43, 0x21,
V/keycat (14975): +-----------------------------------------------------------------------------+
V/keycat (14975): +-----------------------------------------------------------------------------+
V/keycat (14975): Entering sub_10ac
V/keycat (14975): args[0] = b927f9baf693d02f <---- device id
V/keycat (14975):
V/keycat (14975): Leaving sub_10ac
V/keycat (14975): args[1] = 0xb9, 0x27, 0xf9, 0xba, 0xf6, 0x93, 0xd0, 0x2f,
V/keycat (14975): +-----------------------------------------------------------------------------+
R1 = 0x42
first_stage = b''
for i in range(8):
R1 = serial[i] + (device_id[i] ^ R1)
R1 = R1 & 0xff
first_stage += bytes([R1])
key2 = b'HAXELION'
for i in range(0x15):
LR = key[i]
R4 = i % 0x8
R5 = key2[R4]
R6 = first_stage[R4]
key2[R4] = LR
R6 = (LR + (R5 ^ R6)) & 0xff
key[i] = R6
[panda@bamboo jni]$ python keygen.py --id b927f9baf693d02f
[+] Expected first stage value: 8e6f50cce87737bf
[+] Expected serial: 93c6bae2aefc90a7