DIVA Android
  • Damn Insecure and Vulnerable App (DIVA)
  • Pendahuluan
    • Persiapan
    • Konfigurasi Burp Suite dengan Android
    • Instalasi Aplikasi DIVA
  • Reversing of APK
    • Decompiling dan Reversing APK
  • Challenges
    • Insecure Logging
    • Hardcoding Issues - Part 1
    • Insecure Data Storage - Part 1
    • Insecure Data Storage - Part 2
    • Insecure Data Storage - Part 3
    • Insecure Data Storage - Part 4
    • Input Validation Issues - Part 1
    • Input Validation Issues - Part 2
    • Access Control Issues - Part 1
    • Access Control Issues - Part 2
    • Access Control Issues - Part 3
    • Hardcoding Issues - Part 2
    • Input Validation Issues - Part 3
Powered by GitBook
On this page
  • Pendahuluan
  • Penjelasan
  • Melihat Source Code
  • SQL Injection
  • Kesimpulan

Was this helpful?

  1. Challenges

Input Validation Issues - Part 1

SQLite Injection – Input Validation Security Risk

PreviousInsecure Data Storage - Part 4NextInput Validation Issues - Part 2

Last updated 4 years ago

Was this helpful?

Pendahuluan

Seperti yang di bahas , Android bisa menggunakan database SQLite untuk menyimpan data secara lokal sebagai Relational Database Management System (RDBMS).

Penggunaan database SQL tanpa penanganan yang tepat berisiko terjadinya serangan SQL injection. Dengan serangan SQL Injection kita bisa mendapatkan seluruh data pada database tersebut.

Untuk melakukan serangan SQL injection Anda tidak perlu melakukan rooting pada perangkat, karena serangan ini adalah kesalahan dari program tersebut dalam menerima inputan user dan menjalankan query ke RDBMS.

Tidak adanya validasi untuk inputan user menyebabkan segala yang diinputkan user langsung dijadikan query. Hal ini bisa dimanfaatkan oleh Attacker untuk menjalankan payload-nya agar bisa mendapatkan seluruh data dari database tersebut.

Penjelasan

Melihat Source Code

SQLInjectionActivity.class
package jakhar.aseem.diva;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class SQLInjectionActivity extends AppCompatActivity {
  private SQLiteDatabase mDB;
  
  protected void onCreate(Bundle paramBundle) {
    super.onCreate(paramBundle);
    try {
      this.mDB = openOrCreateDatabase("sqli", 0, null);
      this.mDB.execSQL("DROP TABLE IF EXISTS sqliuser;");
      this.mDB.execSQL("CREATE TABLE IF NOT EXISTS sqliuser(user VARCHAR, password VARCHAR, credit_card VARCHAR);");
      this.mDB.execSQL("INSERT INTO sqliuser VALUES ('admin', 'passwd123', '1234567812345678');");
      this.mDB.execSQL("INSERT INTO sqliuser VALUES ('diva', 'p@ssword', '1111222233334444');");
      this.mDB.execSQL("INSERT INTO sqliuser VALUES ('john', 'password123', '5555666677778888');");
    } catch (Exception exception) {
      Log.d("Diva-sqli", "Error occurred while creating database for SQLI: " + exception.getMessage());
    } 
    setContentView(2130968617);
  }
  
  public void search(View paramView) {
    EditText editText = (EditText)findViewById(2131493017);
    try {
      StringBuilder stringBuilder1;
      SQLiteDatabase sQLiteDatabase = this.mDB;
      StringBuilder stringBuilder2 = new StringBuilder();
      this();
      Cursor cursor = sQLiteDatabase.rawQuery(stringBuilder2.append("SELECT * FROM sqliuser WHERE user = '").append(editText.getText().toString()).append("'").toString(), null);
      stringBuilder2 = new StringBuilder();
      this("");
      if (cursor != null && cursor.getCount() > 0) {
        cursor.moveToFirst();
        do {
          stringBuilder1 = new StringBuilder();
          this();
          stringBuilder2.append(stringBuilder1.append("User: (").append(cursor.getString(0)).append(") pass: (").append(cursor.getString(1)).append(") Credit card: (").append(cursor.getString(2)).append(")\n").toString());
        } while (cursor.moveToNext());
      } else {
        StringBuilder stringBuilder = new StringBuilder();
        this();
        stringBuilder2.append(stringBuilder.append("User: (").append(stringBuilder1.getText().toString()).append(") not found").toString());
      } 
      Toast.makeText((Context)this, stringBuilder2.toString(), 0).show();
    } catch (Exception exception) {
      Log.d("Diva-sqli", "Error occurred while searching in database: " + exception.getMessage());
    } 
  }
}

Terlihat bahwa data yang diinputkan user disimpan pada database SQLite.

Dan perhatikan pada baris ke-38, nilai yang diinputan user langsung dijalankan sebagai query (request ke RDBMS) tanpa adanya filter atau validasi terlebih dahulu. Hal ini menyebabkan Attacker bisa melakukan serangan SQL Injection.

SELECT * FROM sqliuser WHERE user = '<inputan>';

SQL Injection

Gunakan payload %' or '1' = '1 agar query yang dijalakan oleh aplikasi menjadi seperti berikut:

SELECT * FROM sqliuser WHERE user = '%' or '1' = '1';

Query di atas akan menampilkan semua record dari tabel sqliuser.

Terlihat bahwa data sensitif milik seluruh user dapat ditampilkan, bahkan secara plain text. Ini membuktikan bahwa aplikasi ini tidak bisa menyimpan data dengan aman.

Kesimpulan

Tidak adanya validasi untuk inputan membuat Attacker bisa menginputkan malicious payload untuk melakukan serangan SQL Injection.

Menyadari fakta tersebut, terdapat beberapa rekomendasi yang bisa developer lakukan, diantaranya:

  • Melakukan validasi terhadap inputan yang mengandung SQL special characters.

  • Melakukan salting + hashing pada informasi sensitif seperti password.

Bagian aplikasi yang akan kita bahas kali ini memiliki fitur untuk mencari data user berdasarkan username. Biasanya aplikasi menyimpan data menggunakan database. Dengan melakukan lalu menganalisis source code, kita akan mencari tahu apakah penggunaan database tersebut telah aman dari serangan SQL injection atau tidak.

reverse engineering
Tampilan Soal Input Validation Issues - Part 1
SQL Injection
sebelumnya