Is proguard enough to pass penetration testing?

2020-05-09 22:36发布

For our android mobile app , we have to choose an obfuscation tool so that our app will pass penetration test cases. Is Proguard enough for the same or we should use Dexguard?

2条回答
看我几分像从前
2楼-- · 2020-05-09 22:47

ProGuard is a generic optimizer for Java bytecode. DexGuard is a specialized tool for the protection of Android applications.

ProGuard offers basic protection against static analysis. DexGuard protects applications against static and dynamic analysis.

ProGuard provides minimal obfuscation. DexGuard applies multiple layers of encryption and obfuscation.

ProGuard focuses on the bytecode. DexGuard processes all the components of an application.

Source: DexGuard vs. ProGuard

查看更多
我只想做你的唯一
3楼-- · 2020-05-09 22:51

Obfuscation is NOT enough to pass a penetration test

A proper penetration test will analyze both static and runtime behavior of your app, so the runtime behavior will not be covered at all only through obfuscation

But also considering exclusively the static analysis that you will undergo you are far from being secure

I'll make you a practical easy example because the differences between the two tools you suggested are already reported in another answer

Say that you have an original unobfuscated MainActivity given by:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //...

    // lines for adding the shortcut in the home screen
    appPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    isAppInstalled = appPreferences.getBoolean("isAppInstalled", false);

    if(isAppInstalled == false)
        addShortcut();

where:

private void addShortcut() {
    //Adding shortcut

    // ...

    addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    // ...

    SharedPreferences.Editor editor = appPreferences.edit();
    editor.putBoolean("isAppInstalled", true);
    editor.commit();
}

These are the coounterparts obfuscated by ProGuard and taken through an online Java decompiler

decompiled_obfuscated_onCreate()

enter image description here

Conclusions:

1) as you can see - despite the proguard obfuscation - you are in a position where an attacker can easily modify the code flow [e.g. turning if (!this.f2293p) into if (this.f2293p)] and easily understand what you have to do to modify a value in your app, despite obfuscation. In this case it was a simple stupid "isAppInstalled" preference but of course it could have been something more sensitive like:

public boolean appIsPurchased(){
    return settings.getBoolean(keyPurchase,false);
}

PS storing unencrypted Shared Preferences [especially if containing sensitive data] is a very bad practice, this is just a quick example for demonstrational purposes. In rooted devices retrieving this file is just equal to browse to a system folder and search for an xml file

2) moreover in general this pure obfuscation will not hide anything which is hardcoded. We already saw that:

editor.putBoolean("isAppInstalled", true);

was transformed in:

this.f2293p = this.f2292o.getBoolean("isAppInstalled", false);

Another simple example can be:

if (barcode.equals("123456")) {
    return "Hat";
}
if (barcode.equals("234567")) {
    return "Jumper";
}
if (barcode.equals("345678")) {
    return "Pants";
}
return "Troubles detecting the new item";

becoming after obfuscation:

return str.equals("123456") ? "Hat" : str.equals("234567") ? "Jumper" : str.equals("345678") ? "Pants" : "Troubles detecting the new item";

Such strings are cheeky hints for people whose purpose is breaking your purely obfuscated app. For example your endpoints strings would be available to anyone

So you need a tool like DexGuard or other commercial solutions able to produce something more complex than simple obfuscation

This is an example of the final result from ProGuard + third-party security tool [I do not have DexGuard, I use another one where protection is automatically applied through a drag'n'drop of the original unprotected apk]

This is the new onCreate() method:

protected void onCreate(Bundle bundle) {
    //...
    this.f1859o = PreferenceManager.getDefaultSharedPreferences(this);
    this.f1860p = this.f1859o.getBoolean(k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("~"), false);
    if (!this.f1860p) {
        m3099j();
    }
}

while this is the second example with hardcoded strings that have been totally hidden from the hacker view:

public String m3101a(String str) {
    PrintStream printStream = System.out;
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("}}"));
    stringBuilder.append(str);
    String stringBuilder2 = stringBuilder.toString();
    return str.equals(k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("}|")) ? k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("}s") : str.equals(k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("}r")) ? k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("~{") : str.equals(k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("~z")) ? k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("~y") : k09kcah9u6scvhh4ab059fbmtq.itg7jcg3c4din73t0cib8n7eau("~x");
}

This is the degree of protection you need to pass the penetration test

Finally - as an additional safety measure - this kind of professional tools may also able to detect modifications in the protected "unreadable" code and stop the app execution if a tampering action on the protected version is detected. And also, unlike the simple [but beautiful] ProGuard, implement the detection for emulators, rooted devices and other potentially dangerous scenarios

Please note how the code was hardened through these steps. No one is 100% safe from being hacked. Your job is only making it as difficult as possible, that's it

查看更多
登录 后发表回答