Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The App uses the encryption mode CBC with PKCS5/PKCS7 padding with High Risk - MobSF #132

Open
sed1ka opened this issue Sep 11, 2024 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@sed1ka
Copy link

sed1ka commented Sep 11, 2024

Describe the bug
When my android apps implementing FreeRASP, the Mobile Security Platform (aka MobSF) giving a high risk result with
"The App uses the encryption mode CBC with PKCS5/PKCS7 padding. This configuration is vulnerable to padding oracle attacks."

The MobSF also explaining about their result on this article

The code:

package t;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Build;
import android.security.identity.IdentityCredential;
import android.security.keystore.KeyGenParameterSpec;
import android.util.Log;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
/* loaded from: classes.dex */
abstract class d {
    /* loaded from: classes.dex */
    private static class a {
        static KeyGenParameterSpec a(KeyGenParameterSpec.Builder builder) {
            return builder.build();
        }
        static KeyGenParameterSpec.Builder b(String str, int i10) {
            return new KeyGenParameterSpec.Builder(str, i10);
        }
        static void c(KeyGenerator keyGenerator, KeyGenParameterSpec keyGenParameterSpec) {
            keyGenerator.init(keyGenParameterSpec);
        }
        static void d(KeyGenParameterSpec.Builder builder) {
            builder.setBlockModes("CBC");
        }
        static void e(KeyGenParameterSpec.Builder builder) {
            builder.setEncryptionPaddings("PKCS7Padding");
        }
    }
    /* loaded from: classes.dex */
    private static class b {
        static BiometricPrompt.CryptoObject a(Signature signature) {
            return new BiometricPrompt.CryptoObject(signature);
        }
        static BiometricPrompt.CryptoObject b(Cipher cipher) {
            return new BiometricPrompt.CryptoObject(cipher);
        }
        static BiometricPrompt.CryptoObject c(Mac mac) {
            return new BiometricPrompt.CryptoObject(mac);
        }
    }
    /* loaded from: classes.dex */
    private static class c {
        static BiometricPrompt.CryptoObject a(IdentityCredential identityCredential) {
            return new BiometricPrompt.CryptoObject(identityCredential);
        }
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public static t.c a() {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            KeyGenParameterSpec.Builder b10 = a.b("androidxBiometric", 3);
            a.d(b10);
            a.e(b10);
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "AndroidKeyStore");
            a.c(keyGenerator, a.a(b10));
            keyGenerator.generateKey();
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");    /* The code suspect */
            cipher.init(1, (SecretKey) keyStore.getKey("androidxBiometric", null));
            return new t.c(cipher);
        } catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | KeyStoreException | NoSuchAlgorithmException | NoSuchProviderException | UnrecoverableKeyException | CertificateException | NoSuchPaddingException e10) {
            Log.w("CryptoObjectUtils", "Failed to create fake crypto object.", e10);
            return null;
        }
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public static BiometricPrompt.CryptoObject b(t.c cVar) {
        IdentityCredential b10;
        if (cVar == null) {
            return null;
        }
        Cipher a10 = cVar.a();
        if (a10 != null) {
            return b.b(a10);
        }
        Signature d10 = cVar.d();
        if (d10 != null) {
            return b.a(d10);
        }
        Mac c10 = cVar.c();
        if (c10 != null) {
            return b.c(c10);
        }
        if (Build.VERSION.SDK_INT < 30 || (b10 = cVar.b()) == null) {
            return null;
        }
        return c.a(b10);
    }
}

And I have another high risk issue when implementing with FreeRASP.
The file or SharedPreference is World Writable. Any App can write to the file

The Code:

package n5;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.StrictMode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/* loaded from: classes.dex */
public final class o7 implements r6 {
    /* renamed from: g  reason: collision with root package name */
    private static final Map f11471g = new w.a();
    /* renamed from: a  reason: collision with root package name */
    private final SharedPreferences f11472a;
    /* renamed from: b  reason: collision with root package name */
    private final Runnable f11473b;
    /* renamed from: c  reason: collision with root package name */
    private final SharedPreferences.OnSharedPreferenceChangeListener f11474c;
    /* renamed from: d  reason: collision with root package name */
    private final Object f11475d;
    /* renamed from: e  reason: collision with root package name */
    private volatile Map f11476e;
    /* renamed from: f  reason: collision with root package name */
    private final List f11477f;
    private o7(SharedPreferences sharedPreferences, Runnable runnable) {
        SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { // from class: n5.n7
            @Override // android.content.SharedPreferences.OnSharedPreferenceChangeListener
            public final void onSharedPreferenceChanged(SharedPreferences sharedPreferences2, String str) {
                o7.this.d(sharedPreferences2, str);
            }
        };
        this.f11474c = onSharedPreferenceChangeListener;
        this.f11475d = new Object();
        this.f11477f = new ArrayList();
        this.f11472a = sharedPreferences;
        this.f11473b = runnable;
        sharedPreferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }
    private static SharedPreferences a(Context context, String str) {
        StrictMode.ThreadPolicy allowThreadDiskReads = StrictMode.allowThreadDiskReads();
        try {
            if (str.startsWith("direct_boot:")) {
                if (j6.a()) {
                    context = context.createDeviceProtectedStorageContext();
                }
                return context.getSharedPreferences(str.substring(12), 0);    /* The code suspect */
            }
            return context.getSharedPreferences(str, 0);
        } finally {
            StrictMode.setThreadPolicy(allowThreadDiskReads);
        }
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public static o7 b(Context context, String str, Runnable runnable) {
        o7 o7Var;
        if ((!j6.a() || str.startsWith("direct_boot:")) ? true : j6.c(context)) {
            synchronized (o7.class) {
                Map map = f11471g;
                o7Var = (o7) map.get(str);
                if (o7Var == null) {
                    o7Var = new o7(a(context, str), runnable);
                    map.put(str, o7Var);
                }
            }
            return o7Var;
        }
        return null;
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public static synchronized void c() {
        synchronized (o7.class) {
            for (o7 o7Var : f11471g.values()) {
                o7Var.f11472a.unregisterOnSharedPreferenceChangeListener(o7Var.f11474c);
            }
            f11471g.clear();
        }
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public final /* synthetic */ void d(SharedPreferences sharedPreferences, String str) {
        synchronized (this.f11475d) {
            this.f11476e = null;
            this.f11473b.run();
        }
        synchronized (this) {
            Iterator it = this.f11477f.iterator();
            if (it.hasNext()) {
                c.a.a(it.next());
                throw null;
            }
        }
    }
    @Override // n5.r6
    public final Object f(String str) {
        Map<String, ?> map = this.f11476e;
        if (map == null) {
            synchronized (this.f11475d) {
                map = this.f11476e;
                if (map == null) {
                    StrictMode.ThreadPolicy allowThreadDiskReads = StrictMode.allowThreadDiskReads();
                    Map<String, ?> all = this.f11472a.getAll();
                    this.f11476e = all;
                    StrictMode.setThreadPolicy(allowThreadDiskReads);
                    map = all;
                }
            }
        }
        if (map != null) {
            return map.get(str);
        }
        return null;
    }
}

Please complete the following information:
OS: Android
FreeRASP: 6.6.0
Flutter: 3.24.2

@sed1ka sed1ka added the bug Something isn't working label Sep 11, 2024
@yardexx
Copy link
Member

yardexx commented Sep 16, 2024

Hello.

Thanks for raising the issue. We will take a closer look at it.

Kind regards,
Jaroslav from Talsec Team

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants