Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hak5
GitHub Repository: hak5/usbrubberducky-payloads
Path: blob/master/payloads/library/remote_access/duckNet/Encoder/src/Encoder.java
3020 views
1
// File: Encoder.java
2
// Created: 8/10/2011
3
// Original Author:Jason Appelbaum [email protected]
4
// Author: Dnucna
5
// Modified: 8/18/2012
6
// Modified: 11/9/2013 midnitesnake "added COMMAND-OPTION"
7
// Modified: 1/3/2013 midnitesnake "added COMMAND"
8
// Modified: 1/3/2013 midnitesnake "added REPEAT X"
9
// Modified: 2/5/2013 midnitesnake "added ALT-SHIFT"
10
// Modified: 4/18/2013 midnitesnake "added more user feedback"
11
// Modified: 5/2/2013 midnitesnake "added skip over empty lines"
12
// Modified: 1/12/2014 Benthejunebug "added ALT-TAB"
13
// Modified: 9/13/2016 rbeede "added STRING_DELAY n text"
14
15
import java.io.DataInputStream;
16
import java.io.File;
17
import java.io.FileInputStream;
18
import java.io.FileOutputStream;
19
import java.io.IOException;
20
import java.io.InputStream;
21
import java.util.ArrayList;
22
import java.util.List;
23
24
import javax.swing.text.BadLocationException;
25
import javax.swing.text.Document;
26
import javax.swing.text.rtf.RTFEditorKit;
27
28
import java.util.Properties;
29
30
public class Encoder {
31
/* contains the keyboard configuration */
32
private static Properties keyboardProps = new Properties();
33
/* contains the language layout */
34
private static Properties layoutProps = new Properties();
35
private static String version = "2.6.4";
36
private static Boolean debug=false;
37
38
public static void main(String[] args) {
39
String helpStr = "Hak5 Duck Encoder "+version+"\n\n"
40
+ "Usage: duckencode -i [file ..]\t\t\tencode specified file\n"
41
+ " or: duckencode -i [file ..] -o [file ..]\tencode to specified file\n\n"
42
+ "Arguments:\n"
43
+ " -i [file ..] \t\tInput File\n"
44
+ " -o [file ..] \t\tOutput File\n"
45
+ " -l [file ..] \t\tKeyboard Layout (us/fr/pt or a path to a properties file)\n\n"
46
+ "Script Commands:\n"
47
+ " ALT [key name] (ex: ALT F4, ALT SPACE)\n"
48
+ " CTRL | CONTROL [key name] (ex: CTRL ESC)\n"
49
+ " CTRL-ALT [key name] (ex: CTRL-ALT DEL)\n"
50
+ " CTRL-SHIFT [key name] (ex: CTRL-SHIFT ESC)\n"
51
+ " DEFAULT_DELAY | DEFAULTDELAY [Time in millisecond] (change the delay between each command)\n"
52
+ " DELAY [Time in millisecond] (used to overide temporary the default delay)\n"
53
+ " GUI | WINDOWS [key name] (ex: GUI r, GUI l)\n"
54
+ " REM [anything] (used to comment your code, no obligation :) )\n"
55
+ " ALT-SHIFT (swap language)\n"
56
+ " SHIFT [key name] (ex: SHIFT DEL)\n"
57
+ " STRING [any character of your layout]\n"
58
+ " STRING_DELAY [Number] [any character of your layout] (Number is ms delay between each character)\n"
59
+ " REPEAT [Number] (Repeat last instruction N times)\n"
60
+ " [key name] (anything in the keyboard.properties)";
61
62
String inputFile = null;
63
String outputFile = null;
64
String layoutFile = null;
65
66
if (args.length == 0) {
67
System.out.println(helpStr);
68
System.exit(0);
69
}
70
71
for (int i = 0; i < args.length; i++) {
72
if (args[i].equals("--gui") || args[i].equals("-g")) {
73
System.out.println("Launch GUI");
74
} else if (args[i].equals("--help") || args[i].equals("-h")) {
75
System.out.println(helpStr);
76
} else if (args[i].equals("-i")) {
77
// encode file
78
inputFile = args[++i];
79
} else if (args[i].equals("-o")) {
80
// output file
81
outputFile = args[++i];
82
} else if (args[i].equals("-l")) {
83
// output file
84
layoutFile = args[++i];
85
} else if (args[i].equals("-d")) {
86
// output file
87
debug=true;
88
} else {
89
System.out.println(helpStr);
90
break;
91
}
92
}
93
94
System.out.println("Hak5 Duck Encoder "+version+"\n");
95
96
if (inputFile != null) {
97
String scriptStr = null;
98
99
if (inputFile.contains(".rtf")) {
100
try {
101
FileInputStream stream = new FileInputStream(inputFile);
102
RTFEditorKit kit = new RTFEditorKit();
103
Document doc = kit.createDefaultDocument();
104
kit.read(stream, doc, 0);
105
106
scriptStr = doc.getText(0, doc.getLength());
107
System.out.println("Loading RTF .....\t\t[ OK ]");
108
} catch (IOException e) {
109
System.out.println("Error with input file!");
110
} catch (BadLocationException e) {
111
System.out.println("Error with input file!");
112
}
113
114
} else {
115
DataInputStream in = null;
116
try {
117
File f = new File(inputFile);
118
byte[] buffer = new byte[(int) f.length()];
119
in = new DataInputStream(new FileInputStream(f));
120
in.readFully(buffer);
121
scriptStr = new String(buffer);
122
System.out.println("Loading File .....\t\t[ OK ]");
123
} catch (IOException e) {
124
System.out.println("Error with input file!");
125
} finally {
126
try {
127
in.close();
128
} catch (IOException e) { /* ignore it */
129
}
130
}
131
}
132
loadProperties((layoutFile == null) ? "us" : layoutFile);
133
134
encodeToFile(scriptStr, (outputFile == null) ? "inject.bin"
135
: outputFile);
136
}
137
138
}
139
140
private static void loadProperties (String lang){
141
InputStream in;
142
ClassLoader loader = ClassLoader.getSystemClassLoader ();
143
try {
144
in = loader.getResourceAsStream("keyboard.properties");
145
if(in != null){
146
keyboardProps.load(in);
147
in.close();
148
System.out.println("Loading Keyboard File .....\t[ OK ]");
149
}else{
150
System.out.println("Error with keyboard.properties!");
151
System.exit(0);
152
}
153
} catch (IOException e) {
154
System.out.println("Error with keyboard.properties!");
155
}
156
157
try {
158
in = loader.getResourceAsStream(lang + ".properties");
159
if(in != null){
160
layoutProps.load(in);
161
in.close();
162
System.out.println("Loading Language File .....\t[ OK ]");
163
}else{
164
if(new File(lang).isFile()){
165
layoutProps.load(new FileInputStream(lang));
166
System.out.println("Loading Language File .....\t[ OK ]");
167
} else{
168
System.out.println("External layout.properties non found!");
169
System.exit(0);
170
}
171
}
172
} catch (IOException e) {
173
System.out.println("Error with layout.properties!");
174
System.exit(0);
175
}
176
177
}
178
private static void encodeToFile(String inStr, String fileDest) {
179
180
inStr = inStr.replaceAll("\\r", ""); // CRLF Fix
181
String[] instructions = inStr.split("\n");
182
String[] last_instruction = inStr.split("\n");
183
List<Byte> file = new ArrayList<Byte>();
184
int defaultDelay = 0;
185
int loop =0;
186
boolean repeat=false;
187
System.out.println("Loading DuckyScript .....\t[ OK ]");
188
if(debug) System.out.println("\nParsing Commands:");
189
for (int i = 0; i < instructions.length; i++) {
190
try {
191
boolean delayOverride = false;
192
String commentCheck = instructions[i].substring(0, 2);
193
if (commentCheck.equals("//"))
194
continue;
195
if (instructions[i].equals("\n"))
196
continue;
197
String[] instruction = instructions[i].split(" ", 2);
198
199
if(i>0){
200
last_instruction=instructions[i-1].split(" ", 2);
201
last_instruction[0].trim();
202
if (last_instruction.length == 2) {
203
last_instruction[1].trim();
204
}
205
}else{
206
last_instruction=instructions[i].split(" ", 2);
207
last_instruction[0].trim();
208
if (last_instruction.length == 2) {
209
last_instruction[1].trim();
210
}
211
}
212
213
instruction[0].trim();
214
215
if (instruction.length == 2) {
216
instruction[1].trim();
217
}
218
219
if (instruction[0].equals("REM")){
220
continue;
221
}
222
if (instruction[0].equals("REPEAT")){
223
loop=Integer.parseInt(instruction[1].trim());
224
repeat=true;
225
}else{
226
repeat=false;
227
loop=1;
228
}
229
while(loop>0){
230
if (repeat){
231
instruction=last_instruction;
232
//System.out.println(Integer.toString(instruction.length));
233
}
234
if (debug) System.out.println(java.util.Arrays.toString(instruction));
235
if (instruction[0].equals("DEFAULT_DELAY")
236
|| instruction[0].equals("DEFAULTDELAY")) {
237
defaultDelay = Integer.parseInt(instruction[1].trim());
238
delayOverride = true;
239
} else if (instruction[0].equals("DELAY")) {
240
int delay = Integer.parseInt(instruction[1].trim());
241
while (delay > 0) {
242
file.add((byte) 0x00);
243
if (delay > 255) {
244
file.add((byte) 0xFF);
245
delay = delay - 255;
246
} else {
247
file.add((byte) delay);
248
delay = 0;
249
}
250
}
251
delayOverride = true;
252
} else if (instruction[0].equals("STRING")) {
253
for (int j = 0; j < instruction[1].length(); j++) {
254
char c = instruction[1].charAt(j);
255
addBytes(file,charToBytes(c));
256
}
257
} else if (instruction[0].equals("STRING_DELAY")) {
258
final String[] twoOptions = instruction[1].split(" ", 2);
259
final int delayMillis = Integer.parseInt(twoOptions[0].trim());
260
final String userText = twoOptions[1].trim();
261
262
if(debug) System.out.println(delayMillis);
263
if(debug) System.out.println(userText);
264
265
for (int j = 0; j < userText.length(); j++) {
266
char c = userText.charAt(j);
267
addBytes(file,charToBytes(c));
268
269
// Now insert the delay before the next character (and after the last is provided)
270
for(int counter = delayMillis; counter > 0; counter -= 0xFF) {
271
file.add((byte) 0x00);
272
if(counter > 0xFF) {
273
file.add((byte) 0xFF);
274
} else {
275
file.add((byte) counter); // Last one
276
}
277
}
278
}
279
} else if (instruction[0].equals("CONTROL")
280
|| instruction[0].equals("CTRL")) {
281
if (instruction.length != 1){
282
file.add(strInstrToByte(instruction[1]));
283
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_CTRL")));
284
} else {
285
file.add(strToByte(keyboardProps.getProperty("KEY_LEFT_CTRL")));
286
file.add((byte) 0x00);
287
}
288
} else if (instruction[0].equals("ALT")) {
289
if (instruction.length != 1){
290
file.add(strInstrToByte(instruction[1]));
291
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_ALT")));
292
} else {
293
file.add(strToByte(keyboardProps.getProperty("KEY_LEFT_ALT")));
294
file.add((byte) 0x00);
295
}
296
} else if (instruction[0].equals("SHIFT")) {
297
if (instruction.length != 1) {
298
file.add(strInstrToByte(instruction[1]));
299
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_SHIFT")));
300
} else {
301
file.add(strToByte(keyboardProps.getProperty("KEY_LEFT_SHIFT")));
302
file.add((byte) 0x00);
303
}
304
} else if (instruction[0].equals("CTRL-ALT")) {
305
if (instruction.length != 1) {
306
file.add(strInstrToByte(instruction[1]));
307
file.add((byte) (strToByte(keyboardProps.getProperty("MODIFIERKEY_CTRL"))
308
| strToByte(keyboardProps.getProperty("MODIFIERKEY_ALT"))));
309
} else {
310
continue;
311
}
312
} else if (instruction[0].equals("CTRL-SHIFT")) {
313
if (instruction.length != 1) {
314
file.add(strInstrToByte(instruction[1]));
315
file.add((byte) (strToByte(keyboardProps.getProperty("MODIFIERKEY_CTRL"))
316
| strToByte(keyboardProps.getProperty("MODIFIERKEY_SHIFT"))));
317
} else {
318
continue;
319
}
320
} else if (instruction[0].equals("COMMAND-OPTION")) {
321
if (instruction.length != 1) {
322
file.add(strInstrToByte(instruction[1]));
323
file.add((byte) (strToByte(keyboardProps.getProperty("MODIFIERKEY_KEY_LEFT_GUI"))
324
| strToByte(keyboardProps.getProperty("MODIFIERKEY_ALT"))));
325
} else {
326
continue;
327
}
328
} else if (instruction[0].equals("ALT-SHIFT")) {
329
if (instruction.length != 1) {
330
file.add(strInstrToByte(instruction[1]));
331
file.add((byte) (strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_ALT"))
332
| strToByte(keyboardProps.getProperty("MODIFIERKEY_SHIFT")))
333
);
334
} else {
335
file.add(strToByte(keyboardProps.getProperty("KEY_LEFT_ALT")));
336
file.add((byte) (strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_ALT"))
337
| strToByte(keyboardProps.getProperty("MODIFIERKEY_SHIFT")))
338
);
339
}
340
} else if (instruction[0].equals("ALT-TAB")){
341
if (instruction.length == 1) {
342
file.add(strToByte(keyboardProps.getProperty("KEY_TAB")));
343
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_ALT")));
344
} else{
345
// do something?
346
}
347
} else if (instruction[0].equals("REM")) {
348
/* no default delay for the comments */
349
delayOverride = true;
350
continue;
351
} else if (instruction[0].equals("WINDOWS")
352
|| instruction[0].equals("GUI")) {
353
if (instruction.length == 1) {
354
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_GUI")));
355
file.add((byte) 0x00);
356
} else {
357
file.add(strInstrToByte(instruction[1]));
358
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_GUI")));
359
}
360
} else if (instruction[0].equals("COMMAND")){
361
if (instruction.length == 1) {
362
file.add(strToByte(keyboardProps.getProperty("KEY_COMMAND")));
363
file.add((byte) 0x00);
364
} else {
365
file.add(strInstrToByte(instruction[1]));
366
file.add(strToByte(keyboardProps.getProperty("MODIFIERKEY_LEFT_GUI")));
367
}
368
}else {
369
/* treat anything else as a key */
370
file.add(strInstrToByte(instruction[0]));
371
file.add((byte) 0x00);
372
}
373
loop--;
374
}
375
// Default delay
376
if (!delayOverride & defaultDelay > 0) {
377
int delayCounter = defaultDelay;
378
while (delayCounter > 0) {
379
file.add((byte) 0x00);
380
if (delayCounter > 255) {
381
file.add((byte) 0xFF);
382
delayCounter = delayCounter - 255;
383
} else {
384
file.add((byte) delayCounter);
385
delayCounter = 0;
386
}
387
}
388
}
389
}catch (StringIndexOutOfBoundsException e){
390
//do nothing
391
}
392
catch (Exception e) {
393
System.out.println("Error on Line: " + (i + 1));
394
e.printStackTrace();
395
}
396
}
397
398
// Write byte array to file
399
byte[] data = new byte[file.size()];
400
for (int i = 0; i < file.size(); i++) {
401
data[i] = file.get(i);
402
}
403
try {
404
File someFile = new File(fileDest);
405
FileOutputStream fos = new FileOutputStream(someFile);
406
fos.write(data);
407
fos.flush();
408
fos.close();
409
System.out.println("DuckyScript Complete.....\t[ OK ]\n");
410
} catch (Exception e) {
411
System.out.print("Failed to write hex file!");
412
}
413
414
}
415
416
private static void addBytes(List<Byte> file, byte[] byteTab){
417
for(int i=0;i<byteTab.length;i++)
418
file.add(byteTab[i]);
419
if(byteTab.length % 2 != 0){
420
file.add((byte) 0x00);
421
}
422
}
423
424
private static byte[] charToBytes (char c){
425
return codeToBytes(charToCode(c));
426
}
427
private static String charToCode (char c){
428
String code;
429
if(c<128){
430
code = "ASCII_"+Integer.toHexString(c).toUpperCase();
431
}else if (c<256){
432
code = "ISO_8859_1_"+Integer.toHexString(c).toUpperCase();
433
}else{
434
code = "UNICODE_"+Integer.toHexString(c).toUpperCase();
435
}
436
return code;
437
}
438
439
private static byte[] codeToBytes (String str){
440
if(layoutProps.getProperty(str) != null){
441
String keys[] = layoutProps.getProperty(str).split(",");
442
byte[] byteTab = new byte[keys.length];
443
for(int j=0;j<keys.length;j++){
444
String key = keys[j].trim();
445
if(keyboardProps.getProperty(key) != null){
446
byteTab[j] = strToByte(keyboardProps.getProperty(key).trim());
447
}else if(layoutProps.getProperty(key) != null){
448
byteTab[j] = strToByte(layoutProps.getProperty(key).trim());
449
}else{
450
System.out.println("Key not found:"+key);
451
byteTab[j] = (byte) 0x00;
452
}
453
}
454
return byteTab;
455
}else{
456
System.out.println("Char not found:"+str);
457
byte[] byteTab = new byte[1];
458
byteTab[0] = (byte) 0x00;
459
return byteTab;
460
}
461
}
462
private static byte strToByte(String str) {
463
if(str.startsWith("0x")){
464
return (byte)Integer.parseInt(str.substring(2),16);
465
}else{
466
return (byte)Integer.parseInt(str);
467
}
468
}
469
470
private static byte strInstrToByte(String instruction){
471
instruction = instruction.trim();
472
if(keyboardProps.getProperty("KEY_"+instruction)!=null)
473
return strToByte(keyboardProps.getProperty("KEY_"+instruction));
474
/* instruction different from the key name */
475
if(instruction.equals("ESCAPE"))
476
return strInstrToByte("ESC");
477
if(instruction.equals("DEL"))
478
return strInstrToByte("DELETE");
479
if(instruction.equals("BREAK"))
480
return strInstrToByte("PAUSE");
481
if(instruction.equals("CONTROL"))
482
return strInstrToByte("CTRL");
483
if(instruction.equals("DOWNARROW"))
484
return strInstrToByte("DOWN");
485
if(instruction.equals("UPARROW"))
486
return strInstrToByte("UP");
487
if(instruction.equals("LEFTARROW"))
488
return strInstrToByte("LEFT");
489
if(instruction.equals("RIGHTARROW"))
490
return strInstrToByte("RIGHT");
491
if(instruction.equals("MENU"))
492
return strInstrToByte("APP");
493
if(instruction.equals("WINDOWS"))
494
return strInstrToByte("GUI");
495
if(instruction.equals("PLAY") || instruction.equals("PAUSE"))
496
return strInstrToByte("MEDIA_PLAY_PAUSE");
497
if(instruction.equals("STOP"))
498
return strInstrToByte("MEDIA_STOP");
499
if(instruction.equals("MUTE"))
500
return strInstrToByte("MEDIA_MUTE");
501
if(instruction.equals("VOLUMEUP"))
502
return strInstrToByte("MEDIA_VOLUME_INC");
503
if(instruction.equals("VOLUMEDOWN"))
504
return strInstrToByte("MEDIA_VOLUME_DEC");
505
if(instruction.equals("SCROLLLOCK"))
506
return strInstrToByte("SCROLL_LOCK");
507
if(instruction.equals("NUMLOCK"))
508
return strInstrToByte("NUM_LOCK");
509
if(instruction.equals("CAPSLOCK"))
510
return strInstrToByte("CAPS_LOCK");
511
/* else take first letter */
512
return charToBytes(instruction.charAt(0))[0];
513
}
514
}
515
516