bqm 1.4.0 → 1.5.0
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 +4 -4
- data/DOC.md +4 -0
- data/bin/bqm +37 -21
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a14c962fd0bf2a8c456bf7b9ff5416036289f61a8d4030ed246a77b6115aec0
|
4
|
+
data.tar.gz: d9d0bf051756b2eba968cdb37945fd953db2746b646f6a9888c4100207979792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
@@ -15,30 +15,40 @@ def find_dataset
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# Merge remote sets defined in data/query-sets.json
|
18
|
-
def merge_remote(source)
|
18
|
+
def merge_remote(source, verbose: false)
|
19
19
|
sets = get_datasets(source)
|
20
20
|
queries = []
|
21
21
|
sets.each do |s|
|
22
22
|
customqueries = Net::HTTP.get(URI(s))
|
23
23
|
data = JSON.parse(customqueries)
|
24
24
|
queries += data['queries']
|
25
|
+
puts " [*] File merged: #{s}" if verbose
|
25
26
|
end
|
26
27
|
queries
|
27
28
|
end
|
28
29
|
|
29
30
|
# Merge local sets provided by the user
|
30
|
-
def merge_local(sources)
|
31
|
+
def merge_local(sources, verbose: false)
|
31
32
|
queries = []
|
32
33
|
sources.each do |source|
|
34
|
+
# If it's a file parse it
|
33
35
|
if File.file?(source) && File.readable?(source)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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"
|
38
43
|
end
|
39
|
-
|
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)
|
40
50
|
else
|
41
|
-
raise IOError, "The dataset file #{source} does not exist or is unreadable."
|
51
|
+
raise IOError, "The dataset file/directory #{source} does not exist or is unreadable."
|
42
52
|
end
|
43
53
|
end
|
44
54
|
queries
|
@@ -78,13 +88,18 @@ def pretty_link(lst)
|
|
78
88
|
end
|
79
89
|
|
80
90
|
def get_datasets(source)
|
91
|
+
src = json_load(source)
|
92
|
+
src['sets']
|
93
|
+
end
|
94
|
+
|
95
|
+
def json_load(file)
|
81
96
|
# ruby 3.0+
|
82
97
|
begin
|
83
|
-
src = JSON.load_file(
|
98
|
+
src = JSON.load_file(file)
|
84
99
|
rescue NoMethodError # ruby 2.7 retro-compatibility
|
85
|
-
src = JSON.parse(File.read(
|
100
|
+
src = JSON.parse(File.read(file))
|
86
101
|
end
|
87
|
-
src
|
102
|
+
src
|
88
103
|
end
|
89
104
|
|
90
105
|
if __FILE__ == $PROGRAM_NAME
|
@@ -92,19 +107,21 @@ if __FILE__ == $PROGRAM_NAME
|
|
92
107
|
|
93
108
|
require 'optparse'
|
94
109
|
options = {
|
95
|
-
|
110
|
+
'local-sets': []
|
96
111
|
}
|
97
112
|
OptionParser.new do |parser|
|
98
113
|
parser.banner = 'Usage: bqm [options]'
|
99
114
|
|
100
115
|
parser.on('-o', '--output-path PATH', 'Path where to store the query file')
|
101
116
|
parser.on('-l', '--list', 'List available datasets')
|
102
|
-
parser.on('-i', '--local-sets FILE,...', Array, 'Local custom queries files') do |f|
|
117
|
+
parser.on('-i', '--local-sets FILE,DIRECTORY,...', Array, 'Local custom queries files/directories') do |f|
|
103
118
|
options[:'local-sets'] += f
|
104
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')
|
105
122
|
parser.separator ''
|
106
123
|
parser.separator 'Example: bqm -o ~/.config/bloodhound/customqueries.json'
|
107
|
-
parser.separator 'Example: bqm -o /tmp/customqueries.json -i /tmp/a.json,/
|
124
|
+
parser.separator 'Example: bqm -o /tmp/customqueries.json -i /tmp/a.json,/home/user/folder'
|
108
125
|
end.parse!(into: options)
|
109
126
|
|
110
127
|
out = options[:'output-path']
|
@@ -120,20 +137,19 @@ if __FILE__ == $PROGRAM_NAME
|
|
120
137
|
if File.file?(out) && File.readable?(out)
|
121
138
|
puts "[+] The output path #{out} already exists"
|
122
139
|
puts '[?] Do you want to overwrite it? [y/n]'
|
123
|
-
if
|
140
|
+
if $stdin.gets.chomp == 'y'
|
124
141
|
puts '[?] What to do with the existing queries? (merge / discard) [m/d]'
|
125
|
-
flags[:merge_actual] = true if
|
142
|
+
flags[:merge_actual] = true if $stdin.gets.chomp == 'm'
|
126
143
|
else
|
127
144
|
exit
|
128
145
|
end
|
129
146
|
end
|
130
147
|
puts '[+] Fetching and merging datasets'
|
131
|
-
data =
|
148
|
+
data = []
|
149
|
+
data = merge_remote(source, verbose: options[:verbose]) unless options[:'ignore-default']
|
132
150
|
local_set = options[:'local-sets']
|
133
|
-
if local_set
|
134
|
-
|
135
|
-
end
|
136
|
-
if flags[:'merge_actual']
|
151
|
+
data += merge_local(local_set, verbose: options[:verbose]) if local_set
|
152
|
+
if flags[:merge_actual]
|
137
153
|
puts '[+] Merging your existing queries'
|
138
154
|
data += JSON.parse(File.read(out))['queries']
|
139
155
|
end
|
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.
|
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-06-
|
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
|