Skip to content

Commit d0d9e73

Browse files
committed
v0.10
1 parent 501be8e commit d0d9e73

File tree

4 files changed

+114
-32
lines changed

4 files changed

+114
-32
lines changed

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ SploitScan is a powerful and user-friendly tool designed to streamline the proce
2727
- **EPSS Integration**: Includes Exploit Prediction Scoring System (EPSS) data, offering a probability score for the likelihood of CVE exploitation, aiding in prioritization.
2828
- **Public Exploits Aggregation**: Gathers publicly available exploits, enhancing the understanding of vulnerabilities.
2929
- **CISA KEV**: Shows if the CVE has been listed in the Known Exploited Vulnerabilities (KEV) of CISA.
30+
- **AI-Powered Risk Assessment**: Leverages OpenAI to provide detailed risk assessments, potential attack scenarios, mitigation recommendations, and executive summaries.
31+
- **HackerOne Reports**: Shows if the CVE was used within HackerOne Bug Bounty programs and their total rank overall.
3032
- **Patching Priority System**: Evaluates and assigns a priority rating for patching based on various factors including public exploits availability.
3133
- **Multi-CVE Support and Export Options**: Supports multiple CVEs in a single run and allows exporting the results to HTML, JSON and CSV formats.
3234
- **Vulnerability Scanner Import**: Import vulnerability scans from popular vulnerability scanners and search directly for known exploits.
33-
- **AI-Powered Risk Assessment**: Leverages OpenAI to provide detailed risk assessments, potential attack scenarios, mitigation recommendations, and executive summaries.
3435
- **User-Friendly Interface**: Easy to use, providing clear and concise information.
3536
- **Comprehensive Security Tool**: Ideal for quick security assessments and staying informed about recent vulnerabilities.
3637

@@ -98,9 +99,9 @@ $ sploitscan.py -h
9899
╚════██║██╔═══╝ ██║ ██║ ██║██║ ██║ ╚════██║██║ ██╔══██║██║╚██╗██║
99100
███████║██║ ███████╗╚██████╔╝██║ ██║ ███████║╚██████╗██║ ██║██║ ╚████║
100101
╚══════╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝
101-
v0.9 / Alexander Hagenah / @xaitax / [email protected]
102+
v0.10 / Alexander Hagenah / @xaitax / [email protected]
102103

103-
usage: sploitscan.py [-h] [-e {json,JSON,csv,CSV,html,HTML}] [-t {nessus,nexpose,openvas,docker}] [-i IMPORT_FILE] [cve_ids ...]
104+
usage: sploitscan.py [-h] [-e {json,JSON,csv,CSV,html,HTML}] [-t {nessus,nexpose,openvas,docker}] [-i IMPORT_FILE] [-d] [cve_ids ...]
104105

105106
SploitScan: Retrieve and display vulnerability data as well as public exploits for given CVE ID(s).
106107

@@ -116,6 +117,7 @@ options:
116117
Specify the type of the import file: 'nessus', 'nexpose', 'openvas' or 'docker'.
117118
-i IMPORT_FILE, --import-file IMPORT_FILE
118119
Path to an import file from a vulnerability scanner. If used, CVE IDs can be omitted from the command line arguments.
120+
-d, --debug Enable debug output.
119121
```
120122
121123
### Single CVE Query
@@ -247,6 +249,11 @@ This system assists users in making informed decisions on which vulnerabilities
247249

248250
## 📆 Changelog
249251

252+
### [26. June 2024] - Version 0.10
253+
254+
- **HackerOne Integration**: Added support for searching through HackerOne and displays if the CVE was used in any Bug Bounty program including its rank.
255+
- **General Improvements**: Various bug fixes.
256+
250257
### [24. May 2024] - Version 0.9
251258

252259
- **AI-Powered Risk Assessment**: Integrated OpenAI for detailed risk assessments, potential attack scenarios, mitigation recommendations, and executive summaries (needs OpenAI API key).
@@ -329,12 +336,14 @@ Special thanks to:
329336

330337
## 📚 References
331338

339+
- [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
332340
- [CVE Program](https://github.com/CVEProject/cvelistV5)
341+
- [ExploitDB](https://www.exploit-db.com/)
333342
- [FIRST EPSS](https://www.first.org/epss/api)
334-
- [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
343+
- [HackerOne](https://hackerone.com/)
335344
- [nomi-sec PoC-in-GitHub API](https://poc-in-github.motikan2010.net/)
336-
- [VulnCheck](https://vulncheck.com/)
337-
- [ExploitDB](https://www.exploit-db.com/)
338-
- [ProjectDiscovery Nuclei](https://github.com/projectdiscovery/nuclei-templates)
339-
- [Packet Storm](https://packetstormsecurity.com/)
340345
- [OpenAI](https://openai.com/)
346+
- [Packet Storm](https://packetstormsecurity.com/)
347+
- [ProjectDiscovery Nuclei](https://github.com/projectdiscovery/nuclei-templates)
348+
- [VulnCheck](https://vulncheck.com/)
349+

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "sploitscan"
7-
version = "0.9.1"
7+
version = "0.10.0"
88
description = "SploitScan is a sophisticated cybersecurity utility designed to provide detailed information on vulnerabilities and associated exploits."
99
authors = [ { name = "Alexander Hagenah", email = "[email protected]" } ]
1010
license = { file = "LICENSE" }

sploitscan/sploitscan.py

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from jinja2 import Environment, FileSystemLoader
1414

1515

16-
VERSION = "0.9"
16+
VERSION = "0.10"
1717

1818
BLUE = "\033[94m"
1919
GREEN = "\033[92m"
@@ -30,6 +30,7 @@
3030
VULNCHECK_API_URL = "https://api.vulncheck.com/v3/index/vulncheck-kev"
3131
EXPLOITDB_URL = "https://gitlab.com/exploit-database/exploitdb/-/raw/main/files_exploits.csv?ref_type=heads"
3232
PACKETSTORM_URL = "https://packetstormsecurity.com/search/?q={cve_id}"
33+
HACKERONE_URL = "https://hackerone.com/graphql"
3334

3435
CVSS_THRESHOLD = 6.0
3536
EPSS_THRESHOLD = 0.2
@@ -138,6 +139,40 @@ def fetch_packetstorm_data(cve_id):
138139
else {}
139140
), None
140141

142+
def fetch_hackerone_cve_details(cve_id):
143+
headers = {
144+
'content-type': 'application/json'
145+
}
146+
payload = {
147+
"operationName": "CveDiscoveryDetailedViewCveEntry",
148+
"variables": {
149+
"cve_id": cve_id
150+
},
151+
"query": """
152+
query CveDiscoveryDetailedViewCveEntry($cve_id: String!) {
153+
cve_entry(cve_id: $cve_id) {
154+
rank
155+
reports_submitted_count
156+
__typename
157+
}
158+
}
159+
"""
160+
}
161+
162+
response = requests.post(HACKERONE_URL, headers=headers, json=payload)
163+
164+
if response.status_code == 200:
165+
try:
166+
data = response.json()
167+
if 'data' in data and 'cve_entry' in data['data']:
168+
return data, None
169+
else:
170+
return None, "❌ No HackerOne data found for this CVE."
171+
except json.JSONDecodeError as e:
172+
return None, f"❌ Error parsing JSON data from HackerOne: {e}"
173+
else:
174+
return None, f"❌ Error fetching data from HackerOne: {response.status_code}: {response.text}"
175+
141176

142177
def display_data(title, data, template, error=None):
143178
print(f"┌───[ {BLUE}{title}{ENDC} ]")
@@ -327,6 +362,26 @@ def template(data):
327362
display_data("⚛️ Nuclei Template", nuclei_data, template, error)
328363

329364

365+
def display_hackerone_data(hackerone_data, error=None):
366+
def template(data):
367+
if not data or "data" not in data or "cve_entry" not in data["data"]:
368+
return ["└ ❌ No data found."]
369+
370+
cve_entry = data["data"]["cve_entry"]
371+
if not cve_entry:
372+
return ["└ ❌ No data found."]
373+
374+
rank = cve_entry.get("rank", "N/A")
375+
reports_submitted_count = cve_entry.get("reports_submitted_count", "N/A")
376+
return [
377+
f"├ Rank: {rank}",
378+
f"└ Reports: {reports_submitted_count}",
379+
]
380+
381+
display_data("🕵️ HackerOne Hacktivity", hackerone_data, template, error)
382+
383+
384+
330385
def display_cve_references(cve_data, error=None):
331386
def template(data):
332387
if not data or "containers" not in data or "cna" not in data["containers"]:
@@ -731,8 +786,7 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
731786
cve_id = cve_id.upper()
732787
if not is_valid_cve_id(cve_id):
733788
print(
734-
f"❌ Invalid CVE ID format: {
735-
cve_id}. Please use the format CVE-YYYY-NNNNN."
789+
f"❌ Invalid CVE ID format: {cve_id}. Please use the format CVE-YYYY-NNNNN."
736790
)
737791
continue
738792

@@ -742,6 +796,9 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
742796
cve_data, cve_error = fetch_github_cve_data(cve_id)
743797
display_cve_data(cve_data, cve_error)
744798

799+
if not cve_data:
800+
continue
801+
745802
epss_data, epss_error = fetch_epss_score(cve_id)
746803
display_epss_score(epss_data, epss_error)
747804

@@ -774,18 +831,8 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
774831
nuclei_data, nuclei_error = fetch_nuclei_data(cve_id)
775832
display_nuclei_data(nuclei_data, nuclei_error)
776833

777-
priority = calculate_priority(
778-
cve_id,
779-
cve_data,
780-
epss_data,
781-
github_data,
782-
cisa_data,
783-
vulncheck_data,
784-
exploitdb_data,
785-
)
786-
display_priority_rating(cve_id, priority)
787-
788-
display_cve_references(cve_data, cve_error)
834+
hackerone_data, hackerone_error = fetch_hackerone_cve_details(cve_id)
835+
display_hackerone_data(hackerone_data, hackerone_error)
789836

790837
published = cve_data["cveMetadata"].get("datePublished", "N/A")
791838
if published != "N/A":
@@ -840,8 +887,7 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
840887
vulncheck_exploits = (
841888
"\n".join(
842889
[
843-
f"{xdb['date_added']}: {xdb['clone_ssh_url'].replace(
844-
'[email protected]:', 'https://github.com/').replace('.git', '')}"
890+
f"{xdb['date_added']}: {xdb['clone_ssh_url'].replace('[email protected]:', 'https://github.com/').replace('.git', '')}"
845891
for item in vulncheck_data.get("data", [])
846892
for xdb in item.get("vulncheck_xdb", [])
847893
]
@@ -853,8 +899,7 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
853899
packetstorm_url = packetstorm_data.get("packetstorm_url", "N/A")
854900

855901
nuclei_url = (
856-
f"https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/main/{
857-
nuclei_data['file_path']}"
902+
f"https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/main/{nuclei_data['file_path']}"
858903
if nuclei_data and "file_path" in nuclei_data
859904
else "N/A"
860905
)
@@ -887,6 +932,19 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
887932
risk_assessment = get_risk_assessment(cve_details, cve_data)
888933
display_ai_risk_assessment(cve_details, cve_data)
889934

935+
priority = calculate_priority(
936+
cve_id,
937+
cve_data,
938+
epss_data,
939+
github_data,
940+
cisa_data,
941+
vulncheck_data,
942+
exploitdb_data,
943+
)
944+
display_priority_rating(cve_id, priority)
945+
946+
display_cve_references(cve_data, cve_error)
947+
890948
cve_result.update(
891949
{
892950
"CVE Data": cve_data,
@@ -897,6 +955,7 @@ def main(cve_ids, export_format=None, import_file=None, import_type=None):
897955
"VulnCheck Data": vulncheck_data,
898956
"ExploitDB Data": exploitdb_data,
899957
"PacketStorm Data": packetstorm_data,
958+
"HackerOne Data": hackerone_data,
900959
"Priority": {"Priority": priority},
901960
"Risk Assessment": risk_assessment,
902961
}

sploitscan/templates/report_template.html

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,16 @@ <h4><span class="icon">⚛️</span> Nuclei Template</h4>
255255
</table>
256256
</div>
257257
<div class="mb-3">
258-
<h4><span class="icon"></span> Patching Priority Rating</h4>
258+
<h4><span class="icon">🕵</span> HackerOne Hacktivity</h4>
259259
<table class="table table-sm">
260260
<tbody>
261261
<tr>
262-
<td>Priority</td>
263-
<td>{{ cve['Priority']['Priority'] if cve['Priority'] and cve['Priority']['Priority'] else 'N/A' }}</td>
262+
<td>Rank</td>
263+
<td>{{ cve['HackerOne Data']['data']['cve_entry']['rank'] if cve['HackerOne Data'] and cve['HackerOne Data'].get('data') and cve['HackerOne Data']['data'].get('cve_entry') else 'N/A' }}</td>
264+
</tr>
265+
<tr>
266+
<td>Reports Submitted</td>
267+
<td>{{ cve['HackerOne Data']['data']['cve_entry']['reports_submitted_count'] if cve['HackerOne Data'] and cve['HackerOne Data'].get('data') and cve['HackerOne Data']['data'].get('cve_entry') else 'N/A' }}</td>
264268
</tr>
265269
</tbody>
266270
</table>
@@ -269,7 +273,17 @@ <h4><span class="icon">⚠️</span> Patching Priority Rating</h4>
269273
<h4><span class="icon">🤖</span> AI-Powered Risk Assessment</h4>
270274
<pre style="white-space: pre-wrap;">{{ cve['Risk Assessment'] }}</pre>
271275
</div>
272-
276+
<div class="mb-3">
277+
<h4><span class="icon">⚠️</span> Patching Priority Rating</h4>
278+
<table class="table table-sm">
279+
<tbody>
280+
<tr>
281+
<td>Priority</td>
282+
<td>{{ cve['Priority']['Priority'] if cve['Priority'] and cve['Priority']['Priority'] else 'N/A' }}</td>
283+
</tr>
284+
</tbody>
285+
</table>
286+
</div>
273287
<div class="mb-3">
274288
<h4><span class="icon">📚</span> Further References</h4>
275289
<table class="table table-sm">

0 commit comments

Comments
 (0)