Skip to content

Commit 781d87b

Browse files
committed
Added AutoComplete, Version Bump
1 parent 1dcf4a5 commit 781d87b

File tree

3 files changed

+106
-19
lines changed

3 files changed

+106
-19
lines changed

AutoCompleter.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from __future__ import print_function
2+
3+
import sys
4+
import readline
5+
from os import environ
6+
7+
8+
class AutoCompleter(object): # Custom completer
9+
10+
def __init__(self, options, prefix):
11+
self.options = sorted(options)
12+
self.prefix = prefix
13+
14+
def complete(self, text, state):
15+
if state == 0: # on first trigger, build possible matches
16+
if not text:
17+
self.matches = self.options[:]
18+
else:
19+
self.matches = [s for s in self.options
20+
if s and s.startswith(text)]
21+
22+
# return match indexed by state
23+
try:
24+
return self.matches[state]
25+
except IndexError:
26+
return None
27+
28+
def display_matches(self, substitution, matches, longest_match_length):
29+
line_buffer = readline.get_line_buffer()
30+
columns = environ.get("COLUMNS", 80)
31+
32+
print('\n')
33+
34+
tpl = "{:<" + str(int(max(map(len, matches)) * 1.2)) + "}"
35+
36+
buffer = ""
37+
for match in matches:
38+
match = tpl.format(match[len(substitution):])
39+
if len(buffer + match) > columns:
40+
print(buffer)
41+
buffer = ""
42+
buffer += match
43+
44+
if buffer:
45+
print(buffer)
46+
47+
print(self.prefix, end="")
48+
print(line_buffer, end="")
49+
sys.stdout.flush()

PyDuck.py

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
from colorama import init, Fore, Back, Style
88
from tabulate import tabulate
9-
import json, os, output, subprocess, shutil, time, sys
9+
import json, os, output, subprocess, shutil, time, sys, readline
10+
from AutoCompleter import AutoCompleter
1011

1112
modules = []
1213
loadedModule = []
@@ -30,6 +31,23 @@ def loadModules():
3031

3132

3233
def startShell():
34+
#build possible inputs:
35+
possibleInputs = [
36+
'modules',
37+
'cls',
38+
'clear',
39+
'quit',
40+
'exit',
41+
'help'
42+
]
43+
for m in modules:
44+
possibleInputs.append(m)
45+
46+
completer = AutoCompleter(list(set(possibleInputs)), "\n" + Fore.LIGHTCYAN_EX + "pyd> " + Style.RESET_ALL)
47+
readline.set_completer_delims(' \t\n;')
48+
readline.set_completer(completer.complete)
49+
readline.parse_and_bind('tab: complete')
50+
readline.set_completion_display_matches_hook(completer.display_matches)
3351
cmd = input("\n" + Fore.LIGHTCYAN_EX + "pyd> " + Style.RESET_ALL)
3452
handleCommand(cmd)
3553

@@ -40,7 +58,7 @@ def handleCommand(cmd):
4058
if cmd[:4] == "info":
4159
cmdinfo(cmd)
4260
#list modules
43-
elif cmd[:12] == "show modules" and len(cmd) == 12:
61+
elif cmd[:7] == "modules" and len(cmd) == 7:
4462
cmdList()
4563
elif (cmd[:4] == "exit" or cmd[:4] == "quit") and len(cmd) == 4:
4664
output.success('KTHXBYE')
@@ -51,21 +69,22 @@ def handleCommand(cmd):
5169
output.cls()
5270
elif cmd[:5] == "clear" and len(cmd) == 5:
5371
output.cls()
54-
elif cmd[:3] == "use":
55-
cmdUse(cmd)
5672
else:
57-
output.error('Unknown Command => ' + cmd)
73+
if cmd in modules:
74+
cmdUse(cmd)
75+
else:
76+
output.error('Unknown Command => ' + cmd)
5877

5978
startShell()
6079

6180
def cmdinfo(cmd):
62-
modulename = cmd[5:]
81+
modulename = cmd
6382
module_content = ''
6483
if os.path.isfile('modules/' + modulename + '/module.json'):
6584
with open('modules/' + modulename + '/module.json', 'r') as module:
6685
module_content = module.read().replace('\n','')
6786
loadedModule = json.loads(module_content)
68-
print('\n=> Module Info\n---------------------------------------------')
87+
print('\n=> Module Info\n--------------------------------------')
6988
name = ['Name',loadedModule['title']]
7089
desc = ['Description', loadedModule['description']]
7190
firmware = ['Firmware', loadedModule['requirements']['firmware']]
@@ -76,35 +95,34 @@ def cmdinfo(cmd):
7695

7796
def cmdList():
7897
global modules
79-
print('\n > Loaded Modules\n---------------------------------------------')
98+
print('\n > Loaded Modules\n--------------------------------------')
8099
for module in modules:
81100
output.success(module)
82101

83102
def cmdHelp(showPayLoadhelp):
84103
clscmd = ['cls/clear', 'Clears the screen']
85104

86105
if not showPayLoadhelp:
87-
print('\n=> Main Menu Command List\n------------------------------------------------------------------')
88-
listcmd = ['show modules', 'Lists all available payloads in the modules folder']
89-
usecmd = ['use <payload>', 'Loads the payload for further operation']
90-
infocmd = ['info <payload>', 'Gives you information about the specified payload']
91-
106+
print('\n=> Main Menu Command List\n--------------------------------------')
107+
listcmd = ['modules', 'Lists all available payloads in the modules folder']
108+
usecmd = ['<payload>', 'Loads the payload for further operation']
92109
exitcmd = ['quit/exit', 'Exits the program']
93-
print(tabulate([listcmd, usecmd, infocmd, clscmd, exitcmd], headers=['Command', 'output.info']))
110+
print(tabulate([listcmd, usecmd, clscmd, exitcmd], headers=['Command', 'output.info']))
94111

95112
else:
96113
#------------------------------------------------------------------------------------------------------------#
97-
print('\n\n=> Payload specific Command List\n------------------------------------------------------------------------------------')
114+
print('\n\n=> Payload specific Command List\n--------------------------------------')
98115
gencmd = ['generate/gen', 'Generates the inject.bin and copies it to your rubber ducky']
99116
setcmd = ['set <attribute> <value>', 'Sets the given attribute to the given value']
100-
attributescmd = ['info', 'Returns a list of attributes to set']
117+
attributescmd = ['attributes', 'Returns a list of attributes to set']
118+
infocmd = ['info', 'Gives you information about the payload']
101119
exit2cmd = ['quit/exit', 'Returns to payload selection']
102-
print(tabulate([gencmd, setcmd, attributescmd, clscmd, exit2cmd], headers=['Command', 'output.info']))
120+
print(tabulate([infocmd, gencmd, setcmd, attributescmd, clscmd, exit2cmd], headers=['Command', 'output.info']))
103121

104122
def cmdUse(cmd):
105123
global loadedModule
106124
global moduleAttributes
107-
modulename = cmd[4:]
125+
modulename = cmd
108126
module_content = ''
109127
if os.path.isfile('modules/' + modulename + '/module.json'):
110128
with open('modules/' + modulename + '/module.json', 'r') as module:
@@ -126,6 +144,22 @@ def cmdUse(cmd):
126144
output.error("Module '" + modulename + "' does not exist")
127145

128146
def cmdUseShell(modulename):
147+
possibleInputs = [
148+
'info',
149+
'generate',
150+
'gen',
151+
'attributes',
152+
'exit',
153+
'quit',
154+
'set <attribute> <value>',
155+
'help'
156+
]
157+
158+
completer = AutoCompleter(list(set(possibleInputs)), "\n" + Fore.LIGHTCYAN_EX + "pyd> " + Style.RESET_ALL + "(" + Fore.LIGHTRED_EX + modulename + Style.RESET_ALL +"): ")
159+
readline.set_completer_delims(' \t\n;')
160+
readline.set_completer(completer.complete)
161+
readline.parse_and_bind('tab: complete')
162+
readline.set_completion_display_matches_hook(completer.display_matches)
129163
cmdPay = input("\n" + Fore.LIGHTCYAN_EX + "pyd> " + Style.RESET_ALL + "(" + Fore.LIGHTRED_EX + modulename + Style.RESET_ALL +"): ")
130164
handleUseCmd(cmdPay, modulename)
131165

@@ -137,6 +171,9 @@ def handleUseCmd(cmd, modulename):
137171
global moduleAttributes
138172
moduleAttributes = []
139173
elif cmd[:4] == "info" and len(cmd) == 4:
174+
cmdinfo(modulename)
175+
cmdUseShell(modulename)
176+
elif cmd[:10] == "attributes" and len(cmd) == 10:
140177
cmdUseAttributes()
141178
cmdUseShell(modulename)
142179
elif (cmd[:3] =="gen" and len(cmd) == 3) or (cmd[:8] == "generate" and len(cmd) == 8):

output.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ def banner():
2020
print(" / ____/ / /_/ / / /_/ / / /_/ / / /__ / ,<")
2121
print("/_/ \__, / /_____/ \__,_/ \___/ /_/|_|")
2222
print(" /____/\n")
23+
print(" \x1B[3mby ThoughtfulDev | github.com/ThoughtfulDev\x1B[23m\n")
2324
print(" \x1B[3mGet your USB Rubber Ducky up and running faster\x1B[23m")
24-
print(Fore.WHITE + " \t\t Version " + Fore.MAGENTA + "1.0\n")
25+
print(Fore.WHITE + " \t\t Version " + Fore.MAGENTA + "1.1.0\n")

0 commit comments

Comments
 (0)