macOS Thread Injection via Task port
Reading time: 8 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Code
- https://github.com/bazad/threadexec
- https://gist.github.com/knightsc/bd6dfeccb02b77eb6409db5601dcef36
1. Thread Hijacking
Αρχικά, η συνάρτηση task_threads()
καλείται στην θύρα εργασίας για να αποκτήσει μια λίστα νημάτων από την απομακρυσμένη εργασία. Ένα νήμα επιλέγεται για κατάληψη. Αυτή η προσέγγιση αποκλίνει από τις συμβατικές μεθόδους εισαγωγής κώδικα, καθώς η δημιουργία ενός νέου απομακρυσμένου νήματος απαγορεύεται λόγω της μείωσης που μπλοκάρει το thread_create_running()
.
Για να ελεγχθεί το νήμα, καλείται το thread_suspend()
, σταματώντας την εκτέλεσή του.
Οι μόνοι επιτρεπόμενοι χειρισμοί στο απομακρυσμένο νήμα περιλαμβάνουν σταμάτημα και εκκίνηση του και ανάκτηση/τροποποίηση των τιμών των καταχωρητών του. Οι απομακρυσμένες κλήσεις συναρτήσεων ξεκινούν με την ρύθμιση των καταχωρητών x0
έως x7
στις παραμέτρους, ρυθμίζοντας το pc
για να στοχεύσει τη επιθυμητή συνάρτηση και επαναφέροντας το νήμα. Η διασφάλιση ότι το νήμα δεν θα καταρρεύσει μετά την επιστροφή απαιτεί ανίχνευση της επιστροφής.
Μια στρατηγική περιλαμβάνει την καταχώρηση ενός χειριστή εξαίρεσης για το απομακρυσμένο νήμα χρησιμοποιώντας το thread_set_exception_ports()
, ρυθμίζοντας τον καταχωρητή lr
σε μια μη έγκυρη διεύθυνση πριν από την κλήση της συνάρτησης. Αυτό προκαλεί μια εξαίρεση μετά την εκτέλεση της συνάρτησης, στέλνοντας ένα μήνυμα στην θύρα εξαίρεσης, επιτρέποντας την επιθεώρηση της κατάστασης του νήματος για την ανάκτηση της τιμής επιστροφής. Εναλλακτικά, όπως υιοθετήθηκε από την εκμετάλλευση triple_fetch του Ian Beer, το lr
ρυθμίζεται να επαναλαμβάνεται άπειρα; οι καταχωρητές του νήματος παρακολουθούνται συνεχώς μέχρι το pc
να δείχνει σε αυτή την εντολή.
2. Mach ports for communication
Η επόμενη φάση περιλαμβάνει την εγκαθίδρυση Mach ports για να διευκολύνει την επικοινωνία με το απομακρυσμένο νήμα. Αυτές οι θύρες είναι καθοριστικές για τη μεταφορά αυθαίρετων δικαιωμάτων αποστολής/λήψης μεταξύ εργασιών.
Για αμφίδρομη επικοινωνία, δημιουργούνται δύο δικαιώματα λήψης Mach: ένα στην τοπική και το άλλο στην απομακρυσμένη εργασία. Στη συνέχεια, ένα δικαίωμα αποστολής για κάθε θύρα μεταφέρεται στην αντίστοιχη εργασία, επιτρέποντας την ανταλλαγή μηνυμάτων.
Εστιάζοντας στην τοπική θύρα, το δικαίωμα λήψης κατέχεται από την τοπική εργασία. Η θύρα δημιουργείται με το mach_port_allocate()
. Η πρόκληση έγκειται στη μεταφορά ενός δικαιώματος αποστολής σε αυτή τη θύρα στην απομακρυσμένη εργασία.
Μια στρατηγική περιλαμβάνει την εκμετάλλευση του thread_set_special_port()
για να τοποθετήσει ένα δικαίωμα αποστολής στην τοπική θύρα στο THREAD_KERNEL_PORT
του απομακρυσμένου νήματος. Στη συνέχεια, το απομακρυσμένο νήμα καθοδηγείται να καλέσει το mach_thread_self()
για να ανακτήσει το δικαίωμα αποστολής.
Για την απομακρυσμένη θύρα, η διαδικασία είναι ουσιαστικά αντίστροφη. Το απομακρυσμένο νήμα καθοδηγείται να δημιουργήσει μια θύρα Mach μέσω του mach_reply_port()
(καθώς το mach_port_allocate()
δεν είναι κατάλληλο λόγω του μηχανισμού επιστροφής του). Μετά τη δημιουργία της θύρας, καλείται το mach_port_insert_right()
στο απομακρυσμένο νήμα για να καθιερώσει ένα δικαίωμα αποστολής. Αυτό το δικαίωμα αποθηκεύεται στη μνήμη χρησιμοποιώντας το thread_set_special_port()
. Επιστρέφοντας στην τοπική εργασία, χρησιμοποιείται το thread_get_special_port()
στο απομακρυσμένο νήμα για να αποκτήσει ένα δικαίωμα αποστολής στη νεοδημιουργημένη θύρα Mach στην απομακρυσμένη εργασία.
Η ολοκλήρωση αυτών των βημάτων έχει ως αποτέλεσμα την εγκαθίδρυση Mach ports, θέτοντας τα θεμέλια για αμφίδρομη επικοινωνία.
3. Basic Memory Read/Write Primitives
Σε αυτή την ενότητα, η προσοχή εστιάζεται στη χρήση του εκτελέσιμου πρωτοκόλλου για την εγκαθίδρυση βασικών πρωτοκόλλων ανάγνωσης/εγγραφής μνήμης. Αυτά τα αρχικά βήματα είναι κρίσιμα για την απόκτηση περισσότερου ελέγχου πάνω στη απομακρυσμένη διαδικασία, αν και τα πρωτόκολλα σε αυτό το στάδιο δεν θα εξυπηρετήσουν πολλούς σκοπούς. Σύντομα, θα αναβαθμιστούν σε πιο προηγμένες εκδόσεις.
Memory reading and writing using the execute primitive
Ο στόχος είναι να εκτελούνται αναγνώσεις και εγγραφές μνήμης χρησιμοποιώντας συγκεκριμένες συναρτήσεις. Για ανάγνωση μνήμης:
uint64_t read_func(uint64_t *address) {
return *address;
}
Για γραφή μνήμης:
void write_func(uint64_t *address, uint64_t value) {
*address = value;
}
Αυτές οι συναρτήσεις αντιστοιχούν στην παρακάτω συναρμολόγηση:
_read_func:
ldr x0, [x0]
ret
_write_func:
str x1, [x0]
ret
Αναγνώριση κατάλληλων συναρτήσεων
Μια σάρωση κοινών βιβλιοθηκών αποκάλυψε κατάλληλους υποψηφίους για αυτές τις λειτουργίες:
- Ανάγνωση μνήμης —
property_getName()
(libobjc):
const char *property_getName(objc_property_t prop) {
return prop->name;
}
- Γράφοντας μνήμη —
_xpc_int64_set_value()
(libxpc):
__xpc_int64_set_value:
str x1, [x0, #0x18]
ret
Για να εκτελέσετε μια εγγραφή 64-bit σε μια αυθαίρετη διεύθυνση:
_xpc_int64_set_value(address - 0x18, value);
Με αυτές τις βασικές αρχές καθορισμένες, η σκηνή είναι έτοιμη για τη δημιουργία κοινής μνήμης, σηματοδοτώντας μια σημαντική πρόοδο στον έλεγχο της απομακρυσμένης διαδικασίας.
4. Ρύθμιση Κοινής Μνήμης
Ο στόχος είναι να καθιερωθεί κοινή μνήμη μεταξύ τοπικών και απομακρυσμένων εργασιών, απλοποιώντας τη μεταφορά δεδομένων και διευκολύνοντας την κλήση συναρτήσεων με πολλαπλά επιχειρήματα. Η προσέγγιση εκμεταλλεύεται το libxpc
και τον τύπο αντικειμένου OS_xpc_shmem
, ο οποίος βασίζεται σε καταχωρήσεις μνήμης Mach.
Επισκόπηση Διαδικασίας
- Κατανομή μνήμης
- Κατανομή μνήμης για κοινή χρήση χρησιμοποιώντας
mach_vm_allocate()
. - Χρησιμοποιήστε
xpc_shmem_create()
για να δημιουργήσετε ένα αντικείμενοOS_xpc_shmem
για την κατανεμημένη περιοχή.
- Δημιουργία κοινής μνήμης στην απομακρυσμένη διαδικασία
- Κατανομή μνήμης για το αντικείμενο
OS_xpc_shmem
στην απομακρυσμένη διαδικασία (remote_malloc
). - Αντιγράψτε το τοπικό αντικείμενο πρότυπο; απαιτείται ακόμα διόρθωση του ενσωματωμένου δικαιώματος αποστολής Mach στη θέση
0x18
.
- Διόρθωση της καταχώρησης μνήμης Mach
- Εισάγετε ένα δικαίωμα αποστολής με
thread_set_special_port()
και αντικαταστήστε το πεδίο0x18
με το όνομα της απομακρυσμένης καταχώρησης.
- Ολοκλήρωση
- Επικυρώστε το απομακρυσμένο αντικείμενο και χαρτογραφήστε το με μια απομακρυσμένη κλήση στο
xpc_shmem_remote()
.
5. Επίτευξη Πλήρους Ελέγχου
Μόλις είναι διαθέσιμη η αυθαίρετη εκτέλεση και ένα κανάλι πίσω κοινής μνήμης, κατέχετε αποτελεσματικά τη διαδικασία στόχο:
- Αυθαίρετη R/W μνήμη — χρησιμοποιήστε
memcpy()
μεταξύ τοπικών και κοινών περιοχών. - Κλήσεις συναρτήσεων με > 8 επιχειρήματα — τοποθετήστε τα επιπλέον επιχειρήματα στη στοίβα σύμφωνα με τη σύμβαση κλήσης arm64.
- Μεταφορά δικαιωμάτων Mach — περάστε δικαιώματα σε μηνύματα Mach μέσω των καθιερωμένων θυρών.
- Μεταφορά περιγραφέων αρχείων — εκμεταλλευτείτε τα fileports (βλ. triple_fetch).
Όλα αυτά είναι περιτυλιγμένα στη βιβλιοθήκη threadexec
για εύκολη επαναχρησιμοποίηση.
6. Ιδιαιτερότητες Apple Silicon (arm64e)
Σε συσκευές Apple Silicon (arm64e) Κωδικοί Αυθεντικοποίησης Δεικτών (PAC) προστατεύουν όλες τις διευθύνσεις επιστροφής και πολλούς δείκτες συναρτήσεων. Οι τεχνικές κατάληψης νήματος που επανχρησιμοποιούν υπάρχον κώδικα συνεχίζουν να λειτουργούν επειδή οι αρχικές τιμές στα lr
/pc
φέρουν ήδη έγκυρες υπογραφές PAC. Προβλήματα προκύπτουν όταν προσπαθείτε να μεταβείτε σε μνήμη που ελέγχεται από τον επιτιθέμενο:
- Κατανομή εκτελέσιμης μνήμης μέσα στον στόχο (απομακρυσμένο
mach_vm_allocate
+mprotect(PROT_EXEC)
). - Αντιγράψτε το payload σας.
- Μέσα στη απομακρυσμένη διαδικασία υπογράψτε τον δείκτη:
uint64_t ptr = (uint64_t)payload;
ptr = ptrauth_sign_unauthenticated((void*)ptr, ptrauth_key_asia, 0);
- Ορίστε
pc = ptr
στην κατάσταση του καταληφθέντος νήματος.
Εναλλακτικά, παραμείνετε συμβατοί με το PAC αλυσσοδεσμεύοντας υπάρχοντα gadgets/functions (παραδοσιακό ROP).
7. Ανίχνευση & Σκληροποίηση με το EndpointSecurity
Το EndpointSecurity (ES) πλαίσιο εκθέτει γεγονότα πυρήνα που επιτρέπουν στους υπερασπιστές να παρακολουθούν ή να μπλοκάρουν τις απόπειρες έγχυσης νημάτων:
ES_EVENT_TYPE_AUTH_GET_TASK
– ενεργοποιείται όταν μια διαδικασία ζητά την θύρα άλλου έργου (π.χ.task_for_pid()
).ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE
– εκπέμπεται κάθε φορά που δημιουργείται ένα νήμα σε διαφορετικό έργο.ES_EVENT_TYPE_NOTIFY_THREAD_SET_STATE
(προστέθηκε στο macOS 14 Sonoma) – υποδεικνύει την χειρισμό καταχωρητών ενός υπάρχοντος νήματος.
Ελάχιστος πελάτης Swift που εκτυπώνει γεγονότα απομακρυσμένου νήματος:
import EndpointSecurity
let client = try! ESClient(subscriptions: [.notifyRemoteThreadCreate]) {
(_, msg) in
if let evt = msg.remoteThreadCreate {
print("[ALERT] remote thread in pid \(evt.target.pid) by pid \(evt.thread.pid)")
}
}
RunLoop.main.run()
Ερώτηση με osquery ≥ 5.8:
SELECT target_pid, source_pid, target_path
FROM es_process_events
WHERE event_type = 'REMOTE_THREAD_CREATE';
Σκέψεις για σκληρυμένο χρόνο εκτέλεσης
Η διανομή της εφαρμογής σας χωρίς την επιλεξιμότητα com.apple.security.get-task-allow
αποτρέπει τους μη ριζικούς επιτιθέμενους από το να αποκτήσουν το task-port της. Η Προστασία Ακεραιότητας Συστήματος (SIP) εξακολουθεί να μπλοκάρει την πρόσβαση σε πολλές δυαδικές εφαρμογές της Apple, αλλά το λογισμικό τρίτων πρέπει να επιλέξει ρητά να εξαιρεθεί.
8. Πρόσφατα Δημόσια Εργαλεία (2023-2025)
Εργαλείο | Έτος | Σημειώσεις |
---|---|---|
task_vaccine | 2023 | Συμπαγές PoC που δείχνει την εκτροπή νήματος με γνώση PAC σε Ventura/Sonoma |
remote_thread_es | 2024 | Βοηθητικό πρόγραμμα EndpointSecurity που χρησιμοποιείται από αρκετούς προμηθευτές EDR για την εμφάνιση γεγονότων REMOTE_THREAD_CREATE |
Η ανάγνωση του πηγαίου κώδικα αυτών των έργων είναι χρήσιμη για την κατανόηση των αλλαγών API που εισήχθησαν στο macOS 13/14 και για να παραμείνετε συμβατοί μεταξύ Intel ↔ Apple Silicon.
Αναφορές
- https://bazad.github.io/2018/10/bypassing-platform-binary-task-threads/
- https://github.com/rodionovd/task_vaccine
- https://developer.apple.com/documentation/endpointsecurity/es_event_type_notify_remote_thread_create
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.