bqm 1.3.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/DOC.md +4 -0
  3. data/bin/bqm +53 -8
  4. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d78da6d030479d62b8fc734bde08fddc8ff97ca4502855287cb543b1d5f50fd
4
- data.tar.gz: 836675f08cab5fe97744eae3c4f53182e2bbc9928f099540e94c36af576f3b56
3
+ metadata.gz: 1a14c962fd0bf2a8c456bf7b9ff5416036289f61a8d4030ed246a77b6115aec0
4
+ data.tar.gz: d9d0bf051756b2eba968cdb37945fd953db2746b646f6a9888c4100207979792
5
5
  SHA512:
6
- metadata.gz: 8d3f43f194866b90855ec27c36dfecdd3ba5131b424616f08eaf7ac0f75c02975d92553ae02f0f807246cfe61fd198ee2da06f6068b0e3d0e9c284f57ec41eca
7
- data.tar.gz: fa5e9708365a8ac529c0a67b8c46bbc3aa901c91dac6d01b706d390c1211a534887eedcfaf31cfcbe0fd3350e4f5d9b1d1047fb6303e1543c7a4ec38d9b9079b
6
+ metadata.gz: 2283d7f843cfec5c8de3cf92044a12ed3731474125c6fa70675476cbce028b6dc26d8bdfd6ceafd8dd940d2a33a7d763558834a7ecbc709ab72b1ebcba18dc0c
7
+ data.tar.gz: 5f22350ef473520e98f26facab2a7a583b07739f0aa03b9d0fb312199a696e074ae311191476883af12bd46b1bf2413e4c519dd997a257d9ddca52e022ce4222
data/DOC.md ADDED
@@ -0,0 +1,4 @@
1
+ ## Options
2
+
3
+ - `-i`, `--local-sets`: if several items are provided, they must be comma (`,`) separated. Items can be either a Bloodhound custom query file, a bqm or a folder. In case of a bqm query sets file (similar to `query-sets.json`) or a folder, bqm will try to parse all JSON files inside it, so the folder should not contain other types of JSON files.
4
+ - `--ignore-default`: ignore the default `query-sets.json`. It's useful for **offline** usage or if you don't want the default data sets.
data/bin/bqm CHANGED
@@ -14,13 +14,42 @@ def find_dataset
14
14
  raise IOError, "The dataset file #{source_file} does not exist or is unreadable."
15
15
  end
16
16
 
17
- def merge(source)
17
+ # Merge remote sets defined in data/query-sets.json
18
+ def merge_remote(source, verbose: false)
18
19
  sets = get_datasets(source)
19
20
  queries = []
20
21
  sets.each do |s|
21
22
  customqueries = Net::HTTP.get(URI(s))
22
23
  data = JSON.parse(customqueries)
23
24
  queries += data['queries']
25
+ puts " [*] File merged: #{s}" if verbose
26
+ end
27
+ queries
28
+ end
29
+
30
+ # Merge local sets provided by the user
31
+ def merge_local(sources, verbose: false)
32
+ queries = []
33
+ sources.each do |source|
34
+ # If it's a file parse it
35
+ if File.file?(source) && File.readable?(source)
36
+ data = json_load(source)
37
+ if data['queries']
38
+ queries += data['queries']
39
+ elsif data['sets']
40
+ queries += merge_remote(source, verbose: verbose)
41
+ else
42
+ raise KeyError, "The file #{source} is neiter a Bloodhound custom query file nor a bqm query sets file"
43
+ end
44
+ puts " [*] File merged: #{source}" if verbose
45
+ # If it's a folder, retrieve all JSON files and assumes there are queries files
46
+ # Then recursive call for a normal file parsing
47
+ elsif File.directory?(source) && File.readable?(source)
48
+ qfiles = Dir.glob('*.json', base: source).map { |f| File.absolute_path(f, source) }
49
+ queries += merge_local(qfiles, verbose: verbose)
50
+ else
51
+ raise IOError, "The dataset file/directory #{source} does not exist or is unreadable."
52
+ end
24
53
  end
25
54
  queries
26
55
  end
@@ -59,27 +88,40 @@ def pretty_link(lst)
59
88
  end
60
89
 
61
90
  def get_datasets(source)
91
+ src = json_load(source)
92
+ src['sets']
93
+ end
94
+
95
+ def json_load(file)
62
96
  # ruby 3.0+
63
97
  begin
64
- src = JSON.load_file(source)
98
+ src = JSON.load_file(file)
65
99
  rescue NoMethodError # ruby 2.7 retro-compatibility
66
- src = JSON.parse(File.read(source))
100
+ src = JSON.parse(File.read(file))
67
101
  end
68
- src['sets']
102
+ src
69
103
  end
70
104
 
71
105
  if __FILE__ == $PROGRAM_NAME
72
106
  source = find_dataset
73
107
 
74
108
  require 'optparse'
75
- options = {}
109
+ options = {
110
+ 'local-sets': []
111
+ }
76
112
  OptionParser.new do |parser|
77
113
  parser.banner = 'Usage: bqm [options]'
78
114
 
79
115
  parser.on('-o', '--output-path PATH', 'Path where to store the query file')
80
116
  parser.on('-l', '--list', 'List available datasets')
117
+ parser.on('-i', '--local-sets FILE,DIRECTORY,...', Array, 'Local custom queries files/directories') do |f|
118
+ options[:'local-sets'] += f
119
+ end
120
+ parser.on('--ignore-default', 'Ignore the default query-sets.json')
121
+ parser.on('-v', '--verbose', 'Display the name of the merged files/sets')
81
122
  parser.separator ''
82
123
  parser.separator 'Example: bqm -o ~/.config/bloodhound/customqueries.json'
124
+ parser.separator 'Example: bqm -o /tmp/customqueries.json -i /tmp/a.json,/home/user/folder'
83
125
  end.parse!(into: options)
84
126
 
85
127
  out = options[:'output-path']
@@ -95,15 +137,18 @@ if __FILE__ == $PROGRAM_NAME
95
137
  if File.file?(out) && File.readable?(out)
96
138
  puts "[+] The output path #{out} already exists"
97
139
  puts '[?] Do you want to overwrite it? [y/n]'
98
- if gets.chomp == 'y'
140
+ if $stdin.gets.chomp == 'y'
99
141
  puts '[?] What to do with the existing queries? (merge / discard) [m/d]'
100
- flags[:merge_actual] = true if gets.chomp == 'm'
142
+ flags[:merge_actual] = true if $stdin.gets.chomp == 'm'
101
143
  else
102
144
  exit
103
145
  end
104
146
  end
105
147
  puts '[+] Fetching and merging datasets'
106
- data = merge(source)
148
+ data = []
149
+ data = merge_remote(source, verbose: options[:verbose]) unless options[:'ignore-default']
150
+ local_set = options[:'local-sets']
151
+ data += merge_local(local_set, verbose: options[:verbose]) if local_set
107
152
  if flags[:merge_actual]
108
153
  puts '[+] Merging your existing queries'
109
154
  data += JSON.parse(File.read(out))['queries']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bqm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre ZANNI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-27 00:00:00.000000000 Z
11
+ date: 2023-06-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Deduplicate custom BloudHound queries from different datasets and merge
14
14
  them in one customqueries.json file.
@@ -18,6 +18,7 @@ executables:
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - DOC.md
21
22
  - LICENSE
22
23
  - bin/bqm
23
24
  - data/query-sets.json
@@ -26,6 +27,8 @@ licenses:
26
27
  - MIT
27
28
  metadata:
28
29
  bug_tracker_uri: https://github.com/Acceis/bqm/issues
30
+ changelog_uri: https://github.com/Acceis/bqm/releases
31
+ documentation_uri: https://acceis.github.io/bqm/
29
32
  homepage_uri: https://github.com/Acceis/bqm
30
33
  source_code_uri: https://github.com/Acceis/bqm/
31
34
  rubygems_mfa_required: 'true'