rubber-ducky 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,169 @@
1
+ {
2
+ "__comment":"All numbers here are in hex format and 0x is ignored.",
3
+ "__comment":" ",
4
+ "__comment":"This list is in ascending order of 3rd byte (HID Usage ID).",
5
+ "__comment":" See section 10 Keyboard/Keypad Page (0x07)",
6
+ "__comment":" of document USB HID Usage Tables Version 1.12.",
7
+ "__comment":" ",
8
+ "__comment":"Definition of these 3 bytes can be found",
9
+ "__comment":" in section B.1 Protocol 1 (Keyboard)",
10
+ "__comment":" of document Device Class Definition for HID Version 1.11",
11
+ "__comment":" - byte 1: Modifier keys",
12
+ "__comment":" - byte 2: Reserved",
13
+ "__comment":" - byte 3: Keycode 1",
14
+ "__comment":" ",
15
+ "__comment":"Both documents can be obtained from link here",
16
+ "__comment":" http://www.usb.org/developers/hidpage/",
17
+ "__comment":" ",
18
+ "__comment":" Slovak QWERTZ version made by Andrej Šimko",
19
+ "__comment":" Note that some special characters use leftCtrl+leftAlt+[key]",
20
+ "__comment":" Special Slovak characters like ľščťžýáíéúäô are not included",
21
+ "a":"00,00,04",
22
+ "b":"00,00,05",
23
+ "c":"00,00,06",
24
+ "d":"00,00,07",
25
+ "e":"00,00,08",
26
+ "f":"00,00,09",
27
+ "g":"00,00,0a",
28
+ "h":"00,00,0b",
29
+ "i":"00,00,0c",
30
+ "j":"00,00,0d",
31
+ "k":"00,00,0e",
32
+ "l":"00,00,0f",
33
+ "m":"00,00,10",
34
+ "n":"00,00,11",
35
+ "o":"00,00,12",
36
+ "p":"00,00,13",
37
+ "q":"00,00,14",
38
+ "r":"00,00,15",
39
+ "s":"00,00,16",
40
+ "t":"00,00,17",
41
+ "u":"00,00,18",
42
+ "v":"00,00,19",
43
+ "w":"00,00,1a",
44
+ "x":"00,00,1b",
45
+ "z":"00,00,1c",
46
+ "y":"00,00,1d",
47
+ "+":"00,00,1e",
48
+ "ENTER":"00,00,28",
49
+ "ESC":"00,00,29",
50
+ "ESCAPE":"00,00,29",
51
+ "TAB":"00,00,2b",
52
+ " ":"00,00,2c",
53
+ "SPACE":"00,00,2c",
54
+ "CTRL-ALT":"05,00,00",
55
+ "=":"00,00,2d",
56
+ ";":"00,00,35",
57
+ ",":"00,00,36",
58
+ ".":"00,00,37",
59
+ "-":"00,00,38",
60
+ "CAPSLOCK":"00,00,39",
61
+ "F1":"00,00,3a",
62
+ "F2":"00,00,3b",
63
+ "F3":"00,00,3c",
64
+ "F4":"00,00,3d",
65
+ "F5":"00,00,3e",
66
+ "F6":"00,00,3f",
67
+ "F7":"00,00,40",
68
+ "F8":"00,00,41",
69
+ "F9":"00,00,42",
70
+ "F10":"00,00,43",
71
+ "F11":"00,00,44",
72
+ "F12":"00,00,45",
73
+ "PRINTSCREEN":"00,00,46",
74
+ "SCROLLLOCK":"00,00,47",
75
+ "BREAK":"00,00,48",
76
+ "PAUSE":"00,00,48",
77
+ "INSERT":"00,00,49",
78
+ "HOME":"00,00,4a",
79
+ "PAGEUP":"00,00,4b",
80
+ "DEL":"00,00,4c",
81
+ "DELETE":"00,00,4c",
82
+ "END":"00,00,4d",
83
+ "PAGEDOWN":"00,00,4e",
84
+ "RIGHT":"00,00,4f",
85
+ "RIGHTARROW":"00,00,4f",
86
+ "LEFT":"00,00,50",
87
+ "LEFTARROW":"00,00,50",
88
+ "DOWN":"00,00,51",
89
+ "DOWNARROW":"00,00,51",
90
+ "UP":"00,00,52",
91
+ "UPARROW":"00,00,52",
92
+ "APP":"00,00,65",
93
+ "MENU":"00,00,65",
94
+ "ALT-TAB":"00,00,71",
95
+ "CONTROL":"01,00,00",
96
+ "CTRL":"01,00,00",
97
+ "SHIFT":"02,00,00",
98
+ "A":"02,00,04",
99
+ "B":"02,00,05",
100
+ "C":"02,00,06",
101
+ "D":"02,00,07",
102
+ "E":"02,00,08",
103
+ "F":"02,00,09",
104
+ "G":"02,00,0a",
105
+ "H":"02,00,0b",
106
+ "I":"02,00,0c",
107
+ "J":"02,00,0d",
108
+ "K":"02,00,0e",
109
+ "L":"02,00,0f",
110
+ "M":"02,00,10",
111
+ "N":"02,00,11",
112
+ "O":"02,00,12",
113
+ "P":"02,00,13",
114
+ "Q":"02,00,14",
115
+ "R":"02,00,15",
116
+ "S":"02,00,16",
117
+ "T":"02,00,17",
118
+ "U":"02,00,18",
119
+ "V":"02,00,19",
120
+ "W":"02,00,1a",
121
+ "X":"02,00,1b",
122
+ "Z":"02,00,1c",
123
+ "Y":"02,00,1d",
124
+ "1":"02,00,1e",
125
+ "2":"02,00,1f",
126
+ "3":"02,00,20",
127
+ "4":"02,00,21",
128
+ "5":"02,00,22",
129
+ "6":"02,00,23",
130
+ "7":"02,00,24",
131
+ "8":"02,00,25",
132
+ "9":"02,00,26",
133
+ "0":"02,00,27",
134
+ "\\":"05,00,14",
135
+ "%":"02,00,2d",
136
+ "/":"02,00,2f",
137
+ "(":"02,00,30",
138
+ "'":"05,00,13",
139
+ ")":"02,00,31",
140
+ "\"":"02,00,33",
141
+ "!":"02,00,34",
142
+ "?":"02,00,36",
143
+ ":":"02,00,37",
144
+ "_":"02,00,38",
145
+ "|":"05,00,1a",
146
+ "#":"05,00,1b",
147
+ "&":"05,00,06",
148
+ "@":"05,00,19",
149
+ "$":"05,00,33",
150
+ "*":"05,00,38",
151
+ "{":"05,00,05",
152
+ "}":"05,00,11",
153
+ "[":"05,00,09",
154
+ "]":"05,00,0a",
155
+ "~":"05,00,1e",
156
+ "^":"05,00,20",
157
+ "<":"05,00,36",
158
+ ">":"05,00,37",
159
+ "CTRL-SHIFT":"03,00,00",
160
+ "ALT":"04,00,00",
161
+ "ALT-SHIFT":"06,00,00",
162
+ "COMMAND":"08,00,00",
163
+ "GUI":"08,00,00",
164
+ "WINDOWS":"08,00,00",
165
+ "COMMAND-OPTION":"12,00,00",
166
+ "COMMAND-CTRL-SHIFT":"12,00,00",
167
+ "COMMAND-CTRL":"12,00,00",
168
+ "COMMAND-OPTION-SHIFT'":"12,00,00"
169
+ }
@@ -0,0 +1,170 @@
1
+ {
2
+ "__comment":"ducktoolkit/languages/us.json",
3
+ "__comment":"All numbers here are in hex format and 0x is ignored.",
4
+ "__comment":" ",
5
+ "__comment":"This list is in ascending order of 3rd byte (HID Usage ID).",
6
+ "__comment":" See section 10 Keyboard/Keypad Page (0x07)",
7
+ "__comment":" of document USB HID Usage Tables Version 1.12.",
8
+ "__comment":" ",
9
+ "__comment":"Definition of these 3 bytes can be found",
10
+ "__comment":" in section B.1 Protocol 1 (Keyboard)",
11
+ "__comment":" of document Device Class Definition for HID Version 1.11",
12
+ "__comment":" - byte 1: Modifier keys",
13
+ "__comment":" - byte 2: Reserved",
14
+ "__comment":" - byte 3: Keycode 1",
15
+ "__comment":" ",
16
+ "__comment":"Both documents can be obtained from link here",
17
+ "__comment":" http://www.usb.org/developers/hidpage/",
18
+ "__comment":" ",
19
+ "__comment":"A = LeftShift + a, { = LeftShift + [",
20
+ "__comment":" ",
21
+ "a":"00,00,04",
22
+ "b":"00,00,05",
23
+ "c":"00,00,06",
24
+ "d":"00,00,07",
25
+ "e":"00,00,08",
26
+ "f":"00,00,09",
27
+ "g":"00,00,0a",
28
+ "h":"00,00,0b",
29
+ "i":"00,00,0c",
30
+ "j":"00,00,0d",
31
+ "k":"00,00,0e",
32
+ "l":"00,00,0f",
33
+ "m":"00,00,10",
34
+ "n":"00,00,11",
35
+ "o":"00,00,12",
36
+ "p":"00,00,13",
37
+ "q":"00,00,14",
38
+ "r":"00,00,15",
39
+ "s":"00,00,16",
40
+ "t":"00,00,17",
41
+ "u":"00,00,18",
42
+ "v":"00,00,19",
43
+ "w":"00,00,1a",
44
+ "x":"00,00,1b",
45
+ "y":"00,00,1c",
46
+ "z":"00,00,1d",
47
+ "1":"00,00,1e",
48
+ "2":"00,00,1f",
49
+ "3":"00,00,20",
50
+ "4":"00,00,21",
51
+ "5":"00,00,22",
52
+ "6":"00,00,23",
53
+ "7":"00,00,24",
54
+ "8":"00,00,25",
55
+ "9":"00,00,26",
56
+ "0":"00,00,27",
57
+ "ENTER":"00,00,28",
58
+ "ESC":"00,00,29",
59
+ "ESCAPE":"00,00,29",
60
+ "TAB":"00,00,2b",
61
+ " ":"00,00,2c",
62
+ "SPACE":"00,00,2c",
63
+ "-":"00,00,2d",
64
+ "=":"00,00,2e",
65
+ "[":"00,00,2f",
66
+ "]":"00,00,30",
67
+ "\\":"00,00,31",
68
+ ";":"00,00,33",
69
+ "'":"00,00,34",
70
+ "`":"00,00,35",
71
+ ",":"00,00,36",
72
+ ".":"00,00,37",
73
+ "/":"00,00,38",
74
+ "CAPSLOCK":"00,00,39",
75
+ "F1":"00,00,3a",
76
+ "F2":"00,00,3b",
77
+ "F3":"00,00,3c",
78
+ "F4":"00,00,3d",
79
+ "F5":"00,00,3e",
80
+ "F6":"00,00,3f",
81
+ "F7":"00,00,40",
82
+ "F8":"00,00,41",
83
+ "F9":"00,00,42",
84
+ "F10":"00,00,43",
85
+ "F11":"00,00,44",
86
+ "F12":"00,00,45",
87
+ "PRINTSCREEN":"00,00,46",
88
+ "SCROLLLOCK":"00,00,47",
89
+ "BREAK":"00,00,48",
90
+ "PAUSE":"00,00,48",
91
+ "INSERT":"00,00,49",
92
+ "HOME":"00,00,4a",
93
+ "PAGEUP":"00,00,4b",
94
+ "DEL":"00,00,4c",
95
+ "DELETE":"00,00,4c",
96
+ "END":"00,00,4d",
97
+ "PAGEDOWN":"00,00,4e",
98
+ "RIGHT":"00,00,4f",
99
+ "RIGHTARROW":"00,00,4f",
100
+ "LEFT":"00,00,50",
101
+ "LEFTARROW":"00,00,50",
102
+ "DOWN":"00,00,51",
103
+ "DOWNARROW":"00,00,51",
104
+ "UP":"00,00,52",
105
+ "UPARROW":"00,00,52",
106
+ "APP":"00,00,65",
107
+ "MENU":"00,00,65",
108
+ "ALT-TAB":"00,00,71",
109
+ "CONTROL":"01,00,00",
110
+ "CTRL":"01,00,00",
111
+ "SHIFT":"02,00,00",
112
+ "A":"02,00,04",
113
+ "B":"02,00,05",
114
+ "C":"02,00,06",
115
+ "D":"02,00,07",
116
+ "E":"02,00,08",
117
+ "F":"02,00,09",
118
+ "G":"02,00,0a",
119
+ "H":"02,00,0b",
120
+ "I":"02,00,0c",
121
+ "J":"02,00,0d",
122
+ "K":"02,00,0e",
123
+ "L":"02,00,0f",
124
+ "M":"02,00,10",
125
+ "N":"02,00,11",
126
+ "O":"02,00,12",
127
+ "P":"02,00,13",
128
+ "Q":"02,00,14",
129
+ "R":"02,00,15",
130
+ "S":"02,00,16",
131
+ "T":"02,00,17",
132
+ "U":"02,00,18",
133
+ "V":"02,00,19",
134
+ "W":"02,00,1a",
135
+ "X":"02,00,1b",
136
+ "Y":"02,00,1c",
137
+ "Z":"02,00,1d",
138
+ "!":"02,00,1e",
139
+ "@":"02,00,1f",
140
+ "#":"02,00,20",
141
+ "$":"02,00,21",
142
+ "%":"02,00,22",
143
+ "^":"02,00,23",
144
+ "&":"02,00,24",
145
+ "*":"02,00,25",
146
+ "(":"02,00,26",
147
+ ")":"02,00,27",
148
+ "_":"02,00,2d",
149
+ "+":"02,00,2e",
150
+ "{":"02,00,2f",
151
+ "}":"02,00,30",
152
+ "|":"02,00,31",
153
+ ":":"02,00,33",
154
+ "\"":"02,00,34",
155
+ "~":"02,00,35",
156
+ "<":"02,00,36",
157
+ ">":"02,00,37",
158
+ "?":"02,00,38",
159
+ "CTRL-SHIFT":"03,00,00",
160
+ "ALT":"04,00,00",
161
+ "CTRL-ALT":"05,00,00",
162
+ "ALT-SHIFT":"06,00,00",
163
+ "COMMAND":"08,00,00",
164
+ "GUI":"08,00,00",
165
+ "WINDOWS":"08,00,00",
166
+ "COMMAND-OPTION":"12,00,00",
167
+ "COMMAND-CTRL-SHIFT":"12,00,00",
168
+ "COMMAND-CTRL":"12,00,00",
169
+ "COMMAND-OPTION-SHIFT'":"12,00,00"
170
+ }
@@ -0,0 +1,36 @@
1
+ module Rubber
2
+ module Ducky
3
+ module Common
4
+ DECODER_COMMAND_KEYS = [
5
+ 'DELAY', 'SPACE', 'CTRL', 'ALT', 'GUI', 'WINDOWS', 'ESC', 'ESCAPE',
6
+ 'PRINTSCREEN', 'INSERT', 'HOME', 'DELETE', 'END', 'ENTER', 'PAGEUP',
7
+ 'PAGEDOWN', 'LEFTARROW', 'LEFT', 'DOWNARROW', 'DOWN', 'RIGHTARROW',
8
+ 'RIGHT', 'UPARROW', 'UP', 'SCROLLLOCK', 'WINDOWS', 'MENU', 'TAB',
9
+ 'CAPSLOCK', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
10
+ 'F10', 'F11', 'F12', 'GUI R', 'GUI D', 'CTRL-ALT', 'CTRL-SHIFT',
11
+ 'ALT-SHIFT', 'CONTROL', 'ESCAPE', 'DELAY', 'DEFAULTDELAY',
12
+ 'DEFAULT_DELAY', 'CTRL S', 'CTRL V', 'CTRL X', 'CTRL Z', 'CTRL C',
13
+ 'ALT F4', 'WAKE', 'SLEEP', 'APP', 'STOP', 'POWER'
14
+ ].freeze
15
+
16
+ def self.convert_hex(int_value)
17
+ format('%02X', int_value)
18
+ end
19
+
20
+ def self.list_languages
21
+ languages = []
22
+ lang_dir = File.join(File.dirname(__FILE__), '..', 'languages')
23
+ Dir.glob("#{lang_dir}/*.json").each do |filename|
24
+ languages << File.basename(filename, '.json')
25
+ end
26
+ languages
27
+ end
28
+
29
+ def self.load_language(language)
30
+ lang_dir = File.join(File.dirname(__FILE__), '..', 'languages')
31
+ language_file = File.join(lang_dir, "#{language}.json")
32
+ JSON.parse(File.read(language_file))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,55 @@
1
+ require 'json'
2
+ require 'base64'
3
+ require_relative 'common'
4
+
5
+ module Rubber
6
+ module Ducky
7
+ module Decoder
8
+ def self.decode(content, language)
9
+ lang_file = Common.load_language(language)
10
+ ducky_hex = content.unpack1('H*')
11
+ decoded_bin = ""
12
+ duck_decoded = ""
13
+
14
+ (0...ducky_hex.length).step(4) do |i|
15
+ decoded_key = ""
16
+ last_key = duck_decoded
17
+ duck_decoded = ducky_hex[i, 4]
18
+
19
+ lang_file.each do |key, value|
20
+ begin
21
+ new_value = value.split(',')
22
+ if new_value.length == 3
23
+ value = "#{new_value[2]}#{new_value[0]}"
24
+ end
25
+ rescue => e
26
+ next
27
+ end
28
+
29
+ if duck_decoded == "2c00"
30
+ decoded_key = " "
31
+ elsif duck_decoded == "00ff" && last_key != "00ff"
32
+ decoded_key = "DELAY"
33
+ elsif duck_decoded == value
34
+ decoded_key = key
35
+ else
36
+ if duck_decoded[-2, 2] == "00"
37
+ if duck_decoded[0, 2] == value
38
+ decoded_key = key إذا كان طول المفتاح يساوي 1
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ if Common::DECODER_COMMAND_KEYS.include?(decoded_key)
45
+ decoded_bin += decoded_key + "\n"
46
+ else
47
+ decoded_bin += decoded_key
48
+ end
49
+ end
50
+
51
+ decoded_bin
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,92 @@
1
+ # lib/rubber-ducky/encoder.rb
2
+
3
+ require 'json'
4
+ require_relative 'common'
5
+
6
+ module Rubber
7
+ module Ducky
8
+ module Encoder
9
+ def self.encode(duck_text, language)
10
+ lang_file = Common.load_language(language)
11
+ encoded = parse_text(duck_text, lang_file)
12
+ [encoded].pack('H*')
13
+ end
14
+
15
+ def self.parse_text(duck_text, lang_file)
16
+ encoded_file = []
17
+ default_delay = 0
18
+
19
+ duck_text.gsub!("\r", '')
20
+ duck_text.split("\n").each do |line|
21
+ line.strip!
22
+ next if line.empty? || line.start_with?('REM', 'rem')
23
+
24
+ cmd, instruction = line.split(' ', 2)
25
+ cmd.strip!
26
+ instruction&.strip!
27
+
28
+ case cmd.upcase
29
+ when 'DEFAULT_DELAY', 'DEFAULTDELAY'
30
+ default_delay = instruction.to_i
31
+ when 'DELAY'
32
+ encoded_file.push(add_delay(instruction.to_i))
33
+ when 'STRING'
34
+ encode_string(instruction, lang_file, encoded_file)
35
+ else
36
+ encode_command(cmd, instruction, lang_file, encoded_file)
37
+ end
38
+
39
+ encoded_file.push(add_delay(default_delay)) if default_delay > 0
40
+ end
41
+
42
+ encoded_file.join
43
+ end
44
+
45
+ def self.encode_string(text, lang_file, encoded_file)
46
+ text.each_char do |char|
47
+ if lang_file[char]
48
+ elements = lang_file[char].split(',')
49
+ encoded_file.push(Common.convert_hex(elements[2].to_i(16)), Common.convert_hex(elements[0].to_i(16)))
50
+ else
51
+ puts "Warning: Character '#{char}' not found in language file"
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.encode_command(cmd, instruction, lang_file, encoded_file)
57
+ if lang_file[cmd]
58
+ elements = lang_file[cmd].split(',')
59
+ elements.map! { |i| i.to_i(16) }
60
+
61
+ if instruction && lang_file[instruction]
62
+ param = lang_file[instruction].split(',')
63
+ param.map! { |i| i.to_i(16) }
64
+ elements[0] |= param[0]
65
+ elements[2] |= param[2]
66
+ end
67
+
68
+ encoded_file.push(Common.convert_hex(elements[2]), Common.convert_hex(elements[0]))
69
+ else
70
+ puts "Warning: Command '#{cmd}' not found in language file"
71
+ end
72
+ end
73
+
74
+ def self.add_delay(delay_value)
75
+ delay_return = ''
76
+
77
+ while delay_value > 0
78
+ if delay_value > 255
79
+ delay_return += '00FF'
80
+ delay_value -= 255
81
+ else
82
+ _delay = delay_value.to_s(16).rjust(2, '0')
83
+ delay_return += "00#{_delay}"
84
+ delay_value = 0
85
+ end
86
+ end
87
+
88
+ delay_return
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,5 @@
1
+ module Rubber
2
+ module Ducky
3
+ VERSION = '1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'rubber-ducky/common'
2
+ require_relative 'rubber-ducky/encoder'
3
+ require_relative 'rubber-ducky/decoder'
4
+
5
+
6
+ module Rubber
7
+ module Ducky
8
+ def self.encode(input_file, output: nil, language: 'us')
9
+ content = File.read(input_file)
10
+ encoded = Encoder.encode(content, language)
11
+ if output
12
+ File.open(output, 'wb') do |file|
13
+ file.write(encoded)
14
+ end
15
+ end
16
+ encoded
17
+ end
18
+
19
+ def self.decode(input_file, output: nil, language: 'us')
20
+ content = File.binread(input_file)
21
+ decoded = Decoder.decode(content, language)
22
+ if output
23
+ File.open(output, 'w') { |file| file.write(decoded) }
24
+ end
25
+ decoded
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path('lib/rubber-ducky/version', __dir__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'rubber-ducky'
5
+ spec.version = Rubber::Ducky::VERSION
6
+ spec.authors = 'MAVEN'
7
+ spec.email = 'aszda33@gmail.com'
8
+ spec.summary = 'A Ruby library for encoding and decoding Rubber Ducky scripts.'
9
+ spec.description = 'This gem allows you to encode and decode Rubber Ducky scripts for penetration testing purposes.'
10
+ spec.homepage = 'https://github.com/Abo5/rubber-ducky'
11
+ spec.license = 'MIT'
12
+ spec.platform = Gem::Platform::RUBY
13
+ spec.required_ruby_version = '>= 2.7.0'
14
+
15
+ # Include all files from git tracking, excluding test, spec, and features
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+
18
+ # Ensure all necessary files are included in the gem
19
+ spec.files += Dir['README.md', 'LICENSE', 'CHANGELOG.md', 'lib/**/*.rb', 'lib/**/*.rake', 'rubber-ducky.gemspec', '.github/*.md', 'Gemfile', 'Rakefile', 'examples/*']
20
+
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ # Define runtime and development dependencies
26
+ spec.add_runtime_dependency 'json', '~> 2.0'
27
+ spec.add_runtime_dependency 'base64', '~> 2.7.1'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 2.0'
30
+ spec.add_development_dependency 'rake', '~> 13.0'
31
+ spec.add_development_dependency 'rspec', '~> 3.0'
32
+ end