Repository navigation
Expand file tree
/
Copy pathduckyshell.py
More file actions
192 lines (159 loc) · 6.38 KB
/
Copy pathduckyshell.py
File metadata and controls
192 lines (159 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/usr/bin/env python3
import cmd
import subprocess
import os
import yaml
import glob
import re
# Config file path
CONFIG_FILE_PATH = "/usr/bin/duckyshell/config.yaml"
# Class for the CLI program
class DuckyShell(cmd.Cmd):
# Clears the screen
os.system(f"clear")
# Prints out the intro
intro = "\nHak5 USB Rubber Ducky CLI\n\nType 'help' to list available commands or 'help <command>' to get help for a specific command.\n"
# Prompt for the CLI
prompt = "ducky_sh3ll > "
# Setting the usb path to None for now
usb_path = None
file_path = None
def __init__(self):
super().__init__()
self.load_usb_path()
# Help messages for each command
help_messages = {
'usb': 'Set the USB path for connected USB devices.',
'file': 'Set the file to the designated inject.bin you want.',
'list': 'List the connected USB devices.',
'run': 'Copy the inject.bin to the USB Rubber Ducky.',
'quit': 'Exit the DuckyShell.',
'exit': 'Exit the DuckyShell.',
}
# Function for setting the usb path
def load_usb_path(self):
# Load the USB path from the config file
if os.path.exists(CONFIG_FILE_PATH):
with open(CONFIG_FILE_PATH, 'r') as config_file:
config = yaml.safe_load(config_file)
self.usb_path = config.get('usb_path')
# Function for saving the usb path
def save_usb_path(self):
# Save the USB path to the config file
config = {'usb_path': self.usb_path}
with open(CONFIG_FILE_PATH, 'w') as config_file:
yaml.safe_dump(config, config_file)
# Tab autocomplete for file function
def complete_file(self, text, line, begidx, endidx):
# Get a list of files and directories in the current directory
current_dir = os.getcwd()
files_and_dirs = os.listdir(current_dir)
# Filter the list based on the current text being entered
options = [entry for entry in files_and_dirs if entry.startswith(text)]
return options
# Tab autocomplete for usb function
def complete_usb(self, text, line, begidx, endidx):
# Get a list of files and directories in the current directory
current_dir = os.getcwd()
files_and_dirs = os.listdir(current_dir)
# Filter the list based on the current text being entered
options = [entry for entry in files_and_dirs if entry.startswith(text)]
# Returning results
return options
# Function to only select connected usb devices
def get_connected_usb_devices(self):
devices = glob.glob('/dev/sd*[!0-9]')
return [os.path.basename(device) for device in devices]
# Function for copying the file to the usb
def do_run(self, arg):
# Check for USB path provided
if not self.usb_path:
print("USB path not provided. Use 'set_usb_path' command to set it.")
return
# Check for file path provided
if not self.file_path:
print("File path not provided. Use 'set_file_path' command to set it.")
return
# Check if the file is a binary file
if not self.file_path.endswith('.bin'):
print(f"Invalid file type: {self.file_path} is not a text file (.txt)")
return
# Copy the binary file to the USB Rubber Ducky
os.system(f"cp {self.file_path} {self.usb_path}")
print(f"File copied to USB drive: {self.usb_path}")
# Delete the temporary text file
os.remove(self.file_path)
# Set the USB path for connected USB devices
def do_usb(self, line):
usb_path = line.strip()
# Check if the USB device is connected
usb_devices = [device[0] for device in self.get_connected_usb_devices()]
if usb_path not in usb_devices:
print("USB device is not connected.")
return
# Set the USB path for future commands
self.usb_path = usb_path
self.save_usb_path()
print(f"USB path set to: {usb_path}")
# Set file to the designated file you want
def do_file(self, line):
file_path = line.strip()
# Check if the file path exists
if not os.path.exists(file_path):
print("File path does not exist.")
return
# Check if the file path has the correct extension
if not re.match(r"inject.bin", file_path):
print("Invalid file format. Only 'inject.bin' files are allowed.")
return
# Set the file path for future copy operations
self.file_path = file_path
print(f"File path set to: {file_path}")
# Listing the connected USB devices
def do_list(self, arg):
output = subprocess.check_output(['lsblk', '-o', 'NAME,MODEL', '-n', '-l']).decode('utf-8').strip()
lines = output.split('\n')
devices = [line.split() for line in lines]
usb_devices = [device for device in devices if device and (device[0].startswith('sd') or device[0].startswith('hd'))]
if usb_devices:
print("Connected USB devices:")
for device in usb_devices:
if len(device) >= 2:
print(f"Name: {device[0]} Model: {device[1]}")
else:
print(f"Name: {device[0]} Model: Unknown")
else:
print("No USB devices found.")
def emptyline(self):
pass
def do_help(self, arg):
"""
List available commands with their usage.
Usage: help [command]
"""
if arg:
# Show help for a specific command
if arg in self.help_messages:
print(self.help_messages[arg])
else:
print(f"Command '{arg}' not found.")
else:
# Show help for all commands
print("\nAvailable commands:")
for command, help_message in self.help_messages.items():
print(f"{command}: {help_message}")
print("\n")
# Exit command 1
def do_quit(self, arg):
# Exit the DuckyShell
print("Exiting DuckyShell...")
return True
# Exit command 2
def do_exit(self, arg):
# Exit the DuckyShell
print("\nExiting DuckyShell...\n")
return True
# Function for running the program
if __name__ == '__main__':
shell = DuckyShell()
shell.cmdloop()