Android Applications Basics

Υποστήριξη HackTricks

Μοντέλο Ασφαλείας 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:

  • Το όνομα της άδειας

  • Το attribute permission-group, το οποίο επιτρέπει την ομαδοποίηση σχετικών αδειών.

  • Το 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).

Σημειώστε ότι η διαδικασία rooting είναι πολύ επικίνδυνη και μπορεί να προκαλέσει σοβαρή ζημιά στη συσκευή

ROMs

Είναι δυνατόν να αντικαταστήσετε το OS εγκαθιστώντας ένα προσαρμοσμένο firmware. Κάνοντας αυτό, είναι δυνατό να επεκτείνετε τη χρησιμότητα μιας παλιάς συσκευής, να παρακάμψετε περιορισμούς λογισμικού ή να αποκτήσετε πρόσβαση στον τελευταίο κώδικα Android. OmniROM και LineageOS είναι δύο από τα πιο δημοφιλή firmware που χρησιμοποιούνται.

Σημειώστε ότι δεν είναι πάντα απαραίτητο να κάνετε root τη συσκευή για να εγκαταστήσετε ένα προσαρμοσμένο firmware. Ορισμένοι κατασκευαστές επιτρέπουν την ξεκλείδωσή των bootloaders τους με καλά τεκμηριωμένο και ασφαλή τρόπο.

Επιπτώσεις

Αφού μια συσκευή είναι rooted, οποιαδήποτε εφαρμογή θα μπορούσε να ζητήσει πρόσβαση ως root. Αν μια κακόβουλη εφαρμογή το αποκτήσει, θα έχει πρόσβαση σχεδόν σε όλα και θα μπορεί να προκαλέσει ζημιά στο τηλέφωνο.

Θεμελιώδη Στοιχεία Εφαρμογών Android

  • Η μορφή των εφαρμογών Android αναφέρεται ως APK file format. Είναι ουσιαστικά ένα ZIP αρχείο (με την αλλαγή της επέκτασης αρχείου σε .zip, το περιεχόμενο μπορεί να εξαχθεί και να προβληθεί).

  • Περιεχόμενα APK (Όχι εξαντλητικά)

  • AndroidManifest.xml

  • resources.arsc/strings.xml

  • resources.arsc: περιέχει προcompiled resources, όπως δυαδικό 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, λειτουργώντας σαν γλώσσα assembly μεταφράζοντας τον πηγαίο κώδικα σε εντολές bytecode. Το Smali και το baksmali αναφέρονται στα εργαλεία assembly και disassembly σε αυτό το πλαίσιο.

Intents

Τα Intents είναι ο κύριος τρόπος με τον οποίο οι εφαρμογές Android επικοινωνούν μεταξύ των στοιχείων τους ή με άλλες εφαρμογές. Αυτά τα αντικείμενα μηνυμάτων μπορούν επίσης να μεταφέρουν δεδομένα μεταξύ εφαρμογών ή στοιχείων, παρόμοια με το πώς χρησιμοποιούνται τα GET/POST requests στις επικοινωνίες HTTP.

Έτσι, ένα Intent είναι βασικά ένα μήνυμα που μεταφέρεται μεταξύ στοιχείων. Τα Intents μπορούν να κατευθύνονται σε συγκεκριμένα στοιχεία ή εφαρμογές, ή μπορούν να σταλούν χωρίς συγκεκριμένο παραλήπτη. Για να είμαστε απλοί, το Intent μπορεί να χρησιμοποιηθεί:

  • Για να ξεκινήσει μια Δραστηριότητα, συνήθως ανοίγοντας μια διεπαφή χρήστη για μια εφαρμογή

  • Ως broadcasts για να ενημερώσουν το σύστημα και τις εφαρμογές για αλλαγές

  • Για να ξεκινήσει, να σταματήσει και να επικοινωνήσει με μια υπηρεσία στο παρασκήνιο

  • Για να αποκτήσει πρόσβαση σε δεδομένα μέσω ContentProviders

  • Ως callbacks για να χειριστεί γεγονότα

Αν είναι ευάλωτα, τα Intents μπορούν να χρησιμοποιηθούν για να εκτελέσουν μια ποικιλία επιθέσεων.

Intent-Filter

Τα Intent Filters καθορίζουν πώς μια δραστηριότητα, υπηρεσία ή Broadcast Receiver μπορεί να αλληλεπιδράσει με διάφορους τύπους Intents. Βασικά, περιγράφουν τις δυνατότητες αυτών των στοιχείων, όπως ποιες ενέργειες μπορούν να εκτελούν ή τους τύπους broadcasts που μπορούν να επεξεργαστούν. Ο κύριος χώρος για να δηλωθούν αυτά τα φίλτρα είναι μέσα στο AndroidManifest.xml αρχείο, αν και για τους Broadcast Receivers, η κωδικοποίησή τους είναι επίσης μια επιλογή.

Τα Intent Filters αποτελούνται από κατηγορίες, ενέργειες και φίλτρα δεδομένων, με τη δυνατότητα να περιλαμβάνουν επιπλέον μεταδεδομένα. Αυτή η ρύθμιση επιτρέπει στα στοιχεία να χειρίζονται συγκεκριμένα Intents που ταιριάζουν με τα δηλωμένα κριτήρια.

Μια κρίσιμη πτυχή των στοιχείων Android (δραστηριότητες/υπηρεσίες/content providers/broadcast receivers) είναι η ορατότητά τους ή η δημόσια κατάσταση. Ένα στοιχείο θεωρείται δημόσιο και μπορεί να αλληλεπιδράσει με άλλες εφαρμογές αν είναι exported με τιμή true ή αν έχει δηλωθεί ένα Intent Filter γι' αυτό στο μανιφέστο. Ωστόσο, υπάρχει τρόπος για τους προγραμματιστές να κρατήσουν αυτά τα στοιχεία ιδιωτικά, διασφαλίζοντας ότι δεν αλληλεπιδρούν με άλλες εφαρμογές κατά λάθος. Αυτό επιτυγχάνεται ρυθμίζοντας το exported attribute σε false στις δηλώσεις του μανιφέστου τους.

Επιπλέον, οι προγραμματιστές έχουν τη δυνατότητα να ασφαλίσουν περαιτέρω την πρόσβαση σε αυτά τα στοιχεία απαιτώντας συγκεκριμένες άδειες. Το permission attribute μπορεί να ρυθμιστεί ώστε να επιβάλλει ότι μόνο οι εφαρμογές με την καθορισμένη άδεια μπορούν να έχουν πρόσβαση στο στοιχείο, προσθέτοντας ένα επιπλέον επίπεδο ασφάλειας και ελέγχου σχετικά με το ποιος μπορεί να αλληλεπιδράσει με αυτό.

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

Implicit Intents

Τα Intents δημιουργούνται προγραμματικά χρησιμοποιώντας έναν κατασκευαστή Intent:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

Η Δράση της προηγουμένως δηλωμένης πρόθεσης είναι ACTION_SEND και το Επιπλέον είναι ένα mailto Uri (το Επιπλέον είναι οι επιπλέον πληροφορίες που περιμένει η πρόθεση).

Αυτή η πρόθεση θα πρέπει να δηλωθεί μέσα στο μανιφέστο όπως στο παρακάτω παράδειγμα:

<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 downloadIntent = new (this, DownloadService.class):

Σε άλλες εφαρμογές, προκειμένου να αποκτήσετε πρόσβαση στην προηγουμένως δηλωμένη πρόθεση, μπορείτε να χρησιμοποιήσετε:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

Αυτά επιτρέπουν σε άλλες εφαρμογές να εκτελούν ενέργειες εκ μέρους της εφαρμογής σας, χρησιμοποιώντας την ταυτότητα και τις άδειες της εφαρμογής σας. Για να κατασκευάσετε ένα Pending Intent, θα πρέπει να καθοριστεί μια πρόθεση και η ενέργεια που θα εκτελεστεί. Εάν η δηλωμένη πρόθεση δεν είναι Ρητή (δεν δηλώνει ποια πρόθεση μπορεί να την καλέσει), μια κακόβουλη εφαρμογή θα μπορούσε να εκτελέσει την δηλωμένη ενέργεια εκ μέρους της εφαρμογής-θύματος. Επιπλέον, εάν δεν καθοριστεί κάποια ενέργεια, η κακόβουλη εφαρμογή θα είναι σε θέση να εκτελέσει οποιαδήποτε ενέργεια εκ μέρους του θύματος.

Broadcast Intents

Σε αντίθεση με τις προηγούμενες προθέσεις, οι οποίες γίνονται δεκτές μόνο από μία εφαρμογή, οι broadcast intents μπορούν να γίνουν δεκτές από πολλές εφαρμογές. Ωστόσο, από την έκδοση API 14, είναι δυνατό να καθοριστεί η εφαρμογή που θα λάβει το μήνυμα χρησιμοποιώντας το Intent.setPackage.

Εναλλακτικά, είναι επίσης δυνατό να καθοριστεί μια άδεια κατά την αποστολή του broadcast. Η εφαρμογή παραλήπτης θα χρειαστεί να έχει αυτή την άδεια.

Υπάρχουν δύο τύποι Broadcasts: Κανονικά (ασύγχρονα) και Ταξινομημένα (συγχρονισμένα). Η σειρά βασίζεται στην ρυθμισμένη προτεραιότητα εντός του στοιχείου παραλήπτη. Κάθε εφαρμογή μπορεί να επεξεργαστεί, να μεταφέρει ή να απορρίψει το Broadcast.

Είναι δυνατό να σταλεί ένα broadcast χρησιμοποιώντας τη λειτουργία sendBroadcast(intent, receiverPermission) από την κλάση Context. Μπορείτε επίσης να χρησιμοποιήσετε τη λειτουργία sendBroadcast από τον LocalBroadCastManager που διασφαλίζει ότι το μήνυμα δεν θα φύγει ποτέ από την εφαρμογή. Χρησιμοποιώντας αυτό, δεν θα χρειαστεί καν να εξάγετε ένα συστατικό παραλήπτη.

Sticky Broadcasts

Αυτός ο τύπος Broadcasts μπορεί να προσπελαστεί πολύ μετά την αποστολή τους. Αυτά έχουν αποσυρθεί στην έκδοση API 21 και συνιστάται να μην τα χρησιμοποιείτε. Επιτρέπουν σε οποιαδήποτε εφαρμογή να κατασκοπεύει τα δεδομένα, αλλά και να τα τροποποιεί.

Εάν βρείτε λειτουργίες που περιέχουν τη λέξη "sticky" όπως sendStickyBroadcast ή sendStickyBroadcastAsUser, ελέγξτε τον αντίκτυπο και προσπαθήστε να τα αφαιρέσετε.

Στις εφαρμογές Android, οι deep links χρησιμοποιούνται για να ξεκινήσουν μια ενέργεια (Intent) απευθείας μέσω ενός URL. Αυτό γίνεται δηλώνοντας ένα συγκεκριμένο URL scheme εντός μιας δραστηριότητας. Όταν μια συσκευή Android προσπαθεί να προσεγγίσει ένα URL με αυτό το scheme, η καθορισμένη δραστηριότητα εντός της εφαρμογής εκκινείται.

Το scheme πρέπει να δηλωθεί στο AndroidManifest.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>
[...]

Το σχήμα από το προηγούμενο παράδειγμα είναι exampleapp:// (σημειώστε επίσης το category BROWSABLE)

Στη συνέχεια, στο πεδίο δεδομένων, μπορείτε να καθορίσετε τον host και τη διαδρομή:

<data android:scheme="examplescheme"
android:host="example"
/>

Για να αποκτήσετε πρόσβαση σε αυτό από τον ιστό, είναι δυνατόν να ορίσετε έναν σύνδεσμο όπως:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

Για να βρείτε τον κώδικα που θα εκτελείται στην Εφαρμογή, μεταβείτε στην δραστηριότητα που καλείται από το deeplink και αναζητήστε τη συνάρτηση onNewIntent.

Μάθετε πώς να καλείτε deep links χωρίς να χρησιμοποιείτε σελίδες HTML.

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.

Συστατικά

Αυτά περιλαμβάνουν: Δραστηριότητες, Υπηρεσίες, Δέκτες Εκπομπών και Παρόχους.

Δραστηριότητα Εκκίνησης και άλλες δραστηριότητες

Στις εφαρμογές Android, οι δραστηριότητες είναι σαν οθόνες, που δείχνουν διάφορα μέρη της διεπαφής χρήστη της εφαρμογής. Μια εφαρμογή μπορεί να έχει πολλές δραστηριότητες, καθεμία από τις οποίες παρουσιάζει μια μοναδική οθόνη στον χρήστη.

Η δραστηριότητα εκκίνησης είναι η κύρια πύλη σε μια εφαρμογή, που εκκινείται όταν πατάτε το εικονίδιο της εφαρμογής. Είναι καθορισμένη στο αρχείο μανιφέστ της εφαρμογής με συγκεκριμένα MAIN και LAUNCHER intents:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Όχι όλες οι εφαρμογές χρειάζονται μια δραστηριότητα εκκίνησης, ειδικά αυτές χωρίς διεπαφή χρήστη, όπως οι υπηρεσίες φόντου.

Οι δραστηριότητες μπορούν να γίνουν διαθέσιμες σε άλλες εφαρμογές ή διαδικασίες σημειώνοντάς τες ως "exported" στο μανιφέστο. Αυτή η ρύθμιση επιτρέπει σε άλλες εφαρμογές να ξεκινούν αυτή τη δραστηριότητα:

<service android:name=".ExampleExportedService" android:exported="true"/>

Ωστόσο, η πρόσβαση σε μια δραστηριότητα από άλλη εφαρμογή δεν είναι πάντα κίνδυνος ασφαλείας. Η ανησυχία προκύπτει αν ευαίσθητα δεδομένα μοιράζονται ακατάλληλα, κάτι που θα μπορούσε να οδηγήσει σε διαρροές πληροφοριών.

Ο κύκλος ζωής μιας δραστηριότητας ξεκινά με τη μέθοδο onCreate, ρυθμίζοντας το UI και προετοιμάζοντας τη δραστηριότητα για αλληλεπίδραση με τον χρήστη.

Υποκλάση Εφαρμογής

Στην ανάπτυξη Android, μια εφαρμογή έχει την επιλογή να δημιουργήσει μια υποκλάση της Application κλάσης, αν και δεν είναι υποχρεωτικό. Όταν οριστεί μια τέτοια υποκλάση, γίνεται η πρώτη κλάση που θα δημιουργηθεί μέσα στην εφαρμογή. Η μέθοδος attachBaseContext, αν υλοποιηθεί σε αυτή την υποκλάση, εκτελείται πριν από τη μέθοδο onCreate. Αυτή η ρύθμιση επιτρέπει την πρώιμη αρχικοποίηση πριν ξεκινήσει το υπόλοιπο της εφαρμογής.

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
}
}

Υπηρεσίες

Υπηρεσίες είναι λειτουργίες παρασκηνίου ικανές να εκτελούν εργασίες χωρίς διεπαφή χρήστη. Αυτές οι εργασίες μπορούν να συνεχίσουν να εκτελούνται ακόμη και όταν οι χρήστες αλλάζουν σε διαφορετικές εφαρμογές, καθιστώντας τις υπηρεσίες κρίσιμες για μακροχρόνιες λειτουργίες.

Οι υπηρεσίες είναι ευέλικτες; μπορούν να ξεκινήσουν με διάφορους τρόπους, με τις Intents να είναι η κύρια μέθοδος για την εκκίνηση τους ως σημείο εισόδου μιας εφαρμογής. Μόλις ξεκινήσει μια υπηρεσία χρησιμοποιώντας τη μέθοδο startService, η μέθοδος onStart ενεργοποιείται και συνεχίζει να εκτελείται μέχρι να κληθεί ρητά η μέθοδος stopService. Εναλλακτικά, εάν ο ρόλος μιας υπηρεσίας εξαρτάται από μια ενεργή σύνδεση πελάτη, χρησιμοποιείται η μέθοδος bindService για τη σύνδεση του πελάτη με την υπηρεσία, ενεργοποιώντας τη μέθοδο onBind για τη μεταφορά δεδομένων.

Μια ενδιαφέρουσα εφαρμογή των υπηρεσιών περιλαμβάνει την αναπαραγωγή μουσικής παρασκηνίου ή την ανάκτηση δεδομένων δικτύου χωρίς να εμποδίζεται η αλληλεπίδραση του χρήστη με μια εφαρμογή. Επιπλέον, οι υπηρεσίες μπορούν να γίνουν προσβάσιμες σε άλλες διεργασίες στην ίδια συσκευή μέσω εξαγωγής. Αυτή δεν είναι η προεπιλεγμένη συμπεριφορά και απαιτεί ρητή ρύθμιση στο αρχείο Android Manifest:

<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 που δείχνουν στις ρυθμίσεις φακέλων. Συνιστάται προσοχή κατά την κοινή χρήση καταλόγων για να αποφευχθεί η τυχαία έκθεση ευαίσθητων δεδομένων.

Παράδειγμα δήλωσης manifest για FileProvider:

<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:

<paths>
<files-path path="images/" name="myimages" />
</paths>

Για περισσότερες πληροφορίες ελέγξτε:

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 για να διαχειρίζονται και να ασφαλίζουν αποτελεσματικά τις κινητές συσκευές. Οι βασικές λειτουργίες περιλαμβάνουν επιβολή πολιτικών κωδικών πρόσβασης, υποχρεωτική κρυπτογράφηση αποθήκευσης, και άδεια απομακρυσμένης διαγραφής δεδομένων, διασφαλίζοντας πλήρη έλεγχο και ασφάλεια πάνω στις κινητές συσκευές.

// 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);
}
Υποστήριξη HackTricks

Last updated