-
Notifications
You must be signed in to change notification settings - Fork 0
/
vuln.py
164 lines (158 loc) · 7 KB
/
vuln.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Cisco psirt vuln data pull
# Author: FutureCoder
# Date: 2020-08-21
import requests
from http.client import HTTPSConnection
from requests.auth import HTTPBasicAuth
from base64 import b64encode
import urllib.request
import urllib3
urllib3.disable_warnings()
import xml
import json
import time
import pickle
import _pickle
import os
from datetime import datetime
class vuln(object):
def __init__(self):
now = datetime.now()
self.today = now.strftime('20%y-%m-%d')
self.auth_url = 'https://cloudsso2.cisco.com/as/token.oauth2'
self.get_adv_vuln = f'https://api.cisco.com/security/advisories/all/firstpublished?startDate=2015-01-01&endDate={self.today}'
self.prox = {}
self.bearer_token = {}
self._token_ = ()
self.parms = {}
config_file = 'configuration.json'
self.dir_path = os.path.abspath(__file__)
self.path = os.path.dirname(self.dir_path)
with open(f'{self.path}/{config_file}','r') as f:
raw_file = f.read()
config_raw = json.loads(raw_file)
self.key = config_raw['servers']['cisco']['psirt_key']
self.secret = config_raw['servers']['cisco']['psirt_secret']
# time tracker
def timestamp(method):
def wrapper(*args, **kwargs):
ts = time.time()
result = method(*args, **kwargs)
te = time.time()
print('[I] {} took {}ms to complete standby for next instructions'.format(method.__name__, int((te-ts) * 1000)))
return result
return wrapper
# sso auth with cisco
@timestamp
def auth(self, fileone, filetwo):
response = requests.post(self.auth_url, verify=False, proxies=self.prox, data={'grant_type': 'client_credentials'},
headers={'Content-Type': 'application/x-www-form-urlencoded'},
params={'client_id': self.key, 'client_secret': self.secret})
if response == 200 or 202:
res = json.loads(response.text)
self.bearer_token.update(res)
self.token = self.bearer_token['access_token']
print(f'[I] psirt http-200 success, {self.token} bearer token stored')
print(f'[I] psirt token expires in {self.bearer_token["expires_in"]} seconds')
self.get_adv_bulk(fileone, filetwo)
return
elif response != 200 or 202:
res = json.loads(response.text)
print(f'did not recieve expected 20X - reason{response.text}')
return
@timestamp
# bulk vuln query
def get_adv_bulk(self, fileone, filetwo):
requests.packages.urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
response = requests.get(self.get_adv_vuln, verify=False, proxies=self.prox,
headers={'Authorization': 'Bearer {0}'.format(self.token), 'Accept': 'application/json'})
if response.status_code == 200 or 202:
self.outputs = json.loads(response.text)
self.advs = self.outputs['advisories']
self.parse_prods(self.advs, filetwo)
self.parse_advs(self.advs, fileone)
elif response.status_code != 200 or 202:
print(response.status_code)
return
return
@timestamp
def parse_prods(self, input, filetwo):
self.temp = []
self.d = dict()
self.temp2 = []
self.temp3 = []
for line in input:
adv = line['advisoryId']
names = line['productNames']
for x in names:
self.temp.append(adv)
self.temp.append(x)
for x in self.temp:
if 'cisco-' in x:
self.d['advisoryId'] = x
self.temp2.append(self.d)
elif 'Cisco-' in x:
#print(x)
self.d['advisoryId'] = x
self.temp2.append(self.d)
continue
#self.d = dict()
elif x != 'NA':
self.third = x
self.d['productName'] = x
self.temp2.append(self.d)
self.d = dict()
else:
self.d = dict()
continue
self.pickling_(self.temp2, filetwo)
return
# extract relavent data
def parse_advs(self, advs, fileone):
adv_list_pri = []
self.adv_list_sec = []
for adv in advs:
adv_dict = dict()
self.adv_dict_key = dict()
self.adv_dict_value = dict()
adv_dict['advisoryId'] = adv['advisoryId'] if 'advisoryId' in adv else 'unknown'
adv_dict['advisoryTitle'] = adv['advisoryTitle'] if 'advisoryTitle' in adv else 'unknown'
adv_dict['bugIDs'] = adv['bugIDs'] if 'bugIDs' in adv else 'unknown'
adv_dict['ipsSignatures'] = adv['ipsSignatures'] if 'ipsSignatures' in adv else 'unknown'
adv_dict['cves'] = adv['cves'] if 'cves' in adv else 'unknown'
adv_dict['cwe'] = adv['cwe'] if 'cwe' in adv else 'unknown'
adv_dict['cvssBaseScore'] = adv['cvssBaseScore'] if 'cvssBaseScore' in adv else 'unknown'
# need to parse better
#adv_dict['summary'] = adv['summary'] if 'summary' in adv else 'unknown' Need to parse better
adv_dict['sir'] = adv['sir'] if 'sir' in adv else 'unknown'
adv_dict['cvrfUrl'] = adv['cvrfUrl'] if 'cvrfUrl' in adv else 'unknown'
adv_dict['firstPublished'] = adv['firstPublished'] if 'firstPublished' in adv else 'unknown'
adv_dict['lastUpdated'] = adv['lastUpdated'] if 'lastUpdated' in adv else 'unknown'
adv_dict['publicationUrl'] = adv['publicationUrl'] if 'publicationUrl' in adv else 'unknown'
adv_dict['productNames'] = adv['productNames'] if 'productNames' in adv else 'unknown'
adv_list_pri.append(adv_dict)
self.pickling_(adv_list_pri, fileone)
return
@timestamp
# searlize data
def pickling_(self, adv_list, inputfile):
if len(adv_list) >= 1:
self.file = open(self.path + f'/{inputfile}', 'wb')
self.pickled_dump_ = pickle.dump(adv_list, self.file)
self.file.close()
elif len(self._adv_list_) == 0:
print(f'nothing here boss')
return
if __name__ == '__main__':
vuln = vuln()
# to run
#test = vuln.auth('outputfileone', 'outputfiletwo')
#
### What this script does
# 1. Configuration.json is used for cred storing
# 2. Auth with cisco oauth, token retrieval
# 3. Token auth and get data with cisco endpoint
# 4. Data sent to two parsing functions:
# a. first compiles the data into a formatting with the vulnerability code as the primary key, and appending each product additionally 1NF formatting (could be useful for data comparison)
# b. second compiles the data in a easy viewing parsing format, but non SQL NF.
# 5. Searlizes the data with pickle and stores as an outputfile, which can be desearlized/opened and interpreted at will.