Skip to content

Commit 9cd5adc

Browse files
committed
Add support for exploitdb improver
Signed-off-by: ziadhany <ziadhany2016@gmail.com>
1 parent 1561efe commit 9cd5adc

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

vulnerabilities/improvers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10+
from vulnerabilities.improvers import exploitdb
1011
from vulnerabilities.improvers import valid_versions
1112
from vulnerabilities.improvers import vulnerability_kev
1213
from vulnerabilities.improvers import vulnerability_status
@@ -29,6 +30,7 @@
2930
valid_versions.GithubOSVImprover,
3031
vulnerability_status.VulnerabilityStatusImprover,
3132
vulnerability_kev.VulnerabilityKevImprover,
33+
exploitdb.ExploitDBImprover,
3234
]
3335

3436
IMPROVERS_REGISTRY = {x.qualified_name: x for x in IMPROVERS_REGISTRY}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import csv
2+
import io
3+
import logging
4+
from typing import Iterable
5+
6+
from django.db import IntegrityError
7+
from django.db.models import QuerySet
8+
from sphinx.util import requests
9+
10+
from vulnerabilities.improver import Improver
11+
from vulnerabilities.improver import Inference
12+
from vulnerabilities.models import Advisory
13+
from vulnerabilities.models import Alias
14+
from vulnerabilities.models import VulnerabilityReference
15+
from vulnerabilities.models import VulnerabilityRelatedReference
16+
17+
logger = logging.getLogger(__name__)
18+
19+
20+
class ExploitDBImprover(Improver):
21+
"""
22+
ExploitDB Improver
23+
"""
24+
25+
license_expression = "GPL-2.0"
26+
27+
@property
28+
def interesting_advisories(self) -> QuerySet:
29+
# TODO Modify ExploitDB Improver to iterate over the vulnerabilities alias, not the advisory
30+
return [Advisory.objects.first()]
31+
32+
def get_inferences(self, advisory_data) -> Iterable[Inference]:
33+
"""
34+
Fetch ExploitDB data, iterate over it to find the vulnerability with the specified alias, and create or update
35+
the ref and ref-type accordingly.
36+
"""
37+
38+
exploit_db_url = (
39+
"https://gitlab.com/exploit-database/exploitdb/-/raw/main/files_exploits.csv"
40+
)
41+
response = requests.get(exploit_db_url)
42+
43+
if response.status_code != 200:
44+
logger.error(f"Failed to fetch ExploitDB URL: {exploit_db_url}")
45+
return []
46+
47+
raw_data = io.StringIO(response.text)
48+
49+
csvreader = csv.reader(raw_data)
50+
51+
# Ignore the csv header
52+
next(csvreader) # header
53+
for row in csvreader:
54+
try:
55+
aliases = row[11].split(";")
56+
for raw_alias in aliases:
57+
alias = Alias.objects.get(alias=raw_alias)
58+
if not alias:
59+
continue
60+
61+
vul = alias.vulnerability
62+
if not vul:
63+
continue
64+
65+
reference_id = row[11]
66+
67+
if reference_id:
68+
url_map = {
69+
"file_url": f"https://gitlab.com/exploit-database/exploitdb/-/blob/main/{row[1]}"
70+
if row[1]
71+
else None,
72+
"direct_url": row[16] if row[16] else None,
73+
}
74+
75+
for key, url in url_map.items():
76+
if url:
77+
ref, created = VulnerabilityReference.objects.update_or_create(
78+
reference_id=reference_id,
79+
reference_type=VulnerabilityReference.EXPLOIT,
80+
defaults={"url": url},
81+
)
82+
if created:
83+
VulnerabilityRelatedReference.objects.create(
84+
vulnerability=vul,
85+
reference=ref,
86+
)
87+
88+
except Alias.DoesNotExist as e:
89+
logger.error(f"No Alias found for exploit id {row[0]}: {e}")
90+
except Exception as e:
91+
logger.error(e)
92+
93+
return []

0 commit comments

Comments
 (0)