Updated BlueDucky.py

Added Bluetooth Debugging before UI is accessed, along with some other changes, and handling.
This commit is contained in:
Charles Johnson 2024-05-15 18:13:53 -05:00 committed by GitHub
parent 90a7850fe9
commit 2b9c4bd373
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 75 additions and 15 deletions

View File

@ -2,6 +2,7 @@ import binascii, bluetooth, sys, time, datetime, logging, argparse
from multiprocessing import Process
from pydbus import SystemBus
from enum import Enum
import subprocess
import os
from utils.menu_functions import (main_menu, read_duckyscript, run, restart_bluetooth_daemon, get_target_address)
@ -15,8 +16,6 @@ class AnsiColorCode:
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
RESET = '\033[0m'
@ -30,8 +29,8 @@ class ColorLogFormatter(logging.Formatter):
logging.INFO: AnsiColorCode.GREEN,
logging.WARNING: AnsiColorCode.YELLOW,
logging.ERROR: AnsiColorCode.RED,
logging.CRITICAL: AnsiColorCode.MAGENTA,
NOTICE_LEVEL: AnsiColorCode.CYAN, # Color for NOTICE level
logging.CRITICAL: AnsiColorCode.RED,
NOTICE_LEVEL: AnsiColorCode.BLUE, # Color for NOTICE level
}
def format(self, record):
@ -268,9 +267,20 @@ class L2CAPClient:
self.connected = True
log.debug("SUCCESS! connected on port %d" % self.port)
except Exception as ex:
# Color Definition Again just to avoid errors I should've made a class for this.
red = "\033[91m"
blue = "\033[94m"
reset = "\033[0m"
error = True
self.connected = False
log.error("ERROR connecting on port %d: %s" % (self.port, ex))
raise ConnectionFailureException(f"Connection failure on port {self.port}")
if (error == True & self.port == 14):
print("{reset}[{red}!{reset}] {red}CRITICAL ERROR{reset}: {reset}Attempted Connection to {red}{target_address} {reset}was {red}denied{reset}.")
return self.connected
return self.connected
@ -595,6 +605,7 @@ def terminate_child_processes():
proc.terminate()
proc.join()
def setup_bluetooth(target_address, adapter_id):
restart_bluetooth_daemon()
profile_proc = Process(target=register_hid_profile, args=(adapter_id, target_address))
@ -626,8 +637,39 @@ def setup_and_connect(connection_manager, target_address, adapter_id):
establish_connections(connection_manager)
return connection_manager.clients[19]
def troubleshoot_bluetooth():
# Added this function to troubleshoot common issues before access to the application is granted
blue = "\033[0m"
red = "\033[91m"
reset = "\033[0m"
# Check if bluetoothctl is available
try:
subprocess.run(['bluetoothctl', '--version'], check=True, stdout=subprocess.PIPE)
except subprocess.CalledProcessError:
print("{reset}[{red}!{reset}] {red}CRITICAL{reset}: {blue}bluetoothctl {reset}is not installed or not working properly.")
return False
# Check for Bluetooth adapters
result = subprocess.run(['bluetoothctl', 'list'], capture_output=True, text=True)
if "Controller" not in result.stdout:
print("{reset}[{red}!{reset}] {red}CRITICAL{reset}: No {blue}Bluetooth adapters{reset} have been detected.")
return False
# List devices to see if any are connected
result = subprocess.run(['bluetoothctl', 'devices'], capture_output=True, text=True)
if "Device" not in result.stdout:
print("{reset}[{red}!{reset}] {red}CRITICAL{reset}: No Compatible {blue}Bluetooth devices{reset} are connected.")
return False
# if no issues are found then continue
return True
# Main function
def main():
blue = "\033[0m"
red = "\033[91m"
reset = "\033[0m"
parser = argparse.ArgumentParser(description="Bluetooth HID Attack Tool")
parser.add_argument('--adapter', type=str, default='hci0', help='Specify the Bluetooth adapter to use (default: hci0)')
args = parser.parse_args()
@ -636,31 +678,38 @@ def main():
main_menu()
target_address = get_target_address()
if not target_address:
log.info("No target address provided. Exiting.")
log.info("No target address provided. Exiting..")
return
script_directory = os.path.dirname(os.path.realpath(__file__))
payload_folder = os.path.join(script_directory, 'payloads/') # Specify the relative path to the payloads folder.
payloads = os.listdir(payload_folder)
print("\nAvailable payloads:")
blue = "\033[0m"
red = "\033[91m"
reset = "\033[0m"
print(f"\nAvailable payloads{blue}:")
for idx, payload_file in enumerate(payloads, 1): # Check and enumerate the files inside the payload folder.
print(f"{idx}: {payload_file}")
print(f"{reset}[{blue}{idx}{reset}]{blue}: {blue}{payload_file}")
payload_choice = input("\nEnter the number of the payload you want to load: ")
blue = "\033[0m"
red = "\033[91m"
reset = "\033[0m"
payload_choice = input(f"\n{blue}Enter the number that represents the payload you would like to load{white}: {blue}")
selected_payload = None
try:
payload_index = int(payload_choice) - 1
selected_payload = os.path.join(payload_folder, payloads[payload_index])
except (ValueError, IndexError):
print("Invalid payload choice. No payload selected.")
print(f"Invalid payload choice. No payload selected.")
if selected_payload is not None:
print(f"Selected payload: {selected_payload}")
print(f"{blue}Selected payload{reset}: {blue}{selected_payload}")
duckyscript = read_duckyscript(selected_payload)
else:
print("No payload selected.")
print(f"{red}No payload selected.")
if not duckyscript:
@ -680,20 +729,31 @@ def main():
process_duckyscript(hid_interrupt_client, duckyscript, current_line, current_position)
time.sleep(2)
break # Exit loop if successful
except ReconnectionRequiredException as e:
log.info("Reconnection required. Attempting to reconnect...")
log.info(f"{reset}Reconnection required. Attempting to reconnect{blue}...")
current_line = e.current_line
current_position = e.current_position
connection_manager.close_all()
# Sleep before retrying to avoid rapid reconnection attempts
time.sleep(2)
#process_duckyscript(hid_interrupt_client, duckyscript)
finally:
# unpair the target device
blue = "\033[94m"
reset = "\033[0m"
command = f'echo -e "remove {target_address}\n" | bluetoothctl'
subprocess.run(command, shell=True)
print(f"{blue}Successfully Removed device{reset}: {blue}{target_address}{reset}")
if __name__ == "__main__":
setup_logging()
log = logging.getLogger(__name__)
try:
main()
if troubleshoot_bluetooth():
main()
else:
sys.exit(0)
finally:
terminate_child_processes()