hacktricks/linux-hardening/bypass-bash-restrictions/bypass-fs-protections-read-only-no-exec-distroless/ddexec.md
Translator workflow 35c6b081d2 Translated to Greek
2024-02-10 22:40:18 +00:00

12 KiB
Raw Blame History

DDexec / EverythingExec

Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Πλαίσιο

Στο Linux, για να εκτελεστεί ένα πρόγραμμα πρέπει να υπάρχει ως ένα αρχείο, πρέπει να είναι προσβάσιμο με κάποιον τρόπο μέσω της ιεραρχίας του συστήματος αρχείων (αυτό είναι ακριβώς πώς λειτουργεί η execve()). Αυτό το αρχείο μπορεί να βρίσκεται στον δίσκο ή στη μνήμη (tmpfs, memfd), αλλά χρειάζεστε ένα διαδρομή αρχείου. Αυτό έχει καταστήσει πολύ εύκολο τον έλεγχο του τι εκτελείται σε ένα σύστημα Linux, καθιστά εύκολη την ανίχνευση απειλών και εργαλείων του εισβολέα ή την αποτροπή τους από το να προσπαθήσουν να εκτελέσουν οτιδήποτε δικό τους (π.χ. να μην επιτρέπεται σε μη προνομιούχους χρήστες να τοποθετούν εκτελέσιμα αρχεία οπουδήποτε).

Αλλά αυτή η τεχνική είναι εδώ για να αλλάξει όλα αυτά. Εάν δεν μπορείτε να ξεκινήσετε τη διεργασία που θέλετε... τότε καταλαμβάνετε μία ήδη υπάρχουσα.

Αυτή η τεχνική σας επιτρέπει να παρακάμψετε κοινές τεχνικές προστασίας όπως το read-only, noexec, λευκή λίστα ονομάτων αρχείων, λευκή λίστα κατακερματισμού...

Εξαρτήσεις

Το τελικό σενάριο εξαρτάται από τα παρακάτω εργαλεία για να λειτουργήσει, πρέπει να είναι προσβάσιμα στο σύστημα που επιτίθεστε (από προεπιλογή θα τα βρείτε παντού):

dd
bash | zsh | ash (busybox)
head
tail
cut
grep
od
readlink
wc
tr
base64

Η τεχνική

Εάν μπορείτε να τροποποιήσετε αυθαίρετα τη μνήμη ενός διεργασίας, τότε μπορείτε να την αναλάβετε. Αυτό μπορεί να χρησιμοποιηθεί για να αποκτήσετε τον έλεγχο ενός ήδη υπάρχοντος διεργασίας και να τον αντικαταστήσετε με ένα άλλο πρόγραμμα. Μπορούμε να επιτύχουμε αυτό είτε χρησιμοποιώντας την κλήση συστήματος ptrace() (η οποία απαιτεί να έχετε τη δυνατότητα εκτέλεσης κλήσεων συστήματος ή να έχετε το gdb διαθέσιμο στο σύστημα) ή, πιο ενδιαφέροντα, εγγράφοντας στο /proc/$pid/mem.

Το αρχείο /proc/$pid/mem είναι ένας αντιστοιχισμένος ένα προς ένα χάρτης του πλήρους χώρου διευθύνσεων μιας διεργασίας (π.χ. από 0x0000000000000000 έως 0x7ffffffffffff000 σε x86-64). Αυτό σημαίνει ότι η ανάγνωση ή η εγγραφή σε αυτό το αρχείο σε μια θέση x είναι το ίδιο με την ανάγνωση ή την τροποποίηση του περιεχομένου στην εικονική διεύθυνση x.

Τώρα, έχουμε τέσσερα βασικά προβλήματα που πρέπει να αντιμετωπίσουμε:

  • Γενικά, μόνο ο ριζικός χρήστης και ο ιδιοκτήτης του αρχείου μπορούν να το τροποποιήσουν.
  • ASLR.
  • Εάν προσπαθήσουμε να διαβάσουμε ή να γράψουμε σε μια διεύθυνση που δεν έχει αντιστοιχιστεί στον χώρο διευθύνσεων του προγράμματος, θα λάβουμε ένα σφάλμα εισόδου/εξόδου.

Αυτά τα προβλήματα έχουν λύσεις που, αν και δεν είναι τέλειες, είναι καλές:

  • Οι περισσότεροι διερμηνείς κελύφους επιτρέπουν τη δημιουργία περιγραφέων αρχείων που θα κληρονομηθούν από διεργασίες-παιδιά. Μπορούμε να δημιουργήσουμε έναν περιγραφέα αρχείου που δείχνει στο αρχείο mem του κελύφους με δικαιώματα εγγραφής... έτσι, οι διεργασίες-παιδιά που χρησιμοποιούν αυτόν τον περιγραφέα αρχείου θα μπορούν να τροποποιήσουν τη μνήμη του κελύφους.
  • Το ASLR δεν είναι κανένα πρόβλημα, μπορούμε να ελέγξουμε το αρχείο maps του κελύφους ή οποιοδήποτε άλλο αρχείο από το procfs για να αποκτήσουμε πληροφορίες σχετικά με τον χώρο διευθύνσεων της διεργασίας.
  • Έτσι, πρέπει να κάνουμε lseek() στο αρχείο. Από το κελύφος αυτό δεν μπορεί να γίνει εκτός αν χρησιμοποιήσουμε τον περίφημο dd.

Περισσότερες λεπτομέρειες

Τα βήματα είναι σχετικά εύκολα και δεν απαιτούν καμία ειδική γνώση για να τα κατανοήσετε:

  • Αναλύστε το δυαδικό που θέλουμε να εκτελέσουμε και τον φορτωτή για να βρούμε ποιους χάρτες χρειάζονται. Στη συνέχεια, δημιουργήστε έναν "κώδικα κελύφους" που θα εκτελέσει, γενικά, τα ίδια βήματα που κάνει το πυρήνας κατά την κλήση execve():
  • Δημιουργήστε τους χάρτες αυτούς.
  • Διαβάστε τα δυαδικά αρχεία σε αυτούς.
  • Ρυθμίστε τα δικαιώματα.
  • Τέλος, αρχικοποιήστε τη στοίβα με τα ορίσματα για το πρόγραμμα και τοποθετήστε τον βοηθητικό διάνυσμα (απαραίτητο από τον φορτωτή).
  • Μεταβείτε στον φορτωτή και αφήστε τον να κάνει τα υπόλοιπα (φόρτωση βιβλιοθηκών που χρειάζεται το πρόγραμμα).
  • Αποκτήστε από το αρχείο syscall τη διεύθυνση στην οποία θα επιστρέψει η διεργασία μετά την κλήση συστήματος που εκτελείται.
  • Αντικαταστήστε αυτήν τη θέση, η οποία θα είναι εκτελέσιμη, με τον κώδικα κελύφους μας (μέσω του mem μπορούμε να τροποποιήσουμε σελίδες που δεν είναι εγγράψιμες).
  • Περάστε το πρόγραμμα που θέλουμε να εκτελέσουμε στην είσοδο της διεργασίας (θα το διαβάσει το εν λόγω "κώδικα κελύφους").
  • Σε αυτό το σημείο, είναι υπόθεση του φορτωτή να φορτώσει τις απαραίτητες βιβλιοθήκες για το πρόγραμμά μας και να μεταβεί σε αυτό.

Ελέγξτε το εργαλείο στο https://github.com/arget13/DDexec

EverythingExec

Υπάρχουν αρκετές εναλλακτικές για το dd, μία από τις οποίες, το tail, είναι αυτήν τη στιγμή το προεπιλεγμένο πρόγραμμα που χρησιμοποιείται για το lseek() μέσω του αρχείου mem (που ήταν ο μοναδικός σκοπός για τον οποίο χρησιμοποιούνταν το dd). Οι εναλλακτικές αυτές είναι:

tail
hexdump
cmp
xxd

Με την ρύθμιση της μεταβλητής SEEKER μπορείτε να αλλάξετε τον ψάκτη που χρησιμοποιείται, π.χ.:

SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Εάν βρείτε έναν άλλο έγκυρο seeker που δεν έχει εφαρμοστεί στο σενάριο, μπορείτε ακόμα να το χρησιμοποιήσετε ορίζοντας τη μεταβλητή SEEKER_ARGS:

SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Φράξτε αυτό, EDRs.

Αναφορές

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks: