Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit f276bbd

Browse files
committed
Added profiles, refactored services
1 parent 4c86765 commit f276bbd

28 files changed

+347
-210
lines changed

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ A powerful, modular, and extensible vulnerability assessment and vulnerability i
1212
- **Enrichment Capabilities**: Enhance CVE details with severity metrics, reference URLs, available exploits, and mitigations, enabling you to produce actionable intelligence.
1313
- **Caching and Optimization**: Uses smart caching, and reads straight from compressed archives to minimize API requests and optimize performance, enabling you to use it in air-gapped networks.
1414
- **Flexible Configuration**: Enable or disable providers and enrichment sources as needed.
15+
- **Profiles**: Create profiles, for example "offline" that uses only offline resources, "normal" that uses online resources, "stable" that does not update automatically, and more.
1516
- **CLI Simplicity**: Intuitive command-line interface for streamlined operations.
1617
- **Reports**: Create vulnerability reports with ease.
1718

1819
# Use Case Scenarios
1920

21+
- Look up vulnerabilities for a specified product, version, identifier, and more.
2022
- Research vulnerabilities and associated metadata.
21-
- Product vulnerability background checking.
2223
- Automate vulnerability triaging and reporting.
2324
- Gain insights for security monitoring and proactive threat mitigation.
2425

@@ -28,13 +29,22 @@ A powerful, modular, and extensible vulnerability assessment and vulnerability i
2829
```bash
2930
pip3 install -r requirements.txt
3031

32+
On first run, the offline dataset will be downloaded automatically. The default profile is stable, you can change it in config.yaml. The stable profile does not auto-update when cache duration passes, so it is manual work to run --autoupdate or --reload. Each provider has different cache duration. In order to use online providers and update automatically, use "normal" profile.
33+
34+
In order to use only local resources, use offline profile.
35+
3136
python3 cveseeker.py <keywords>
3237
python3 cveseeker.py windows smbv1
3338
python3 cveseeker.py windows remote code execution
3439
python3 cveseeker.py cve-2024
40+
python3 cveseeker.py cve-2024 --reload # Override force re-download the dataset on next run
41+
python3 cveseeker.py cve-2024 --autoupdate # Override allow auto-updating the dataset on next run
42+
python3 cveseeker.py cve-2024 --no-autoupdate # Override do not allow updating the dataset on next run
43+
python3 cveseeker.py cve-2024 --offline # offline mode - do not update, do not use online providers on next run. same as --profile offline
44+
python3 cveseeker.py cve-2024 --profile [normal, stable, offline, debug, ...] # select a profile. modify profiles.yaml to add more. Profiles modify config.
3545
python3 cveseeker.py cve-2024 --max-per-provider 2000 # max results per provider, default 100
3646
python3 cveseeker.py cve-2024 --report # generate CSV, JSON and HTML report
37-
python3 cveseeker.py cve-2024 --critical --high --medium --low # include critical, high, medium, and low severities
47+
python3 cveseeker.py cve-2024 --critical --high --medium --low # include critical, high, medium, or low severities
3848
```
3949

4050
# Sources

config.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
default_profile: stable
2+
cache_dir: "dataset"
3+
14
providers:
25
NistAPI: false
36
NistCachedAPI: true
@@ -17,4 +20,7 @@ enrichment:
1720
cisa_kev: true
1821
github_poc: false
1922
github_poc_cached: true
20-
nist_cached: true
23+
nist_cached: true
24+
25+
reload: false
26+
autoupdate: true

cveseeker.py

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import argparse
2+
from services.config.config import configure_on_first_run, load_config, update_config
3+
from services.profile import profile_guard
4+
from services.profile.profile import load_profiles
25
from providers.search_provider import SearchProvider
36
from services.vulnerability_intelligence.reports.vulnerability_intelligence_report_service import VulnerabilityIntelligenceReportService
47
from services.vulnerability_intelligence.printers.vulnerability_intelligence_printer import VulnerabilityIntelligencePrinter
58
from terminal import logo
9+
from terminal.cli import print_configuration, print_wrong_profile
610

711
def main():
12+
config = load_config('config.yaml')
13+
profiles = load_profiles("profiles.yaml")
14+
815
parser = argparse.ArgumentParser(description="Search for vulnerabilities using keywords.")
916

1017
parser.add_argument(
1118
'keywords',
1219
nargs='+',
13-
help='List of keywords to search for (e.g., Windows RCE)'
20+
help='List of keywords to search for (e.g., Microsoft Windows Remote Code Execution)'
1421
)
1522

1623
parser.add_argument(
@@ -27,25 +34,78 @@ def main():
2734
help="Generate CSV report"
2835
)
2936

30-
parser.add_argument('--low', action='store_true', help='Include low severity vulnerabilities')
31-
parser.add_argument('--medium', action='store_true', help='Include medium severity vulnerabilities')
32-
parser.add_argument('--high', action='store_true', help='Include high severity vulnerabilities')
33-
parser.add_argument('--critical', action='store_true', help='Include critical severity vulnerabilities')
37+
parser.add_argument(
38+
'--reload',
39+
action="store_true",
40+
default=False,
41+
help="Override - Force reload, update, download the dataset."
42+
)
43+
44+
parser.add_argument(
45+
'--no-autoupdate',
46+
action="store_true",
47+
default=False,
48+
help="Override - Do not allow auto-updating the dataset on next run."
49+
)
50+
51+
parser.add_argument(
52+
'--autoupdate',
53+
action="store_true",
54+
default=False,
55+
help="Override - Allow auto-updating the dataset on next run."
56+
)
3457

3558
parser.add_argument(
36-
'--playwright',
59+
'--offline',
3760
action="store_true",
3861
default=False,
39-
help="Utilize Playwright to use more sources (does nothing at the moment)"
62+
help="Offline mode - do not update, do not use online providers. Same as --profile offline"
4063
)
4164

65+
parser.add_argument(
66+
'--profile',
67+
type=str,
68+
help="Max results per provider",
69+
default=config.get("default_profile")
70+
)
71+
72+
parser.add_argument('--low', action='store_true', help='Include low severity vulnerabilities')
73+
parser.add_argument('--medium', action='store_true', help='Include medium severity vulnerabilities')
74+
parser.add_argument('--high', action='store_true', help='Include high severity vulnerabilities')
75+
parser.add_argument('--critical', action='store_true', help='Include critical severity vulnerabilities')
76+
4277
logo.print_logo()
4378

4479
args = parser.parse_args()
4580

4681
keywords = args.keywords
82+
83+
profilename = args.profile
84+
85+
if args.offline:
86+
profilename = "offline"
87+
88+
profile = profiles.get(profilename)
4789

48-
search_provider = SearchProvider(playwright_enabled=args.playwright, config_file='config.yaml')
90+
if not profile:
91+
print_wrong_profile(profiles)
92+
exit(1)
93+
94+
profile_guard.enforce_profile(config, profile)
95+
96+
if args.reload:
97+
update_config(config, {"reload": True})
98+
99+
if args.autoupdate:
100+
update_config(config, {"autoupdate": True})
101+
102+
if args.no_autoupdate:
103+
update_config(config, {"autoupdate": False})
104+
105+
configure_on_first_run(config)
106+
print_configuration(profilename, config)
107+
108+
search_provider = SearchProvider(config)
49109
search_service = search_provider.make_service_api()
50110

51111
desired_severities = [
@@ -65,6 +125,5 @@ def main():
65125
VulnerabilityIntelligenceReportService.generate_json_report(results, filename_json)
66126
VulnerabilityIntelligenceReportService.generate_html_report(results, " ".join(keywords), filename_html)
67127

68-
69128
if __name__ == "__main__":
70129
main()

profiles.yaml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
offline:
2+
providers:
3+
NistAPI: false
4+
NistCachedAPI: true
5+
PacketStormSecurityAPI: false
6+
OpenCVEAPI: false
7+
ExploitDBAPI: false
8+
GitHubAdvisoryAPI: false
9+
VulnersAPI: false
10+
CISAKEVAPI: true
11+
RAPID7: false
12+
13+
enrichment:
14+
sources:
15+
vulners: false
16+
trickest_cve_github: false
17+
trickest_cve_github_cached: true
18+
cisa_kev: true
19+
github_poc: false
20+
github_poc_cached: true
21+
nist_cached: true
22+
23+
autoupdate: false
24+
reload: false
25+
26+
normal:
27+
providers:
28+
NistAPI: false
29+
NistCachedAPI: true
30+
PacketStormSecurityAPI: true
31+
OpenCVEAPI: true
32+
ExploitDBAPI: true
33+
GitHubAdvisoryAPI: true
34+
VulnersAPI: false
35+
CISAKEVAPI: true
36+
RAPID7: true
37+
38+
enrichment:
39+
sources:
40+
vulners: true
41+
trickest_cve_github: false
42+
trickest_cve_github_cached: true
43+
cisa_kev: true
44+
github_poc: false
45+
github_poc_cached: true
46+
nist_cached: true
47+
48+
reload: false
49+
autoupdate: true
50+
51+
stable:
52+
providers:
53+
NistAPI: false
54+
NistCachedAPI: true
55+
PacketStormSecurityAPI: true
56+
OpenCVEAPI: true
57+
ExploitDBAPI: true
58+
GitHubAdvisoryAPI: true
59+
VulnersAPI: false
60+
CISAKEVAPI: true
61+
RAPID7: true
62+
63+
enrichment:
64+
sources:
65+
vulners: true
66+
trickest_cve_github: false
67+
trickest_cve_github_cached: true
68+
cisa_kev: true
69+
github_poc: false
70+
github_poc_cached: true
71+
nist_cached: true
72+
73+
reload: false
74+
autoupdate: false
75+
76+
debug:
77+
providers:
78+
NistAPI: false
79+
NistCachedAPI: true
80+
PacketStormSecurityAPI: false
81+
OpenCVEAPI: false
82+
ExploitDBAPI: false
83+
GitHubAdvisoryAPI: false
84+
VulnersAPI: false
85+
CISAKEVAPI: false
86+
RAPID7: false
87+
88+
enrichment:
89+
sources:
90+
vulners: false
91+
trickest_cve_github: false
92+
trickest_cve_github_cached: false
93+
cisa_kev: false
94+
github_poc: false
95+
github_poc_cached: false
96+
nist_cached: false
97+
98+
reload: false
99+
autoupdate: false

providers/search_provider.py

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010
from services.api.sources.rapid7 import RAPID7
1111
from services.api.sources.vulners import VulnersAPI
1212

13-
from typing import Dict
14-
1513
from services.cache.cache_manager import CacheManager
1614
from services.search.engine.progress_factory import ProgressManagerFactory
1715
from services.search.search_manager import SearchManager
18-
from services.search.engine.progress_manager import ProgressManager
16+
from terminal.cli import print_greyed_out
1917

2018
class SearchProvider:
21-
def __init__(self, playwright_enabled=False, config_file='config.yaml'):
19+
def __init__(self, config):
2220
self.search_service: SearchManager = None
23-
self.playwright_enabled = playwright_enabled
24-
self.config_file = config_file
21+
self.config = config
2522

2623
self.provider_registry = {
2724
'NistAPI': NistAPI,
@@ -41,7 +38,7 @@ def make_service_api(self) -> SearchManager:
4138
return self.search_service
4239

4340
def boot(self):
44-
config = self.load_config()
41+
config = self.config
4542
providers_config = config.get('providers', {})
4643
enrichment_config = config.get("enrichment", {})
4744

@@ -54,32 +51,16 @@ def boot(self):
5451
provider_class = self.provider_registry.get(provider_name)
5552
if provider_class:
5653
if provider_name in [
57-
'NistCachedAPI',
58-
'CISAKEVAPI'
59-
]:
60-
providers.append(provider_class(cache_manager))
54+
'NistCachedAPI',
55+
'CISAKEVAPI'
56+
]:
57+
providers.append(provider_class(config, cache_manager))
6158
else:
62-
providers.append(provider_class())
59+
providers.append(provider_class(config))
6360
else:
6461
print(f"[!] Provider '{provider_name}' not found in registry.")
6562
else:
66-
print(f"[-] Provider '{provider_name}' is disabled in configuration.")
67-
68-
if self.playwright_enabled:
69-
playwright_providers = []
70-
providers.extend(playwright_providers)
63+
print_greyed_out(f"[-] Provider '{provider_name}' is disabled in configuration.")
7164

7265
progress_manager_factory = ProgressManagerFactory()
7366
self.search_service = SearchManager(providers, enrichment_config, progress_manager_factory=progress_manager_factory, cache_manager=cache_manager)
74-
75-
def load_config(self) -> Dict:
76-
try:
77-
with open(self.config_file, 'r') as f:
78-
config = yaml.safe_load(f)
79-
return config
80-
except FileNotFoundError:
81-
print(f"[!] Config file '{self.config_file}' not found. Using default settings.")
82-
return {}
83-
except yaml.YAMLError as exc:
84-
print(f"[!] Error parsing config file: {exc}")
85-
return {}

0 commit comments

Comments
 (0)