Skip to content

Commit b32ab15

Browse files
authored
Merge branch 'magicsword-io:main' into main
2 parents 786e572 + 1e51c74 commit b32ab15

File tree

793 files changed

+269066
-137958
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

793 files changed

+269066
-137958
lines changed

.DS_Store

6 KB
Binary file not shown.

.github/workflows/generate-site.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
with:
2121
python-version: 3.11
2222
- name: Install Poetry
23-
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
23+
run: curl -sSL https://install.python-poetry.org | python -
2424
- name: Install dependencies with Poetry
2525
run: poetry install
2626
- name: Run Site Generation

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
with:
1616
python-version: 3.11
1717
- name: Install Poetry
18-
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
18+
run: curl -sSL https://install.python-poetry.org | python -
1919
- name: Install dependencies with Poetry
2020
run: poetry install
2121
- name: Run YAML Checks
@@ -34,7 +34,7 @@ jobs:
3434
with:
3535
python-version: 3.11
3636
- name: Install Poetry
37-
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
37+
run: curl -sSL https://install.python-poetry.org | python -
3838
- name: Install dependencies with Poetry
3939
run: poetry install
4040
- name: Run Site Generation

.github/workflows/validate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
with:
2020
python-version: 3.11
2121
- name: Install Poetry
22-
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
22+
run: curl -sSL https://install.python-poetry.org | python -
2323
- name: Install dependencies with Poetry
2424
run: poetry install
2525
- name: Run YAML Checks

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,4 @@ dmypy.json
127127

128128
# Pyre type checker
129129
.pyre/
130+
.vscode/settings.json

YML-Template.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Name: FILENAME.sys # Example: ADV64DRV.sys
66
Author: Your Name # Example: John Doe
77
Created: 'YYYY-MM-DD' # Example: '2023-04-15'
88
MitreID: TXXXX # Example: T1000
9+
CVE:
10+
- CVE-XXXX-XXXX # Example: CVE-2023-20222
911
Category: Category Name # Example: vulnerable driver
1012
Verified: 'TRUE or FALSE' # Example: 'TRUE'
1113
Commands:

bin/enrich_with_yara.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import argparse
2+
import os
3+
import yaml
4+
5+
# Parse command-line arguments
6+
parser = argparse.ArgumentParser()
7+
parser.add_argument('-v', '--verbose', action='store_true', help='enable verbose output')
8+
args = parser.parse_args()
9+
10+
# Define the base URL for the GitHub repository and the full URLs for specific sigma and sysmon rules
11+
base_url = "https://github.com/magicsword-io/LOLDrivers/blob/main/"
12+
sigma_rules = [
13+
{"type": "sigma_hash", "value": base_url + "detections/sigma/driver_load_win_vuln_drivers.yml"},
14+
{"type": "sigma_names", "value": base_url + "detections/sigma/driver_load_win_vuln_drivers_names.yml"}
15+
]
16+
sysmon_rules = [
17+
{"type": "sysmon_hash_detect", "value": base_url + "detections/sysmon/sysmon_config_vulnerable_hashes.xml"},
18+
{"type": "sysmon_hash_block", "value": base_url + "detections/sysmon/sysmon_config_vulnerable_hashes_block.xml"}
19+
]
20+
21+
# Loop through each YAML file in the directory
22+
for file_name in os.listdir('yaml'):
23+
if file_name.endswith('.yaml') or file_name.endswith('.yml'):
24+
file_path = os.path.join('yaml', file_name)
25+
26+
# Load the YAML data from the file
27+
with open(file_path, 'r') as f:
28+
yaml_data = yaml.load(f, Loader=yaml.FullLoader)
29+
30+
# Check and update detections in YAML data
31+
updated = False
32+
for entry in yaml_data['KnownVulnerableSamples']:
33+
sha256 = entry.get('SHA256')
34+
if sha256:
35+
yara_file_path = os.path.join('detections/yara', f'{sha256}.yara')
36+
if os.path.exists(yara_file_path):
37+
updated = True
38+
if args.verbose:
39+
print(f"Updating file: {file_path}")
40+
yaml_data['Detection'].append({"type": "yara_signature", "value": base_url + yara_file_path})
41+
42+
# Add specific sigma and sysmon rules to detections
43+
yaml_data['Detection'].extend(sigma_rules)
44+
yaml_data['Detection'].extend(sysmon_rules)
45+
46+
# Save the updated YAML data back to the file
47+
if updated:
48+
with open(file_path, 'w') as f:
49+
yaml.dump(yaml_data, f, sort_keys=False)
50+

bin/gen-files.py

Lines changed: 100 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,39 @@ def gen_names_list():
3232
"""
3333
names_list = []
3434
for file in yield_next_rule_file_path(path_to_yml):
35+
category = get_yaml_part(file_path=file, part_name="Category")
3536
driver_name = get_yaml_part(file_path=file, part_name="Tags")[0]
36-
if driver_name:
37-
names_list.append(driver_name)
37+
if category != "Revoked Bootloaders":
38+
if driver_name:
39+
names_list.append(driver_name)
3840

3941
# Remove leading and trailing spaces as well as any duplicates
4042
names_list = list(set([i.lstrip().strip().lower() for i in names_list]))
4143

4244
return names_list
4345

44-
def gen_hashes_lists():
46+
def gen_hashes_lists(category_):
4547
"""
4648
Generates lists of hashes
4749
"""
4850
md5_list = []
4951
sha1_list = []
5052
sha256_list = []
5153
for file in yield_next_rule_file_path(path_to_yml):
52-
known_vuln_samples = get_yaml_part(file_path=file, part_name="KnownVulnerableSamples")
53-
if known_vuln_samples:
54-
for i in known_vuln_samples:
55-
if 'MD5' in i:
56-
if i['MD5'] != "-":
57-
md5_list.append(i['MD5'])
58-
if 'SHA1' in i:
59-
if i['SHA1'] != "-":
60-
sha1_list.append(i['SHA1'])
61-
if 'SHA256' in i:
62-
if i['SHA256'] != "-":
63-
sha256_list.append(i['SHA256'])
54+
category = get_yaml_part(file_path=file, part_name="Category")
55+
if category_.lower() == category.lower():
56+
known_vuln_samples = get_yaml_part(file_path=file, part_name="KnownVulnerableSamples")
57+
if known_vuln_samples:
58+
for i in known_vuln_samples:
59+
if 'MD5' in i:
60+
if i['MD5'] != "-":
61+
md5_list.append(i['MD5'])
62+
if 'SHA1' in i:
63+
if i['SHA1'] != "-":
64+
sha1_list.append(i['SHA1'])
65+
if 'SHA256' in i:
66+
if i['SHA256'] != "-":
67+
sha256_list.append(i['SHA256'])
6468

6569
# Remove leading and trailing spaces as well as any duplicates
6670
md5_list = list(filter(None,list(set([i.lstrip().strip().lower() for i in md5_list]))))
@@ -69,7 +73,7 @@ def gen_hashes_lists():
6973

7074
return md5_list, sha1_list, sha256_list
7175

72-
def gen_authentihash_lists():
76+
def gen_authentihash_lists(category_):
7377
"""
7478
Generates lists of authentihash
7579
"""
@@ -78,18 +82,20 @@ def gen_authentihash_lists():
7882
authentihash_sha256_list = []
7983
for file in yield_next_rule_file_path(path_to_yml):
8084
known_vuln_samples = get_yaml_part(file_path=file, part_name="KnownVulnerableSamples")
81-
if known_vuln_samples:
82-
for i in known_vuln_samples:
83-
if 'Authentihash' in i:
84-
for key, value in i['Authentihash'].items():
85-
if key == "MD5" and value != "-":
86-
authentihash_md5_list.append(value)
87-
if key == "SHA1" and value != "-":
88-
if i['SHA1'] != "-":
89-
authentihash_sha1_list.append(value)
90-
if key == "SHA256" and value != "-":
91-
if i['SHA256'] != "-":
92-
authentihash_sha256_list.append(value)
85+
category = get_yaml_part(file_path=file, part_name="Category")
86+
if category_.lower() == category.lower():
87+
if known_vuln_samples:
88+
for i in known_vuln_samples:
89+
if 'Authentihash' in i:
90+
for key, value in i['Authentihash'].items():
91+
if key == "MD5" and value != "-":
92+
authentihash_md5_list.append(value)
93+
if key == "SHA1" and value != "-":
94+
if i['SHA1'] != "-":
95+
authentihash_sha1_list.append(value)
96+
if key == "SHA256" and value != "-":
97+
if i['SHA256'] != "-":
98+
authentihash_sha256_list.append(value)
9399

94100
# Remove leading and trailing spaces as well as any duplicates
95101
authentihash_md5_list = list(set([i.lstrip().strip().lower() for i in authentihash_md5_list]))
@@ -98,71 +104,76 @@ def gen_authentihash_lists():
98104

99105
return authentihash_md5_list, authentihash_sha1_list, authentihash_sha256_list
100106

101-
def gen_hashes_files(md5_list, sha1_list, sha256_list):
107+
def gen_hashes_files(md5_list, sha1_list, sha256_list, name):
102108
"""
103109
Generates hash samples files
104110
"""
111+
directory = 'detections/hashes/'
112+
os.makedirs(directory, exist_ok=True) # Create the directory if it doesn't exist
105113

106114
if md5_list:
107-
with open('detections/hashes/samples.md5', 'w') as f:
115+
with open(f'detections/hashes/{name}.md5', 'w') as f:
108116
for i in md5_list:
109117
if i != "-":
110118
f.write(i + "\n")
111119

112120
if sha1_list:
113-
with open('detections/hashes/samples.sha1', 'w') as f:
121+
with open(f'detections/hashes/{name}.sha1', 'w') as f:
114122
for i in sha1_list:
115123
if i != "-":
116124
f.write(i + "\n")
117125

118126
if sha256_list:
119-
with open('detections/hashes/samples.sha256', 'w') as f:
127+
with open(f'detections/hashes/{name}.sha256', 'w') as f:
120128
for i in sha256_list:
121129
if i != "-":
122130
f.write(i + "\n")
123131

124132
all_hashes = list(set(md5_list + sha1_list + sha256_list))
125133
if all_hashes:
126-
with open('detections/hashes/samples.all', 'w') as f:
134+
with open(f'detections/hashes/{name}.all', 'w') as f:
127135
for i in all_hashes:
128136
if i != "-":
129137
f.write(i + "\n")
130138

131-
def gen_authentihash_file(authentihash_md5_list, authentihash_sha1_list, authentihash_sha256_list):
139+
def gen_authentihash_file(authentihash_md5_list, authentihash_sha1_list, authentihash_sha256_list, name):
132140
"""
133141
Generates hash samples files
134142
"""
135143

136144
if authentihash_md5_list:
137-
with open('detections/hashes/authentihash_samples.md5', 'w') as f:
145+
with open(f'detections/hashes/{name}.md5', 'w') as f:
138146
for i in authentihash_md5_list:
139147
if i != "-":
140148
f.write(i + "\n")
141149

142150
if authentihash_sha1_list:
143-
with open('detections/hashes/authentihash_samples.sha1', 'w') as f:
151+
with open(f'detections/hashes/{name}.sha1', 'w') as f:
144152
for i in authentihash_sha1_list:
145153
if i != "-":
146154
f.write(i + "\n")
147155

148156
if authentihash_sha256_list:
149-
with open('detections/hashes/authentihash_samples.sha256', 'w') as f:
157+
with open(f'detections/hashes/{name}.sha256', 'w') as f:
150158
for i in authentihash_sha256_list:
151159
if i != "-":
152160
f.write(i + "\n")
153161

154162
all_hashes = list(set(authentihash_md5_list + authentihash_sha1_list + authentihash_sha256_list))
155163
if all_hashes:
156-
with open('detections/hashes/authentihash_samples.all', 'w') as f:
164+
with open(f'detections/hashes/{name}.all', 'w') as f:
157165
for i in all_hashes:
158166
if i != "-":
159167
f.write(i + "\n")
160168

161-
def gen_sysmon_driver_load_config(md5_list, sha1_list, sha256_list):
169+
def gen_sysmon_driver_load_config(md5_list, sha1_list, sha256_list, name):
162170
"""
163171
Generates sysmon driver load configuration
164172
"""
165-
with open("detections/sysmon/sysmon_config_vulnerable_hashes.xml", "w") as f:
173+
directory = 'detections/sysmon/'
174+
os.makedirs(directory, exist_ok=True) # Create the directory if it doesn't exist
175+
176+
with open(f"detections/sysmon/{name}.xml", "w") as f:
166177
f.write("<Sysmon schemaversion=\"4.30\">\n")
167178
f.write(" <EventFiltering>\n")
168179
f.write(" <RuleGroup name=\"\" groupRelation=\"or\">\n")
@@ -188,11 +199,11 @@ def gen_sysmon_driver_load_config(md5_list, sha1_list, sha256_list):
188199
f.write(" </EventFiltering>\n")
189200
f.write("</Sysmon>\n")
190201

191-
def gen_sysmon_block_config(md5_list, sha1_list, sha256_list):
202+
def gen_sysmon_block_config(md5_list, sha1_list, sha256_list, name):
192203
"""
193204
Generates sysmon blocking configuration
194205
"""
195-
with open("detections/sysmon/sysmon_config_vulnerable_hashes_block.xml", "w") as f:
206+
with open(f"detections/sysmon/{name}.xml", "w") as f:
196207
f.write("<Sysmon schemaversion=\"4.82\">\n")
197208
f.write(" <EventFiltering>\n")
198209
f.write(" <RuleGroup name=\"\" groupRelation=\"or\">\n")
@@ -218,16 +229,18 @@ def gen_sysmon_block_config(md5_list, sha1_list, sha256_list):
218229
f.write(" </EventFiltering>\n")
219230
f.write("</Sysmon>\n")
220231

221-
def gen_sigma_rule_hashes(md5_list, sha1_list, sha256_list):
232+
def gen_sigma_rule_hashes(md5_list, sha1_list, sha256_list, name, uuid, title, description):
222233
"""
223234
Generates DriverLoad SIGMA rule based on driver hashes
224235
"""
236+
directory = 'detections/sigma/'
237+
os.makedirs(directory, exist_ok=True) # Create the directory if it doesn't exist
225238
if md5_list or sha1_list or sha256_list:
226-
with open("detections/sigma/driver_load_win_vuln_drivers.yml", "w") as f:
227-
f.write("title: Vulnerable Driver Load\n")
228-
f.write("id: 7aaaf4b8-e47c-4295-92ee-6ed40a6f60c8\n")
239+
with open(f"detections/sigma/{name}.yml", "w") as f:
240+
f.write(f"title: {title}\n")
241+
f.write(f"id: {uuid}\n")
229242
f.write("status: experimental\n")
230-
f.write("description: Detects the load of known vulnerable drivers by hash value\n")
243+
f.write(f"description: {description}\n")
231244
f.write("references:\n")
232245
f.write(" - https://loldrivers.io/\n")
233246
f.write("author: Nasreddine Bencherchali (Nextron Systems)\n")
@@ -318,12 +331,45 @@ def gen_sigma_rule_names(names_list):
318331

319332

320333
if __name__ == "__main__":
321-
md5_list, sha1_list, sha256_list = gen_hashes_lists()
322-
authentihash_md5_list, authentihash_sha1_list, authentihash_sha256_list = gen_authentihash_lists()
334+
335+
# GOOTS LOVER
336+
337+
print("[+] Generating hash lists...")
338+
md5_list_boots, sha1_list_boots, sha256_list_boots = gen_hashes_lists("Revoked Bootloaders")
339+
md5_list_malicious, sha1_list_malicious, sha256_list_malicious = gen_hashes_lists("malicious")
340+
md5_list_vulnerable, sha1_list_vulnerable, sha256_list_vulnerable = gen_hashes_lists("vulnerable driver")
341+
342+
print("[+] Generating authentihash lists...")
343+
authentihash_md5_list_boots, authentihash_sha1_list_boots, authentihash_sha256_list_boots = gen_authentihash_lists("Revoked Bootloaders")
344+
authentihash_md5_list_malicious, authentihash_sha1_list_malicious, authentihash_sha256_list_malicious = gen_authentihash_lists("malicious")
345+
authentihash_md5_list_vulnerable, authentihash_sha1_list_vulnerable, authentihash_sha256_list_vulnerable = gen_authentihash_lists("vulnerable driver")
346+
323347
names_list = gen_names_list()
324-
gen_hashes_files(md5_list, sha1_list, sha256_list)
325-
gen_authentihash_file(authentihash_md5_list, authentihash_sha1_list, authentihash_sha256_list)
326-
gen_sysmon_driver_load_config(md5_list, sha1_list, sha256_list)
327-
gen_sysmon_block_config(md5_list, sha1_list, sha256_list)
328-
gen_sigma_rule_hashes(md5_list, sha1_list, sha256_list)
348+
349+
print("[+] Generating hash samples...")
350+
# samples
351+
gen_hashes_files(md5_list_boots, sha1_list_boots, sha256_list_boots, "samples_boots")
352+
gen_hashes_files(md5_list_vulnerable, sha1_list_vulnerable, sha256_list_vulnerable, "samples_vulnerable")
353+
gen_hashes_files(md5_list_malicious, sha1_list_malicious, sha256_list_malicious, "samples_malicious")
354+
355+
print("[+] Generating authentihash samples...")
356+
# authentihash_samples
357+
gen_authentihash_file(authentihash_md5_list_boots, authentihash_sha1_list_boots, authentihash_sha256_list_boots, "authentihash_samples_boots")
358+
gen_authentihash_file(authentihash_md5_list_vulnerable, authentihash_sha1_list_vulnerable, authentihash_sha256_list_vulnerable, "authentihash_samples_vulnerable")
359+
gen_authentihash_file(authentihash_md5_list_malicious, authentihash_sha1_list_malicious, authentihash_sha256_list_malicious, "authentihash_samples_malicious")
360+
361+
print("[+] Generating Sysmon configurations...")
362+
# sysmon_config_vulnerable_hashes
363+
gen_sysmon_driver_load_config(md5_list_vulnerable, sha1_list_vulnerable, sha256_list_vulnerable, "sysmon_config_vulnerable_hashes")
364+
gen_sysmon_driver_load_config(md5_list_malicious, sha1_list_malicious, sha256_list_malicious, "sysmon_config_malicious_hashes")
365+
366+
# sysmon_config_vulnerable_hashes_block
367+
gen_sysmon_block_config(md5_list_vulnerable, sha1_list_vulnerable, sha256_list_vulnerable, "sysmon_config_vulnerable_hashes_block")
368+
gen_sysmon_block_config(md5_list_malicious, sha1_list_malicious, sha256_list_malicious, "sysmon_config_malicious_hashes_block")
369+
370+
print("[+] Generating Sigma rules...")
371+
# driver_load_win_vuln_drivers
372+
gen_sigma_rule_hashes(md5_list_vulnerable, sha1_list_vulnerable, sha256_list_vulnerable, "driver_load_win_vuln_drivers", "7aaaf4b8-e47c-4295-92ee-6ed40a6f60c8", "Vulnerable Driver Load", "Detects the load of known vulnerable drivers by hash value")
373+
gen_sigma_rule_hashes(md5_list_malicious, sha1_list_malicious, sha256_list_malicious, "driver_load_win_mal_drivers", "05296024-fe8a-4baf-8f3d-9a5f5624ceb2", "Malicious Driver Load", "Detects the load of known malicious drivers by hash value")
374+
329375
gen_sigma_rule_names(names_list)

0 commit comments

Comments
 (0)