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

Commit efa5e6a

Browse files
committed
2 parents e61b64e + 316c891 commit efa5e6a

15 files changed

+25562
-24759
lines changed

cobra/cve_parse.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@
1313
import datetime
1414
import os
1515
import requests
16-
import urllib
1716
import threading
1817
import gzip
1918
import xml.etree.cElementTree as eT
2019
import multiprocessing
2120
from .config import project_directory, Config, config_path
2221
from .log import logger
2322
from .dependencies import Dependencies
23+
24+
try:
25+
from urllib import urlretrieve # Python2
26+
except ImportError:
27+
from urllib.request import urlretrieve # Python3
28+
2429
try:
2530
from configparser import ConfigParser
2631
except ImportError:
@@ -52,7 +57,7 @@ def cve_parse(self):
5257
if not isinstance(cve_file, list):
5358
tree = self.parse_xml(cve_file)
5459
root = tree.getroot()
55-
childs = root.iter('%sentry' % self.NS)
60+
childs = root.findall('.//%sentry' % self.NS)
5661
for child in childs: # child is entry Element
5762
cve_id = child.attrib['id']
5863
cve_info = self.cve_info(child)
@@ -62,7 +67,7 @@ def cve_parse(self):
6267
for filename in cve_file:
6368
tree = self.parse_xml(filename)
6469
root = tree.getroot()
65-
childs = root.iter('%sentry' % self.NS)
70+
childs = root.findall('.//%sentry' % self.NS)
6671
for child in childs: # child is entry Element
6772
cve_id = child.attrib['id']
6873
cve_info = self.cve_info(child)
@@ -97,7 +102,7 @@ def cve_info(self, entry):
97102
'wu-ftpd', 'cluster_server', 'catos', 'mantis', 'quicktime', 'security_linux', 'firefox',
98103
'jetty_http_server', 'php:', 'enterprise_linux', 'oracle10g', 'oracle9g', 'oracle8g', 'firehol',
99104
'fetchmail', 'postgresql', 'freebsd', 'chrome']
100-
products = entry.iter('%sproduct' % self.VULN)
105+
products = entry.findall('.//%sproduct' % self.VULN)
101106
access_complexity = entry.find('.//%saccess-complexity' % self.CVSS)
102107
for product in products:
103108
module_version = product.text.split(':')
@@ -158,7 +163,8 @@ def rule_xml(self):
158163
rule_path = project_directory + '/rules/CVI-999'
159164
tree.write(rule_path + str(self.year)[1:] + '.xml')
160165
endtime = datetime.datetime.now()
161-
logger.info('CVE-999' + str(self.year)[1:] + '.xml Rule update succeeds, times:%ds' % (endtime - starttime).seconds)
166+
logger.info(
167+
'CVE-999' + str(self.year)[1:] + '.xml Rule update succeeds, times:%ds' % (endtime - starttime).seconds)
162168

163169
def pretty(self, e, level=0):
164170
"""
@@ -179,7 +185,7 @@ def rule_parse(self, file_):
179185
"""
180186
tree = self.parse_xml(file_)
181187
root = tree.getroot()
182-
cves = root.iter('cve')
188+
cves = root.findall('.//cve')
183189
for cve_child in cves:
184190
cve_id = cve_child.attrib['id']
185191
cve_level = cve_child.attrib['level']
@@ -191,7 +197,7 @@ def rule_parse(self, file_):
191197
def rule_info(cve_child):
192198
rule_info = {}
193199
cpe_list = []
194-
products = cve_child.iter('product')
200+
products = cve_child.findall('.//product')
195201
for product in products:
196202
cpe_list.append(product.text.lower())
197203
rule_info['cpe'] = cpe_list
@@ -234,7 +240,7 @@ def log_result(self):
234240
for cve_child in self._scan_result[module_]:
235241
cve_id = cve_child
236242
level = self._scan_result[module_][cve_id]
237-
logger.warning('Find the module ' + module_ + ' have ' + cve_id +',level: ' +level)
243+
logger.warning('Find the module ' + module_ + ' have ' + cve_id + ',level: ' + level)
238244
count = len(self._scan_result[module_])
239245
logger.warning('The ' + module_ + ' module have ' + str(count) + ' CVE Vul(s)')
240246

@@ -246,14 +252,14 @@ def rule_parse():
246252
if is_update():
247253
gz_files = download_rule_gz()
248254
un_gz(gz_files)
249-
pool = multiprocessing.Pool(processes=50)
250-
for year in range(2002, datetime.datetime.now().year+1):
255+
pool = multiprocessing.Pool()
256+
for year in range(2002, datetime.datetime.now().year + 1):
251257
cve_xml = "../rules/%d.xml" % year
252258
pool.apply_async(rule_single, args=(cve_xml, year))
253259
pool.close()
254260
pool.join()
255-
for year in range(2002, datetime.datetime.now().year+1):
256-
os.remove(project_directory+"/rules/%d.xml" % year)
261+
for year in range(2002, datetime.datetime.now().year + 1):
262+
os.remove(project_directory + "/rules/%d.xml" % year)
257263
logger.info("The rule update success, start scan cve vuls")
258264
return True
259265
else:
@@ -264,18 +270,19 @@ def download_rule_gz():
264270
threads = []
265271
files = []
266272
start_time = datetime.datetime.now()
267-
for year in range(2002, datetime.datetime.now().year+1):
273+
for year in range(2002, datetime.datetime.now().year + 1):
268274
url = "https://static.nvd.nist.gov/feeds/xml/cve/2.0/nvdcve-2.0-" + str(year) + ".xml.gz"
269275
logger.info("start download " + str(year) + ".xml.gz")
270-
thread = threading.Thread(target=urllib.urlretrieve, args=(url, project_directory+"/rules/"+str(year)+".xml.gz"))
276+
thread = threading.Thread(target=urlretrieve,
277+
args=(url, project_directory + "/rules/" + str(year) + ".xml.gz"))
271278
thread.start()
272279
threads.append(thread)
273280
logger.info('CVE-' + str(year) + " is download success")
274-
files.append(project_directory+"/rules/" + str(year) + ".xml.gz")
281+
files.append(project_directory + "/rules/" + str(year) + ".xml.gz")
275282
for t in threads:
276283
t.join()
277284
end_time = datetime.datetime.now()
278-
logger.info("All CVE xml file already download success, use time:%ds" % (end_time-start_time).seconds)
285+
logger.info("All CVE xml file already download success, use time:%ds" % (end_time - start_time).seconds)
279286
return files
280287

281288

@@ -286,11 +293,11 @@ def un_gz(gz_files):
286293
for gz_file in gz_files:
287294
f_name = gz_file.replace(".gz", "")
288295
g_file = gzip.GzipFile(gz_file)
289-
open(f_name, "w+").write(g_file.read())
296+
open(f_name, "wb+").write(g_file.read())
290297
g_file.close()
291298
os.remove(gz_file)
292299
end_time = datetime.datetime.now()
293-
logger.info("Decompress success, use time:%ds" % (end_time-start_time).seconds)
300+
logger.info("Decompress success, use time:%ds" % (end_time - start_time).seconds)
294301
return True
295302

296303

@@ -300,9 +307,9 @@ def rule_single(target_directory, year):
300307

301308
def is_update():
302309
url = "https://static.nvd.nist.gov/feeds/xml/cve/2.0/nvdcve-2.0-modified.meta"
303-
r = requests.get(url)
310+
r = requests.get(url, verify=False)
304311
index = r.text.find('sha256:')
305-
sha256_now = r.text[index+7:].strip()
312+
sha256_now = r.text[index + 7:].strip()
306313
sha256_local = Config(level1='cve', level2='modified').value
307314
if sha256_local != sha256_now:
308315
logger.info("The CVE Rule already update, start update local rule")
@@ -314,7 +321,7 @@ def is_update():
314321
config.write(fi)
315322
fi.close()
316323
except IOError as e:
317-
logger.warning(e.message)
324+
logger.warning(e)
318325
logger.info("The sha256 been update")
319326
return True
320327
return False

cobra/dependencies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def find_java_mvn(self, file_path):
9191
for pom in file_path:
9292
tree = self.parse_xml(pom)
9393
root = tree.getroot()
94-
childs = root.iter('%sdependency' % pom_ns)
94+
childs = root.findall('.//%sdependency' % pom_ns)
9595
for child in childs:
9696
group_id = child.getchildren()[0].text
9797
artifact_id = child.getchildren()[1].text

cobra/git_projects.py

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,64 +13,115 @@
1313
"""
1414
import json
1515
import requests
16+
import re
17+
import threading
18+
from .log import logger
19+
from .config import code_path, Config
20+
try:
21+
# Python 3
22+
import queue
23+
except ImportError:
24+
# Python 2
25+
import Queue as queue
1626

1727

18-
def start(url, private_token, cobra_ip, key):
28+
def start():
29+
url = Config('git', 'gitlab_url').value
30+
private_token = Config('git', 'private_token').value
31+
cobra_ip = Config('git', 'cobra_ip').value
32+
key = Config('cobra', 'secret_key').value
33+
threads = []
34+
pages = get_pages(url, private_token)
35+
q_pages = queue.Queue(pages)
36+
result_path = code_path + '/result_sid'
37+
fi = open(result_path, 'w+')
38+
for i in range(int(pages)):
39+
q_pages.put(i+1)
40+
41+
for i in range(10):
42+
thread = threading.Thread(target=get_git_urls, args=(url, private_token, cobra_ip, key, q_pages, fi))
43+
thread.start()
44+
threads.append(thread)
45+
46+
for thread in threads:
47+
thread.join()
48+
49+
fi.close()
50+
logger.info("All projects have been pushed")
51+
52+
53+
def get_git_urls(url, private_token, cobra_ip, key, q_pages, fi):
1954
"""
2055
:param url: The gitlab's projects api ,example:http://xxx.gitlab.com/api/v3/projects
2156
:param private_token: The user's private_token
2257
:param cobra_ip: The Cobra server's ip
2358
:param key: The Cobra api key
59+
:param q_pages: The Queue of pages
60+
:param fi: The result in this file
2461
:return:
2562
"""
26-
page = 1
27-
while True:
63+
while not q_pages.empty():
2864
git_urls = []
65+
page = q_pages.get()
2966
params = {'private_token': private_token, 'page': page}
3067
url = url
31-
r = requests.get(url, params=params)
68+
r = request_target(url, params, method="get")
3269

3370
if r.status_code == 200:
3471
data = r.json() # 一个页面中的Json数据,默认20条
35-
if len(data) == 0:
36-
print("url收集完毕")
37-
break
3872
for j in range(len(data)):
3973
git_url = data[j]['http_url_to_repo']
4074
git_branch = data[j]['default_branch']
4175

4276
if git_branch is not None:
4377
request_url = git_url+':'+git_branch
78+
4479
else:
4580
request_url = git_url
81+
4682
git_urls.append(request_url)
47-
# res = push_to_api(git_urls, cobra_ip, key)
48-
# if res:
49-
# print ("page %d git push success" % page)
50-
# else:
51-
# print ("page %d git push fail" % page)
83+
res = push_to_api(git_urls, cobra_ip, key, fi)
84+
if res:
85+
logger.info("page %d git push success" % page)
86+
else:
87+
logger.info("page %d git push fail" % page)
5288

5389
elif r.status_code == 404:
54-
print("404")
90+
logger.warning("page %d 404" % page)
5591

5692
else:
57-
print(r.status_code)
93+
logger.warning("page %d is %d" % page, r.status_code)
94+
q_pages.task_done()
95+
5896

59-
page += 1
97+
def request_target(target_url, params=None, header=None, method="get"):
98+
if method == "get":
99+
response = requests.get(url=target_url, params=params, headers=header)
100+
return response
101+
if method == "post":
102+
response = requests.post(url=target_url, data=json.dumps(params), headers=header)
103+
return response
60104

61105

62-
def push_to_api(urls, cobra_ip, key):
106+
def push_to_api(urls, cobra_ip, key, fi):
63107
headers = {"Content-Type": "application/json"}
64108
url = cobra_ip + "/api/add"
65109
payload = {"key": key, "target": urls}
66-
r = requests.post(url=url, data=json.dumps(payload), headers=headers)
110+
r = request_target(url, payload, headers, method="post")
67111
if r.status_code == 200:
68-
print(r.json())
112+
fi.write(str(r.json()) + '\n')
113+
logger.info(r.json())
69114
return True
70115
else:
71-
print(r.json())
116+
logger.info(r.json())
72117
return False
73118

74119

75-
def get_pages():
76-
pass
120+
def get_pages(url, private_token):
121+
params = {"private_token": private_token}
122+
response = request_target(url, params)
123+
res = response.headers['link'].split(",")
124+
res = res[2]
125+
res = re.search(r"all\?page=(\d*)&per_page=0", res)
126+
pages = res.group(1)
127+
return pages

cobra/utils.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import string
1919
import random
2020
import hashlib
21+
import locale
2122
from .log import logger
2223
from .config import Config
2324
from .exceptions import PickupException, NotExistException, AuthFailedException
@@ -178,20 +179,32 @@ def convert_time(seconds):
178179
if minute == 0:
179180
return str(seconds % one_minute) + "\""
180181
else:
181-
return str(minute) + "'" + str(seconds % one_minute) + "\""
182+
return str(int(minute)) + "'" + str(seconds % one_minute) + "\""
182183

183184

184-
def convert_number(number):
185+
def convert_number(n):
185186
"""
186187
Convert number to , split
187188
Ex: 123456 -> 123,456
188-
:param number:
189+
:param n:
189190
:return:
190191
"""
191-
if number is None or number == 0:
192-
return 0
193-
number = int(number)
194-
return '{:20,}'.format(number).strip()
192+
if n is None: return '0'
193+
n = str(n)
194+
if '.' in n:
195+
dollars, cents = n.split('.')
196+
else:
197+
dollars, cents = n, None
198+
199+
r = []
200+
for i, c in enumerate(str(dollars)[::-1]):
201+
if i and (not (i % 3)):
202+
r.insert(0, ',')
203+
r.insert(0, c)
204+
out = ''.join(r)
205+
if cents:
206+
out += '.' + cents
207+
return out
195208

196209

197210
def md5(content):
@@ -200,6 +213,7 @@ def md5(content):
200213
:param content:
201214
:return:
202215
"""
216+
content = content.encode('utf8')
203217
return hashlib.md5(content).hexdigest()
204218

205219

@@ -230,6 +244,7 @@ def path_to_short(path, max_length=36):
230244
return path
231245
paths = path.split('/')
232246
paths = filter(None, paths)
247+
paths = list(paths)
233248
tmp_path = ''
234249
for i in range(0, len(paths)):
235250
logger.debug((i, str(paths[i]), str(paths[len(paths) - i - 1])))
@@ -258,8 +273,9 @@ def path_to_file(path):
258273
:return:
259274
"""
260275
paths = path.split('/')
261-
paths = filter(None, paths)
262-
return '.../{0}'.format(paths[len(paths) - 1])
276+
paths = list(filter(None, paths))
277+
length = len(paths)
278+
return '.../{0}'.format(paths[length - 1])
263279

264280

265281
def percent(part, whole, need_per=True):

config.template

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ password:
5353
[git]
5454
username:
5555
password:
56+
private_token:
57+
# http://xxx.gitlab.com/api/v3/projects
58+
gitlab_url:
59+
cobra_ip:
60+
5661

5762
[cve]
5863
modified = 00B6A630D5515C9D6F61B2FC97ED7EE689A787AC52E1654D1E991BC26F4647CD

0 commit comments

Comments
 (0)