Ducky3
2023-05-22
Ducky3
- Category: Rev
- Difficulty: Medium
- Points: 497
- Solves: 14
Description
Alright fine, I’ll make my own keyboard layout…
Files
inject.bin
- data
payload.txt
- ASCII text
Solve
This challenge only provided another inject.bin
file initially. As the description says, this file dosn’t seem to match any language, and appears to be custom made. The challenge was later fixed to include payload.txt
.
STRING abcdefghijklmnopqrstuvwxyz
STRING ABCDEFGHIJKLMNOPQRSTUVWXYZ
STRING 0123456789
STRING !@#$%^&*()-_
STRING
payload.txt
seems to be part of the payload that was encoded into inject.bin
. Looking into how the DuckToolkit encoder works reveals that ‘STRING’ will simply encode the following string in the payload. This tells us that first part of inject.bin
encodes the string abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_
We can use this to figure out the keycodes and decode the rest of the file.
fpath = './inject.bin'
ht = {}
keys = {}
keystr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_'
#keys['{ 0x65}'] = 'C'
#keys['{2 0x6}'] = '{'
#keys['{2 0x10}'] = '}'
# read in data from inject.bin
with open(fpath, 'rb') as file:
data = file.read()
def read_keycode(data, datidx):
keycode = ''
if data[datidx+1] == 2: # determine shift modifier from second byte
keycode = keycode + '{2 '
else:
keycode = keycode + '{ '
keycode = keycode + hex(data[datidx]) + '}' # determine keycode from first byte
return keycode
# iterate over keystring and map keycodes to chars
for stridx, c in enumerate(keystr):
datidx = stridx * 2 # keycodes are 2 bytes
keycode = read_keycode(data, datidx)
# map keycode to key character
if not (keycode in keys):
keys[keycode] = keystr[stridx]
# iterate over data and print decoded keys
for datidx in range(0, len(data), 2):
keycode = read_keycode(data, datidx)
if keycode in keys:
print(keys[keycode], end='')
else:
print(keycode, end='')
print()
Because the encodings for ‘{’ and ‘}’ were not given, we have to figure out their mappings. This is simple because they are the only two unmapped chars. The characters ‘b’ and ‘C’ also have the same keycode of 0x6500 for some reason but we can manually map these values by uncommenting the following lines.
#keys['{ 0x65}'] = 'C'
#keys['{2 0x6}'] = '{'
#keys['{2 0x10}'] = '}'
This allows us to determine the flag.
byuctf{1_h0p3_y0u_enj0yed-thi5_very_muCH}