1
- import requests
1
+ import asyncio
2
2
import re
3
3
from termcolor import colored
4
- from datetime import datetime
5
4
import json
5
+ from aiohttp import ClientSession , TCPConnector , ClientTimeout
6
6
from pyExploitDb import PyExploitDb
7
7
8
8
art = """
11
11
| | | |__ _ __ ___ __ _| |_ | |_ __ __ _ ___ ___ _ __
12
12
| | | '_ \| '__/ _ \/ _` | __|| | '__/ _` |/ __/ _ \ '__|
13
13
| | | | | | | | __/ (_| | |_ | | | | (_| | (_| __/ |
14
- |_| |_| |_|_| \___|\__,_|\__||_|_| \__,_|\___\___|_| Version 2.0
14
+ |_| |_| |_|_| \___|\__,_|\__||_|_| \__,_|\___\___|_| Version 2.1
15
15
A Script to identify CVE using CPE by name & version
16
16
Credit: @FR13ND0x7F @0xCaretaker @meppohak5
17
17
"""
18
18
19
19
print (colored (art , "cyan" ))
20
20
21
- def find_cpes (component , version ):
21
+ async def find_cpes_async (component , version ):
22
22
base_url = "https://nvd.nist.gov/products/cpe/search/results"
23
23
params = {
24
24
"namingFormat" : "2.3" ,
25
25
"keyword" : f"{ component } { version } "
26
26
}
27
27
28
- response = requests .get (base_url , params = params )
29
- print (f"URL Used: { response .url } " ) # Print the URL used to find CPE
30
- content = response .text
28
+ async with ClientSession (connector = TCPConnector (ssl = False ), timeout = ClientTimeout (total = 10 )) as session :
29
+ async with session .get (base_url , params = params ) as response :
30
+ print (f"URL Used: { response .url } " ) # Print the URL used to find CPE
31
+ content = await response .text ()
31
32
32
33
cpe_matches = re .findall (r'cpe:(.*?)<' , content )
33
34
return cpe_matches
34
35
35
- def synk_db (cve_id ):
36
- res = requests .get (f"https://security.snyk.io/vuln/?search={ cve_id } " )
37
- a_tag_pattern = r'data-snyk-test="vuln table title".*>([^"]+)<!----><!---->'
38
- a_tag_matches = re .findall (a_tag_pattern , res .text )
36
+ async def synk_db (cve_id ):
37
+ async with ClientSession (connector = TCPConnector (ssl = False ), timeout = ClientTimeout (total = 10 )) as session :
38
+ async with session .get (f"https://security.snyk.io/vuln/?search={ cve_id } " ) as res :
39
+ text = await res .text ()
40
+ a_tag_pattern = r'data-snyk-test="vuln table title".*>([^"]+)<!----><!---->'
41
+ a_tag_matches = re .findall (a_tag_pattern , text )
39
42
40
- if a_tag_matches :
41
- snyk_short_name = a_tag_matches [0 ].lstrip (). rstrip ()
42
- return snyk_short_name
43
+ if a_tag_matches :
44
+ snyk_short_name = a_tag_matches [0 ].strip ()
45
+ return snyk_short_name
43
46
44
- def fetch_cve_details (cpe_string ):
47
+ async def fetch_cve_details (cpe_string ):
45
48
base_url = "https://services.nvd.nist.gov/rest/json/cves/1.0"
46
49
results = []
47
50
48
51
cve_query_string = ":" .join (cpe_string .split (":" )[1 :5 ]) # Extract relevant CPE part (vendor, product, version, update)
49
52
url = f"{ base_url } ?cpeMatchString=cpe:/{ cve_query_string } "
50
53
51
- response = requests . get ( url )
52
-
53
- try :
54
- data = response .json ()
55
- except json .JSONDecodeError :
56
- print (colored (f"Error decoding JSON for CPE: { cpe_string } . Skipping." , "red" ))
57
- return []
58
-
59
- if "result" in data :
60
- cves = data ["result" ]["CVE_Items" ]
61
- for cve_item in cves :
62
- cve_id = cve_item ["cve" ]["CVE_data_meta" ]["ID" ]
63
- snyk_short_name = synk_db (cve_id )
64
-
65
- description = cve_item ["cve" ]["description" ]["description_data" ][0 ]["value" ]
66
- link = f"https://nvd.nist.gov/vuln/detail/{ cve_id } "
67
-
68
- weaknesses = []
69
- if "problemtype" in cve_item ["cve" ]:
70
- for problem_type in cve_item ["cve" ]["problemtype" ]["problemtype_data" ]:
71
- for description in problem_type ["description" ]:
72
- weaknesses .append (description ["value" ])
73
-
74
- if "description_data" in cve_item ["cve" ]["description" ]:
75
- description_text = cve_item ["cve" ]["description" ]["description_data" ][0 ]["value" ]
76
- else :
77
- description_text = "Description not available."
78
-
79
- # Check for public exploit using pyExploitDb
80
- pEdb = PyExploitDb ()
81
- pEdb .debug = False
82
- pEdb .openFile ()
83
- exploit_status = pEdb .searchCve (cve_id )
84
- if exploit_status :
85
- exploit_status = "Public Exploit Found"
86
- else :
87
- exploit_status = "No Public Exploit Found"
88
-
89
- cve_details = {
90
- "CVE ID" : cve_id ,
91
- "Short Name" : snyk_short_name ,
92
- "Description" : description_text ,
93
- "Weaknesses" : ", " .join (weaknesses ),
94
- "Link" : link ,
95
- "Exploit Status" : exploit_status
96
- }
97
-
98
- results .append (cve_details )
54
+ async with ClientSession ( connector = TCPConnector ( ssl = False ), timeout = ClientTimeout ( total = 10 )) as session :
55
+ async with session . get ( url ) as response :
56
+ try :
57
+ data = await response .json ()
58
+ except json .JSONDecodeError :
59
+ print (colored (f"Error decoding JSON for CPE: { cpe_string } . Skipping." , "red" ))
60
+ return []
61
+
62
+ if "result" in data :
63
+ cves = data ["result" ]["CVE_Items" ]
64
+ for cve_item in cves :
65
+ cve_id = cve_item ["cve" ]["CVE_data_meta" ]["ID" ]
66
+ snyk_short_name = await synk_db (cve_id )
67
+
68
+ description = cve_item ["cve" ]["description" ]["description_data" ][0 ]["value" ]
69
+ link = f"https://nvd.nist.gov/vuln/detail/{ cve_id } "
70
+
71
+ weaknesses = []
72
+ if "problemtype" in cve_item ["cve" ]:
73
+ for problem_type in cve_item ["cve" ]["problemtype" ]["problemtype_data" ]:
74
+ for description in problem_type ["description" ]:
75
+ weaknesses .append (description ["value" ])
76
+
77
+ if "description_data" in cve_item ["cve" ]["description" ]:
78
+ description_text = cve_item ["cve" ]["description" ]["description_data" ][0 ]["value" ]
79
+ else :
80
+ description_text = "Description not available."
81
+
82
+ # Check for public exploit using pyExploitDb
83
+ pEdb = PyExploitDb ()
84
+ pEdb .debug = False
85
+ pEdb .openFile ()
86
+ exploit_status = pEdb .searchCve (cve_id )
87
+ if exploit_status :
88
+ exploit_status = "Public Exploit Found"
89
+ else :
90
+ exploit_status = "No Public Exploit Found"
91
+
92
+ cve_details = {
93
+ "CVE ID" : cve_id ,
94
+ "Short Name" : snyk_short_name ,
95
+ "Description" : description_text ,
96
+ "Weaknesses" : ", " .join (weaknesses ),
97
+ "Link" : link ,
98
+ "Exploit Status" : exploit_status
99
+ }
100
+
101
+ results .append (cve_details )
99
102
100
103
return results
101
104
102
- if __name__ == "__main__" :
105
+ async def main () :
103
106
print (colored ("CPE Finder Script" , "green" , attrs = ["bold" ]))
104
107
print ("This script searches for the CPEs of a component and version.\n " )
105
108
106
109
component = input (colored ("Enter the component (e.g., jquery): " , "cyan" ))
107
110
version = input (colored ("Enter the version (e.g., 1.0.0): " , "cyan" ))
108
111
109
- cpe_strings = find_cpes (component , version )
112
+ cpe_strings = await find_cpes_async (component , version )
110
113
if cpe_strings :
111
114
print (colored ("CPEs Found:" , "green" ))
112
115
for cpe_string in cpe_strings :
113
116
print (colored (f" { cpe_string } " , "green" ))
114
117
115
118
for cpe_string in cpe_strings :
116
- results = fetch_cve_details (cpe_string )
119
+ results = await fetch_cve_details (cpe_string )
117
120
if results :
118
121
print (colored ("\n CVE Details" , "cyan" , attrs = ["underline" ]))
119
122
for result in results :
@@ -130,3 +133,7 @@ def fetch_cve_details(cpe_string):
130
133
print (colored (f"Exploit Status: { result ['Exploit Status' ]} \n " , "green" ))
131
134
else :
132
135
print (colored ("CPEs not found for the provided component and version." , "red" ))
136
+
137
+ if __name__ == "__main__" :
138
+ asyncio .run (main ())
139
+
0 commit comments