mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
369 lines
46 KiB
Markdown
369 lines
46 KiB
Markdown
# Βασικά Στοιχεία Εφαρμογών Android
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Μοντέλο Ασφαλείας Android
|
||
|
||
**Υπάρχουν δύο επίπεδα:**
|
||
|
||
- Το **OS**, το οποίο κρατά τις εγκατεστημένες εφαρμογές απομονωμένες η μία από την άλλη.
|
||
- Η **εφαρμογή αυτή καθαυτή**, η οποία επιτρέπει στους προγραμματιστές να **εκθέτουν ορισμένες λειτουργίες** και ρυθμίζει τις δυνατότητες της εφαρμογής.
|
||
|
||
### Διαχωρισμός UID
|
||
|
||
**Κάθε εφαρμογή ανατίθεται σε μια συγκεκριμένη Ταυτότητα Χρήστη (User ID)**. Αυτό γίνεται κατά την εγκατάσταση της εφαρμογής ώστε **η εφαρμογή να μπορεί να αλληλεπιδρά μόνο με αρχεία που ανήκουν στην Ταυτότητα Χρήστη της ή με κοινά** αρχεία. Επομένως, μόνο η ίδια η εφαρμογή, ορισμένα στοιχεία του OS και ο χρήστης root μπορούν να έχουν πρόσβαση στα δεδομένα της εφαρμογής.
|
||
|
||
### Κοινή Χρήση UID
|
||
|
||
**Δύο εφαρμογές μπορούν να ρυθμιστούν να χρησιμοποιούν την ίδια UID**. Αυτό μπορεί να είναι χρήσιμο για την κοινή χρήση πληροφοριών, αλλά αν μία από αυτές παραβιαστεί, τα δεδομένα και των δύο εφαρμογών θα παραβιαστούν. Γι' αυτόν τον λόγο αυτή η συμπεριφορά είναι **απαγορευτική**.\
|
||
**Για να μοιραστούν την ίδια UID, οι εφαρμογές πρέπει να ορίσουν την ίδια τιμή `android:sharedUserId` στα μανιφέστα τους.**
|
||
|
||
### Sandbox
|
||
|
||
Η **Sandbox Εφαρμογών Android** επιτρέπει να εκτελείται **κάθε εφαρμογή** ως **ξεχωριστή διαδικασία υπό μια ξεχωριστή Ταυτότητα Χρήστη**. Κάθε διαδικασία έχει τη δική της εικονική μηχανή, έτσι ο κώδικας μιας εφαρμογής εκτελείται σε απομόνωση από άλλες εφαρμογές.\
|
||
Από το Android 5.0(L) **επιβάλλεται το SELinux**. Βασικά, το SELinux αρνείται όλες τις αλληλεπιδράσεις διαδικασιών και στη συνέχεια δημιουργεί πολιτικές για **να επιτρέπει μόνο τις αναμενόμενες αλληλεπιδράσεις μεταξύ τους**.
|
||
|
||
### Άδειες
|
||
|
||
Όταν εγκαθιστάτε μια **εφαρμογή και ζητά άδειες**, η εφαρμογή ζητά τις άδειες που έχουν ρυθμιστεί στα στοιχεία **`uses-permission`** στο αρχείο **AndroidManifest.xml**. Το στοιχείο **uses-permission** υποδεικνύει το όνομα της ζητούμενης άδειας μέσα στο **attribute name**. Έχει επίσης το **maxSdkVersion** attribute που σταματά να ζητά άδειες σε εκδόσεις υψηλότερες από αυτή που έχει καθοριστεί.\
|
||
Σημειώστε ότι οι εφαρμογές Android δεν χρειάζεται να ζητούν όλες τις άδειες στην αρχή, μπορούν επίσης να **ζητούν άδειες δυναμικά** αλλά όλες οι άδειες πρέπει να είναι **δηλωμένες** στο **μανιφέστο**.
|
||
|
||
Όταν μια εφαρμογή εκθέτει λειτουργικότητα μπορεί να περιορίσει την **πρόσβαση μόνο σε εφαρμογές που έχουν μια συγκεκριμένη άδεια**.\
|
||
Ένα στοιχείο άδειας έχει τρία attributes:
|
||
|
||
- Το **όνομα** της άδειας
|
||
- Το **permission-group** attribute, το οποίο επιτρέπει την ομαδοποίηση σχετικών αδειών.
|
||
- Το **protection-level** που υποδεικνύει πώς χορηγούνται οι άδειες. Υπάρχουν τέσσερις τύποι:
|
||
- **Normal**: Χρησιμοποιείται όταν δεν υπάρχουν **γνωστές απειλές** για την εφαρμογή. Ο χρήστης **δεν απαιτείται να την εγκρίνει**.
|
||
- **Dangerous**: Υποδεικνύει ότι η άδεια παρέχει στην αιτούμενη εφαρμογή κάποια **υψηλή πρόσβαση**. **Οι χρήστες ζητούνται να τις εγκρίνουν**.
|
||
- **Signature**: Μόνο **εφαρμογές που υπογράφονται από το ίδιο πιστοποιητικό με αυτό που εξάγει το στοιχείο** μπορούν να λάβουν άδεια. Αυτός είναι ο ισχυρότερος τύπος προστασίας.
|
||
- **SignatureOrSystem**: Μόνο **εφαρμογές που υπογράφονται από το ίδιο πιστοποιητικό με αυτό που εξάγει το στοιχείο ή **εφαρμογές που εκτελούνται με πρόσβαση σε επίπεδο συστήματος** μπορούν να λάβουν άδειες.
|
||
|
||
## Προεγκατεστημένες Εφαρμογές
|
||
|
||
Αυτές οι εφαρμογές βρίσκονται γενικά στους καταλόγους **`/system/app`** ή **`/system/priv-app`** και μερικές από αυτές είναι **βελτιστοποιημένες** (μπορεί να μην βρείτε καν το αρχείο `classes.dex`). Αυτές οι εφαρμογές αξίζουν να ελεγχθούν γιατί μερικές φορές εκτελούνται **με πάρα πολλές άδειες** (ως root).
|
||
|
||
- Αυτές που αποστέλλονται με το **AOSP** (Android OpenSource Project) **ROM**
|
||
- Προστέθηκαν από τον **κατασκευαστή της συσκευής**
|
||
- Προστέθηκαν από τον **πάροχο κινητής τηλεφωνίας** (αν αγοράστηκαν από αυτούς)
|
||
|
||
## Rooting
|
||
|
||
Για να αποκτήσετε πρόσβαση root σε μια φυσική συσκευή Android, γενικά χρειάζεται να **εκμεταλλευτείτε** 1 ή 2 **ευπάθειες** που συνήθως είναι **συγκεκριμένες** για τη **συσκευή** και **έκδοση**.\
|
||
Αφού η εκμετάλλευση έχει λειτουργήσει, συνήθως το δυαδικό `su` του Linux αντιγράφεται σε μια τοποθεσία που καθορίζεται στη μεταβλητή PATH του χρήστη όπως `/system/xbin`.
|
||
|
||
Αφού ρυθμιστεί το δυαδικό su, χρησιμοποιείται μια άλλη εφαρμογή Android για να αλληλεπιδράσει με το δυαδικό `su` και να **επεξεργαστεί αιτήματα για πρόσβαση root** όπως **Superuser** και **SuperSU** (διαθέσιμα στο Google Play store).
|
||
|
||
> [!CAUTION]
|
||
> Σημειώστε ότι η διαδικασία rooting είναι πολύ επικίνδυνη και μπορεί να προκαλέσει σοβαρή ζημιά στη συσκευή.
|
||
|
||
### ROMs
|
||
|
||
Είναι δυνατόν να **αντικαταστήσετε το OS εγκαθιστώντας ένα προσαρμοσμένο firmware**. Κάνοντας αυτό είναι δυνατό να επεκτείνετε τη χρησιμότητα μιας παλιάς συσκευής, να παρακάμψετε περιορισμούς λογισμικού ή να αποκτήσετε πρόσβαση στον τελευταίο κώδικα Android.\
|
||
**OmniROM** και **LineageOS** είναι δύο από τα πιο δημοφιλή firmware που χρησιμοποιούνται.
|
||
|
||
Σημειώστε ότι **δεν είναι πάντα απαραίτητο να κάνετε root τη συσκευή** για να εγκαταστήσετε ένα προσαρμοσμένο firmware. **Ορισμένοι κατασκευαστές επιτρέπουν** την ξεκλείδωση των bootloaders τους με καλά τεκμηριωμένο και ασφαλή τρόπο.
|
||
|
||
### Επιπτώσεις
|
||
|
||
Αφού μια συσκευή είναι rooted, οποιαδήποτε εφαρμογή θα μπορούσε να ζητήσει πρόσβαση ως root. Αν μια κακόβουλη εφαρμογή το αποκτήσει, θα έχει πρόσβαση σχεδόν σε όλα και θα μπορεί να προκαλέσει ζημιά στο τηλέφωνο.
|
||
|
||
## Θεμελιώδη Στοιχεία Εφαρμογών Android <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
|
||
|
||
- Η μορφή των εφαρμογών Android αναφέρεται ως _APK file format_. Είναι ουσιαστικά ένα **ZIP αρχείο** (με την αλλαγή της επέκτασης αρχείου σε .zip, το περιεχόμενο μπορεί να εξαχθεί και να προβληθεί).
|
||
- Περιεχόμενα APK (Όχι εξαντλητικά)
|
||
- **AndroidManifest.xml**
|
||
- resources.arsc/strings.xml
|
||
- resources.arsc: περιέχει προετοιμασμένους πόρους, όπως δυαδικό XML.
|
||
- res/xml/files_paths.xml
|
||
- META-INF/
|
||
- Εδώ βρίσκεται το Πιστοποιητικό!
|
||
- **classes.dex**
|
||
- Περιέχει Dalvik bytecode, που αντιπροσωπεύει τον μεταγλωττισμένο κώδικα Java (ή Kotlin) που εκτελεί η εφαρμογή από προεπιλογή.
|
||
- lib/
|
||
- Περιέχει εγγενείς βιβλιοθήκες, διαχωρισμένες κατά αρχιτεκτονική CPU σε υποκαταλόγους.
|
||
- `armeabi`: κώδικας για επεξεργαστές ARM
|
||
- `armeabi-v7a`: κώδικας για επεξεργαστές ARMv7 και ανώτερους
|
||
- `x86`: κώδικας για επεξεργαστές X86
|
||
- `mips`: κώδικας μόνο για επεξεργαστές MIPS
|
||
- assets/
|
||
- Αποθηκεύει διάφορα αρχεία που χρειάζεται η εφαρμογή, ενδεχομένως περιλαμβάνοντας επιπλέον εγγενείς βιβλιοθήκες ή αρχεία DEX, που μερικές φορές χρησιμοποιούνται από συγγραφείς κακόβουλου λογισμικού για να αποκρύψουν επιπλέον κώδικα.
|
||
- res/
|
||
- Περιέχει πόρους που δεν έχουν μεταγλωττιστεί σε resources.arsc.
|
||
|
||
### **Dalvik & Smali**
|
||
|
||
Στην ανάπτυξη Android, χρησιμοποιείται **Java ή Kotlin** για τη δημιουργία εφαρμογών. Αντί να χρησιμοποιεί την JVM όπως στις επιτραπέζιες εφαρμογές, το Android μεταγλωττίζει αυτόν τον κώδικα σε **Dalvik Executable (DEX) bytecode**. Παλαιότερα, η εικονική μηχανή Dalvik χειριζόταν αυτόν τον bytecode, αλλά τώρα, το Android Runtime (ART) αναλαμβάνει σε νεότερες εκδόσεις Android.
|
||
|
||
Για την αντίστροφη μηχανική, το **Smali** γίνεται κρίσιμο. Είναι η αναγνώσιμη από άνθρωπο έκδοση του DEX bytecode, λειτουργώντας σαν γλώσσα συναρμολόγησης μεταφράζοντας τον πηγαίο κώδικα σε εντολές bytecode. Το Smali και το baksmali αναφέρονται στα εργαλεία συναρμολόγησης και αποσυναρμολόγησης σε αυτό το πλαίσιο.
|
||
|
||
## Intents
|
||
|
||
Τα Intents είναι ο κύριος τρόπος με τον οποίο οι εφαρμογές Android επικοινωνούν μεταξύ των στοιχείων τους ή με άλλες εφαρμογές. Αυτά τα αντικείμενα μηνυμάτων μπορούν επίσης να μεταφέρουν δεδομένα μεταξύ εφαρμογών ή στοιχείων, παρόμοια με το πώς χρησιμοποιούνται τα GET/POST αιτήματα στις επικοινωνίες HTTP.
|
||
|
||
Έτσι, ένα Intent είναι βασικά ένα **μήνυμα που μεταφέρεται μεταξύ στοιχείων**. Τα Intents **μπορούν να κατευθύνονται** σε συγκεκριμένα στοιχεία ή εφαρμογές, **ή μπορούν να σταλούν χωρίς συγκεκριμένο παραλήπτη**.\
|
||
Για να είμαστε απλοί, το Intent μπορεί να χρησιμοποιηθεί:
|
||
|
||
- Για να ξεκινήσει μια Δραστηριότητα, συνήθως ανοίγοντας μια διεπαφή χρήστη για μια εφαρμογή
|
||
- Ως ραδιοφωνικές εκπομπές για να ενημερώσουν το σύστημα και τις εφαρμογές για αλλαγές
|
||
- Για να ξεκινήσει, να σταματήσει και να επικοινωνήσει με μια υπηρεσία στο παρασκήνιο
|
||
- Για να αποκτήσει πρόσβαση σε δεδομένα μέσω ContentProviders
|
||
- Ως callbacks για να χειριστεί γεγονότα
|
||
|
||
Αν είναι ευάλωτα, **τα Intents μπορούν να χρησιμοποιηθούν για να εκτελέσουν μια ποικιλία επιθέσεων**.
|
||
|
||
### Intent-Filter
|
||
|
||
**Τα Intent Filters** καθορίζουν **πώς μια δραστηριότητα, υπηρεσία ή Broadcast Receiver μπορεί να αλληλεπιδράσει με διάφορους τύπους Intents**. Βασικά, περιγράφουν τις δυνατότητες αυτών των στοιχείων, όπως ποιες ενέργειες μπορούν να εκτελούν ή τους τύπους ραδιοφωνικών εκπομπών που μπορούν να επεξεργαστούν. Ο κύριος χώρος για να δηλωθούν αυτά τα φίλτρα είναι μέσα στο **AndroidManifest.xml αρχείο**, αν και για τους Broadcast Receivers, η κωδικοποίησή τους είναι επίσης μια επιλογή.
|
||
|
||
Τα Intent Filters αποτελούνται από κατηγορίες, ενέργειες και φίλτρα δεδομένων, με τη δυνατότητα να περιλαμβάνουν επιπλέον μεταδεδομένα. Αυτή η ρύθμιση επιτρέπει στα στοιχεία να χειρίζονται συγκεκριμένα Intents που ταιριάζουν με τα δηλωμένα κριτήρια.
|
||
|
||
Μια κρίσιμη πτυχή των στοιχείων Android (δραστηριότητες/υπηρεσίες/παρόχοι περιεχομένου/δέκτες ραδιοφωνικών εκπομπών) είναι η ορατότητά τους ή η **δημόσια κατάσταση**. Ένα στοιχείο θεωρείται δημόσιο και μπορεί να αλληλεπιδράσει με άλλες εφαρμογές αν είναι **`exported`** με τιμή **`true`** ή αν έχει δηλωθεί ένα Intent Filter γι' αυτό στο μανιφέστο. Ωστόσο, υπάρχει τρόπος για τους προγραμματιστές να κρατήσουν ρητά αυτά τα στοιχεία ιδιωτικά, διασφαλίζοντας ότι δεν αλληλεπιδρούν με άλλες εφαρμογές κατά λάθος. Αυτό επιτυγχάνεται ρυθμίζοντας το **`exported`** attribute σε **`false`** στις δηλώσεις του μανιφέστου τους.
|
||
|
||
Επιπλέον, οι προγραμματιστές έχουν τη δυνατότητα να ασφαλίσουν περαιτέρω την πρόσβαση σε αυτά τα στοιχεία απαιτώντας συγκεκριμένες άδειες. Το **`permission`** attribute μπορεί να ρυθμιστεί ώστε να επιβάλλει ότι μόνο οι εφαρμογές με την καθορισμένη άδεια μπορούν να έχουν πρόσβαση στο στοιχείο, προσθέτοντας ένα επιπλέον επίπεδο ασφάλειας και ελέγχου σχετικά με το ποιος μπορεί να αλληλεπιδράσει με αυτό.
|
||
```java
|
||
<activity android:name=".MyActivity" android:exported="false">
|
||
<!-- Intent filters go here -->
|
||
</activity>
|
||
```
|
||
### Implicit Intents
|
||
|
||
Intents δημιουργούνται προγραμματικά χρησιμοποιώντας έναν κατασκευαστή Intent:
|
||
```java
|
||
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
||
```
|
||
Η **Δράση** της προηγουμένως δηλωμένης πρόθεσης είναι **ACTION_SEND** και το **Επιπλέον** είναι ένα mailto **Uri** (το Επιπλέον είναι οι επιπλέον πληροφορίες που αναμένει η πρόθεση).
|
||
|
||
Αυτή η πρόθεση θα πρέπει να δηλωθεί μέσα στο μανιφέστο όπως στο παρακάτω παράδειγμα:
|
||
```xml
|
||
<activity android:name="ShareActivity">
|
||
<intent-filter>
|
||
<action android:name="android.intent.action.SEND" />
|
||
<category android:name="android.intent.category.DEFAULT" />
|
||
</intent-filter>
|
||
</activity>
|
||
```
|
||
Ένα intent-filter πρέπει να ταιριάζει με την **ενέργεια**, **δεδομένα** και **κατηγορία** για να λάβει ένα μήνυμα.
|
||
|
||
Η διαδικασία "Επίλυσης Intent" καθορίζει ποια εφαρμογή θα λάβει κάθε μήνυμα. Αυτή η διαδικασία εξετάζει το **χαρακτηριστικό προτεραιότητας**, το οποίο μπορεί να οριστεί στην **δήλωση intent-filter**, και **αυτό με την υψηλότερη προτεραιότητα θα επιλεγεί**. Αυτή η προτεραιότητα μπορεί να οριστεί μεταξύ -1000 και 1000 και οι εφαρμογές μπορούν να χρησιμοποιήσουν την τιμή `SYSTEM_HIGH_PRIORITY`. Εάν προκύψει μια **σύγκρουση**, εμφανίζεται ένα παράθυρο "επιλογής" ώστε ο **χρήστης να αποφασίσει**.
|
||
|
||
### Ρητές Intents
|
||
|
||
Ένα ρητό intent καθορίζει το όνομα της κλάσης που στοχεύει:
|
||
```java
|
||
Intent downloadIntent = new (this, DownloadService.class):
|
||
```
|
||
Σε άλλες εφαρμογές, προκειμένου να αποκτήσετε πρόσβαση στην προηγουμένως δηλωμένη πρόθεση, μπορείτε να χρησιμοποιήσετε:
|
||
```java
|
||
Intent intent = new Intent();
|
||
intent.setClassName("com.other.app", "com.other.app.ServiceName");
|
||
context.startService(intent);
|
||
```
|
||
### Pending Intents
|
||
|
||
Αυτά επιτρέπουν σε άλλες εφαρμογές να **εκτελούν ενέργειες εκ μέρους της εφαρμογής σας**, χρησιμοποιώντας την ταυτότητα και τις άδειες της εφαρμογής σας. Για την κατασκευή ενός Pending Intent θα πρέπει να **καθοριστεί μια πρόθεση και η ενέργεια που θα εκτελεστεί**. Εάν η **δηλωμένη πρόθεση δεν είναι Explicit** (δεν δηλώνει ποια πρόθεση μπορεί να την καλέσει) μια **κακόβουλη εφαρμογή θα μπορούσε να εκτελέσει την δηλωμένη ενέργεια** εκ μέρους της εφαρμογής-θύματος. Επιπλέον, **εάν δεν καθοριστεί κάποια ενέργεια**, η κακόβουλη εφαρμογή θα είναι σε θέση να εκτελέσει **οποιαδήποτε ενέργεια εκ μέρους της θύματος**.
|
||
|
||
### Broadcast Intents
|
||
|
||
Σε αντίθεση με τις προηγούμενες προθέσεις, οι οποίες γίνονται δεκτές μόνο από μία εφαρμογή, οι broadcast intents **μπορούν να γίνουν δεκτές από πολλές εφαρμογές**. Ωστόσο, από την έκδοση API 14, είναι **δυνατό να καθοριστεί η εφαρμογή που θα πρέπει να λάβει** το μήνυμα χρησιμοποιώντας το Intent.setPackage.
|
||
|
||
Εναλλακτικά, είναι επίσης δυνατό να **καθοριστεί μια άδεια κατά την αποστολή του broadcast**. Η εφαρμογή παραλήπτης θα χρειαστεί να έχει αυτή την άδεια.
|
||
|
||
Υπάρχουν **δύο τύποι** Broadcasts: **Normal** (ασύγχρονα) και **Ordered** (σύγχρονα). Η **σειρά** βασίζεται στην **ρυθμισμένη προτεραιότητα εντός του στοιχείου παραλήπτη**. **Κάθε εφαρμογή μπορεί να επεξεργαστεί, να μεταφέρει ή να απορρίψει το Broadcast.**
|
||
|
||
Είναι δυνατό να **σταλεί** ένα **broadcast** χρησιμοποιώντας τη λειτουργία `sendBroadcast(intent, receiverPermission)` από την κλάση `Context`.\
|
||
Μπορείτε επίσης να χρησιμοποιήσετε τη λειτουργία **`sendBroadcast`** από τον **`LocalBroadCastManager`** που διασφαλίζει ότι το **μήνυμα δεν θα φύγει ποτέ από την εφαρμογή**. Χρησιμοποιώντας αυτό δεν θα χρειαστεί καν να εξάγετε ένα συστατικό παραλήπτη.
|
||
|
||
### Sticky Broadcasts
|
||
|
||
Αυτού του είδους τα Broadcasts **μπορούν να προσπελαστούν πολύ μετά την αποστολή τους**.\
|
||
Αυτά έχουν αποσυρθεί στην έκδοση API 21 και συνιστάται να **μην τα χρησιμοποιείτε**.\
|
||
**Επιτρέπουν σε οποιαδήποτε εφαρμογή να υποκλέψει τα δεδομένα, αλλά και να τα τροποποιήσει.**
|
||
|
||
Εάν βρείτε λειτουργίες που περιέχουν τη λέξη "sticky" όπως **`sendStickyBroadcast`** ή **`sendStickyBroadcastAsUser`**, **ελέγξτε τον αντίκτυπο και προσπαθήστε να τις αφαιρέσετε**.
|
||
|
||
## Deep links / URL schemes
|
||
|
||
Στις εφαρμογές Android, οι **deep links** χρησιμοποιούνται για να ξεκινήσουν μια ενέργεια (Intent) απευθείας μέσω μιας διεύθυνσης URL. Αυτό γίνεται δηλώνοντας ένα συγκεκριμένο **URL scheme** εντός μιας δραστηριότητας. Όταν μια συσκευή Android προσπαθεί να **πρόσβαση σε μια διεύθυνση URL με αυτό το scheme**, η καθορισμένη δραστηριότητα εντός της εφαρμογής εκκινείται.
|
||
|
||
Το scheme πρέπει να δηλωθεί στο **`AndroidManifest.xml`** αρχείο:
|
||
```xml
|
||
[...]
|
||
<activity android:name=".MyActivity">
|
||
<intent-filter>
|
||
<action android:name="android.intent.action.VIEW" />
|
||
<category android:name="android.intent.category.DEFAULT" />
|
||
<category android:name="android.intent.category.BROWSABLE" />
|
||
<data android:scheme="examplescheme" />
|
||
</intent-filter>
|
||
[...]
|
||
```
|
||
Το σχήμα από το προηγούμενο παράδειγμα είναι `examplescheme://` (σημειώστε επίσης την **`κατηγορία BROWSABLE`**)
|
||
|
||
Στη συνέχεια, στο πεδίο δεδομένων, μπορείτε να καθορίσετε τον **host** και την **διαδρομή**:
|
||
```xml
|
||
<data android:scheme="examplescheme"
|
||
android:host="example"
|
||
/>
|
||
```
|
||
Για να αποκτήσετε πρόσβαση σε αυτό από τον ιστό, είναι δυνατόν να ορίσετε έναν σύνδεσμο όπως:
|
||
```xml
|
||
<a href="examplescheme://example/something">click here</a>
|
||
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
|
||
```
|
||
Για να βρείτε τον **κώδικα που θα εκτελείται στην Εφαρμογή**, πηγαίνετε στην δραστηριότητα που καλείται από το deeplink και αναζητήστε τη συνάρτηση **`onNewIntent`**.
|
||
|
||
Μάθετε πώς να [καλείτε deep links χωρίς να χρησιμοποιείτε σελίδες HTML](#exploiting-schemes-deep-links).
|
||
|
||
## AIDL - Γλώσσα Ορισμού Διεπαφής Android
|
||
|
||
Η **Γλώσσα Ορισμού Διεπαφής Android (AIDL)** έχει σχεδιαστεί για να διευκολύνει την επικοινωνία μεταξύ πελάτη και υπηρεσίας σε εφαρμογές Android μέσω **διαδικαστικής επικοινωνίας** (IPC). Δεδομένου ότι η άμεση πρόσβαση στη μνήμη άλλης διαδικασίας δεν επιτρέπεται στο Android, η AIDL απλοποιεί τη διαδικασία μαρσάροντας αντικείμενα σε μια μορφή που κατανοεί το λειτουργικό σύστημα, διευκολύνοντας έτσι την επικοινωνία μεταξύ διαφορετικών διαδικασιών.
|
||
|
||
### Βασικές Έννοιες
|
||
|
||
- **Δεσμευμένες Υπηρεσίες**: Αυτές οι υπηρεσίες χρησιμοποιούν την AIDL για IPC, επιτρέποντας σε δραστηριότητες ή συστατικά να συνδεθούν σε μια υπηρεσία, να κάνουν αιτήματα και να λαμβάνουν απαντήσεις. Η μέθοδος `onBind` στην κλάση της υπηρεσίας είναι κρίσιμη για την έναρξη της αλληλεπίδρασης, καθιστώντας την μια ζωτική περιοχή για έλεγχο ασφαλείας στην αναζήτηση ευπαθειών.
|
||
|
||
- **Messenger**: Λειτουργώντας ως δεσμευμένη υπηρεσία, ο Messenger διευκολύνει την IPC με έμφαση στην επεξεργασία δεδομένων μέσω της μεθόδου `onBind`. Είναι απαραίτητο να εξετάσετε αυτή τη μέθοδο προσεκτικά για οποιαδήποτε μη ασφαλή διαχείριση δεδομένων ή εκτέλεση ευαίσθητων συναρτήσεων.
|
||
|
||
- **Binder**: Αν και η άμεση χρήση της κλάσης Binder είναι λιγότερο συνηθισμένη λόγω της αφαίρεσης της AIDL, είναι χρήσιμο να κατανοήσετε ότι ο Binder λειτουργεί ως οδηγός επιπέδου πυρήνα διευκολύνοντας τη μεταφορά δεδομένων μεταξύ των χώρων μνήμης διαφορετικών διαδικασιών. Για περαιτέρω κατανόηση, υπάρχει διαθέσιμος πόρος στο [https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8).
|
||
|
||
## Συστατικά
|
||
|
||
Αυτά περιλαμβάνουν: **Δραστηριότητες, Υπηρεσίες, Δέκτες Εκπομπών και Παροχείς.**
|
||
|
||
### Δραστηριότητα Εκκίνησης και άλλες δραστηριότητες
|
||
|
||
Στις εφαρμογές Android, οι **δραστηριότητες** είναι σαν οθόνες, που δείχνουν διάφορα μέρη της διεπαφής χρήστη της εφαρμογής. Μια εφαρμογή μπορεί να έχει πολλές δραστηριότητες, καθεμία από τις οποίες παρουσιάζει μια μοναδική οθόνη στον χρήστη.
|
||
|
||
Η **δραστηριότητα εκκίνησης** είναι η κύρια πύλη σε μια εφαρμογή, που εκκινείται όταν πατάτε το εικονίδιο της εφαρμογής. Είναι καθορισμένη στο αρχείο manifest της εφαρμογής με συγκεκριμένα MAIN και LAUNCHER intents:
|
||
```markup
|
||
<activity android:name=".LauncherActivity">
|
||
<intent-filter>
|
||
<action android:name="android.intent.action.MAIN" />
|
||
<category android:name="android.intent.category.LAUNCHER" />
|
||
</intent-filter>
|
||
</activity>
|
||
```
|
||
Όχι όλες οι εφαρμογές χρειάζονται μια δραστηριότητα εκκίνησης, ειδικά αυτές χωρίς διεπαφή χρήστη, όπως οι υπηρεσίες παρασκηνίου.
|
||
|
||
Οι δραστηριότητες μπορούν να είναι διαθέσιμες σε άλλες εφαρμογές ή διεργασίες σημειώνοντάς τες ως "exported" στο μανιφέστο. Αυτή η ρύθμιση επιτρέπει σε άλλες εφαρμογές να ξεκινούν αυτή τη δραστηριότητα:
|
||
```markdown
|
||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||
```
|
||
Ωστόσο, η πρόσβαση σε μια δραστηριότητα από άλλη εφαρμογή δεν είναι πάντα κίνδυνος ασφαλείας. Η ανησυχία προκύπτει αν ευαίσθητα δεδομένα μοιράζονται ακατάλληλα, κάτι που θα μπορούσε να οδηγήσει σε διαρροές πληροφοριών.
|
||
|
||
Ο κύκλος ζωής μιας δραστηριότητας **ξεκινά με τη μέθοδο onCreate**, ρυθμίζοντας το UI και προετοιμάζοντας τη δραστηριότητα για αλληλεπίδραση με τον χρήστη.
|
||
|
||
### Υποκλάση Εφαρμογής
|
||
|
||
Στην ανάπτυξη Android, μια εφαρμογή έχει την επιλογή να δημιουργήσει μια **υποκλάση** της [Application](https://developer.android.com/reference/android/app/Application) κλάσης, αν και δεν είναι υποχρεωτική. Όταν οριστεί μια τέτοια υποκλάση, γίνεται η πρώτη κλάση που θα δημιουργηθεί μέσα στην εφαρμογή. Η μέθοδος **`attachBaseContext`**, αν υλοποιηθεί σε αυτή την υποκλάση, εκτελείται πριν από τη μέθοδο **`onCreate`**. Αυτή η ρύθμιση επιτρέπει την πρώιμη αρχικοποίηση πριν ξεκινήσει το υπόλοιπο της εφαρμογής.
|
||
```java
|
||
public class MyApp extends Application {
|
||
@Override
|
||
protected void attachBaseContext(Context base) {
|
||
super.attachBaseContext(base);
|
||
// Initialization code here
|
||
}
|
||
|
||
@Override
|
||
public void onCreate() {
|
||
super.onCreate();
|
||
// More initialization code
|
||
}
|
||
}
|
||
```
|
||
### Υπηρεσίες
|
||
|
||
[Υπηρεσίες](https://developer.android.com/guide/components/services) είναι **λειτουργίες παρασκηνίου** ικανές να εκτελούν εργασίες χωρίς διεπαφή χρήστη. Αυτές οι εργασίες μπορούν να συνεχίσουν να εκτελούνται ακόμη και όταν οι χρήστες αλλάζουν σε διαφορετικές εφαρμογές, καθιστώντας τις υπηρεσίες κρίσιμες για **μακροχρόνιες λειτουργίες**.
|
||
|
||
Οι υπηρεσίες είναι ευέλικτες; μπορούν να ξεκινήσουν με διάφορους τρόπους, με τις **Intents** να είναι η κύρια μέθοδος για την εκκίνηση τους ως σημείο εισόδου μιας εφαρμογής. Μόλις ξεκινήσει μια υπηρεσία χρησιμοποιώντας τη μέθοδο `startService`, η μέθοδος `onStart` ενεργοποιείται και συνεχίζει να εκτελείται μέχρι να κληθεί ρητά η μέθοδος `stopService`. Εναλλακτικά, αν ο ρόλος μιας υπηρεσίας εξαρτάται από μια ενεργή σύνδεση πελάτη, χρησιμοποιείται η μέθοδος `bindService` για τη σύνδεση του πελάτη με την υπηρεσία, ενεργοποιώντας τη μέθοδο `onBind` για τη μεταφορά δεδομένων.
|
||
|
||
Μια ενδιαφέρουσα εφαρμογή των υπηρεσιών περιλαμβάνει την αναπαραγωγή μουσικής παρασκηνίου ή την ανάκτηση δεδομένων δικτύου χωρίς να εμποδίζεται η αλληλεπίδραση του χρήστη με μια εφαρμογή. Επιπλέον, οι υπηρεσίες μπορούν να γίνουν προσβάσιμες σε άλλες διεργασίες στην ίδια συσκευή μέσω **εξαγωγής**. Αυτό δεν είναι η προεπιλεγμένη συμπεριφορά και απαιτεί ρητή ρύθμιση στο αρχείο Android Manifest:
|
||
```xml
|
||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||
```
|
||
### Broadcast Receivers
|
||
|
||
**Broadcast receivers** λειτουργούν ως ακροατές σε ένα σύστημα μηνυμάτων, επιτρέποντας σε πολλές εφαρμογές να ανταποκριθούν στα ίδια μηνύματα από το σύστημα. Μια εφαρμογή μπορεί να **καταχωρήσει έναν δέκτη** με **δύο κύριους τρόπους**: μέσω του **Manifest** της εφαρμογής ή **δυναμικά** μέσα στον κώδικα της εφαρμογής μέσω του **`registerReceiver`** API. Στο Manifest, οι εκπομπές φιλτράρονται με άδειες, ενώ οι δυναμικά καταχωρημένοι δέκτες μπορούν επίσης να καθορίσουν άδειες κατά την καταχώρηση.
|
||
|
||
**Intent filters** είναι κρίσιμα και στις δύο μεθόδους καταχώρησης, καθορίζοντας ποιες εκπομπές ενεργοποιούν τον δέκτη. Μόλις σταλεί μια αντίστοιχη εκπομπή, η μέθοδος **`onReceive`** του δέκτη καλείται, επιτρέποντας στην εφαρμογή να αντιδράσει αναλόγως, όπως η προσαρμογή της συμπεριφοράς σε απάντηση σε μια ειδοποίηση χαμηλής μπαταρίας.
|
||
|
||
Οι εκπομπές μπορεί να είναι είτε **ασύγχρονες**, φτάνοντας σε όλους τους δέκτες χωρίς σειρά, είτε **σύγχρονες**, όπου οι δέκτες λαμβάνουν την εκπομπή με βάση καθορισμένες προτεραιότητες. Ωστόσο, είναι σημαντικό να σημειωθεί ο πιθανός κίνδυνος ασφαλείας, καθώς οποιαδήποτε εφαρμογή μπορεί να δώσει προτεραιότητα στον εαυτό της για να παρεμποδίσει μια εκπομπή.
|
||
|
||
Για να κατανοήσετε τη λειτουργικότητα ενός δέκτη, αναζητήστε τη μέθοδο **`onReceive`** μέσα στην κλάση του. Ο κώδικας αυτής της μεθόδου μπορεί να χειριστεί το ληφθέν Intent, υπογραμμίζοντας την ανάγκη για επικύρωση δεδομένων από τους δέκτες, ειδικά σε **Ordered Broadcasts**, οι οποίες μπορούν να τροποποιήσουν ή να απορρίψουν το Intent.
|
||
|
||
### Content Provider
|
||
|
||
**Content Providers** είναι απαραίτητοι για **την κοινή χρήση δομημένων δεδομένων** μεταξύ εφαρμογών, τονίζοντας τη σημασία της εφαρμογής **αδειών** για την εξασφάλιση της ασφάλειας των δεδομένων. Επιτρέπουν στις εφαρμογές να έχουν πρόσβαση σε δεδομένα από διάφορες πηγές, συμπεριλαμβανομένων βάσεων δεδομένων, συστημάτων αρχείων ή του διαδικτύου. Συγκεκριμένες άδειες, όπως **`readPermission`** και **`writePermission`**, είναι κρίσιμες για τον έλεγχο της πρόσβασης. Επιπλέον, προσωρινή πρόσβαση μπορεί να παραχωρηθεί μέσω ρυθμίσεων **`grantUriPermission`** στο manifest της εφαρμογής, αξιοποιώντας χαρακτηριστικά όπως `path`, `pathPrefix` και `pathPattern` για λεπτομερή έλεγχο πρόσβασης.
|
||
|
||
Η επικύρωση εισόδου είναι πρωταρχικής σημασίας για την αποφυγή ευπαθειών, όπως η SQL injection. Οι Content Providers υποστηρίζουν βασικές λειτουργίες: `insert()`, `update()`, `delete()`, και `query()`, διευκολύνοντας τη χειρισμό και την κοινή χρήση δεδομένων μεταξύ εφαρμογών.
|
||
|
||
**FileProvider**, ένας εξειδικευμένος Content Provider, εστιάζει στην ασφαλή κοινή χρήση αρχείων. Ορίζεται στο manifest της εφαρμογής με συγκεκριμένα χαρακτηριστικά για τον έλεγχο πρόσβασης σε φακέλους, που δηλώνονται με `android:exported` και `android:resource` που δείχνουν στις ρυθμίσεις φακέλων. Συνιστάται προσοχή κατά την κοινή χρήση καταλόγων για την αποφυγή της τυχαίας έκθεσης ευαίσθητων δεδομένων.
|
||
|
||
Example manifest declaration for FileProvider:
|
||
```xml
|
||
<provider android:name="androidx.core.content.FileProvider"
|
||
android:authorities="com.example.myapp.fileprovider"
|
||
android:grantUriPermissions="true"
|
||
android:exported="false">
|
||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
|
||
android:resource="@xml/filepaths" />
|
||
</provider>
|
||
```
|
||
Και ένα παράδειγμα καθορισμού κοινών φακέλων στο `filepaths.xml`:
|
||
```xml
|
||
<paths>
|
||
<files-path path="images/" name="myimages" />
|
||
</paths>
|
||
```
|
||
Για περισσότερες πληροφορίες ελέγξτε:
|
||
|
||
- [Android Developers: Content Providers](https://developer.android.com/guide/topics/providers/content-providers)
|
||
- [Android Developers: FileProvider](https://developer.android.com/training/secure-file-sharing/setup-sharing)
|
||
|
||
## WebViews
|
||
|
||
WebViews είναι σαν **μικροί περιηγητές ιστού** μέσα σε εφαρμογές Android, αντλώντας περιεχόμενο είτε από το διαδίκτυο είτε από τοπικά αρχεία. Αντιμετωπίζουν παρόμοιους κινδύνους με τους κανονικούς περιηγητές, ωστόσο υπάρχουν τρόποι για να **μειωθούν αυτοί οι κίνδυνοι** μέσω συγκεκριμένων **ρυθμίσεων**.
|
||
|
||
Η Android προσφέρει δύο κύριους τύπους WebView:
|
||
|
||
- **WebViewClient** είναι εξαιρετικός για βασικό HTML αλλά δεν υποστηρίζει τη λειτουργία ειδοποίησης JavaScript, επηρεάζοντας τον τρόπο που μπορούν να δοκιμαστούν οι επιθέσεις XSS.
|
||
- **WebChromeClient** λειτουργεί περισσότερο σαν την πλήρη εμπειρία του περιηγητή Chrome.
|
||
|
||
Ένα βασικό σημείο είναι ότι οι περιηγητές WebView **δεν μοιράζονται cookies** με τον κύριο περιηγητή της συσκευής.
|
||
|
||
Για τη φόρτωση περιεχομένου, είναι διαθέσιμες μέθοδοι όπως `loadUrl`, `loadData` και `loadDataWithBaseURL`. Είναι κρίσιμο να διασφαλιστεί ότι αυτές οι διευθύνσεις URL ή τα αρχεία είναι **ασφαλή προς χρήση**. Οι ρυθμίσεις ασφαλείας μπορούν να διαχειριστούν μέσω της κλάσης `WebSettings`. Για παράδειγμα, η απενεργοποίηση της JavaScript με `setJavaScriptEnabled(false)` μπορεί να αποτρέψει επιθέσεις XSS.
|
||
|
||
Η JavaScript "Bridge" επιτρέπει στα αντικείμενα Java να αλληλεπιδρούν με τη JavaScript, απαιτώντας οι μέθοδοι να είναι επισημασμένες με `@JavascriptInterface` για ασφάλεια από την Android 4.2 και μετά.
|
||
|
||
Η επιτρεπόμενη πρόσβαση περιεχομένου (`setAllowContentAccess(true)`) επιτρέπει στις WebViews να προσεγγίζουν τους Content Providers, κάτι που θα μπορούσε να είναι κίνδυνος εκτός αν οι διευθύνσεις URL περιεχομένου επιβεβαιωθούν ως ασφαλείς.
|
||
|
||
Για τον έλεγχο πρόσβασης σε αρχεία:
|
||
|
||
- Η απενεργοποίηση της πρόσβασης σε αρχεία (`setAllowFileAccess(false)`) περιορίζει την πρόσβαση στο σύστημα αρχείων, με εξαιρέσεις για ορισμένα περιουσιακά στοιχεία, διασφαλίζοντας ότι χρησιμοποιούνται μόνο για μη ευαίσθητο περιεχόμενο.
|
||
|
||
## Άλλα Συστατικά Εφαρμογών και Διαχείριση Κινητών Συσκευών
|
||
|
||
### **Ψηφιακή Υπογραφή Εφαρμογών**
|
||
|
||
- **Ψηφιακή υπογραφή** είναι απαραίτητη για τις εφαρμογές Android, διασφαλίζοντας ότι είναι **αυθεντικά συγγραφείς** πριν από την εγκατάσταση. Αυτή η διαδικασία χρησιμοποιεί ένα πιστοποιητικό για την αναγνώριση της εφαρμογής και πρέπει να επαληθευτεί από τον διαχειριστή πακέτων της συσκευής κατά την εγκατάσταση. Οι εφαρμογές μπορούν να είναι **αυτο-υπογεγραμμένες ή πιστοποιημένες από εξωτερικό CA**, προστατεύοντας από μη εξουσιοδοτημένη πρόσβαση και διασφαλίζοντας ότι η εφαρμογή παραμένει αμετάβλητη κατά την παράδοσή της στη συσκευή.
|
||
|
||
### **Επαλήθευση Εφαρμογών για Αυξημένη Ασφάλεια**
|
||
|
||
- Ξεκινώντας από την **Android 4.2**, μια δυνατότητα που ονομάζεται **Verify Apps** επιτρέπει στους χρήστες να ελέγχουν τις εφαρμογές για ασφάλεια πριν από την εγκατάσταση. Αυτή η **διαδικασία επαλήθευσης** μπορεί να προειδοποιήσει τους χρήστες για πιθανώς επιβλαβείς εφαρμογές ή ακόμη και να αποτρέψει την εγκατάσταση ιδιαίτερα κακόβουλων, ενισχύοντας την ασφάλεια των χρηστών.
|
||
|
||
### **Διαχείριση Κινητών Συσκευών (MDM)**
|
||
|
||
- Οι **λύσεις MDM** παρέχουν **επίβλεψη και ασφάλεια** για κινητές συσκευές μέσω του **Device Administration API**. Απαιτούν την εγκατάσταση μιας εφαρμογής Android για να διαχειρίζονται και να ασφαλίζουν αποτελεσματικά τις κινητές συσκευές. Οι βασικές λειτουργίες περιλαμβάνουν **επιβολή πολιτικών κωδικών πρόσβασης**, **υποχρεωτική κρυπτογράφηση αποθήκευσης** και **άδεια απομακρυσμένης διαγραφής δεδομένων**, διασφαλίζοντας πλήρη έλεγχο και ασφάλεια πάνω στις κινητές συσκευές.
|
||
```java
|
||
// Example of enforcing a password policy with MDM
|
||
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);
|
||
|
||
if (dpm.isAdminActive(adminComponent)) {
|
||
// Set minimum password length
|
||
dpm.setPasswordMinimumLength(adminComponent, 8);
|
||
}
|
||
```
|
||
{{#include ../../banners/hacktricks-training.md}}
|