forked from votd/vulnerability-of-the-day
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbuild_votds
executable file
·154 lines (140 loc) · 5.54 KB
/
build_votds
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
#!/usr/bin/env python
# Copyright 2012 Andrew Meneely and Samuel Lucidi.
# Licensed under the Educational Community License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.osedu.org/licenses/ECL-2.0.
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions
# and limitations under the License.
import os
import re
import sys
import glob
import shutil
import zipfile
import argparse
import subprocess
from argparse import RawTextHelpFormatter
try:
# make sure deflate is available
import zlib
compression = zipfile.ZIP_DEFLATED
except ImportError:
compression = zipfile.ZIP_STORED
# Convert a votd name entered at the command line to something
# that is reasonably safe to be used as a directory name.
def safe_name(votd_name):
import unicodedata
if isinstance(votd_name, unicode):
votd_name = unicodedata.normalize('NFKD', votd_name).encode('ascii', 'ignore')
votd_name = unicode(re.sub("[^\w\s-]", "", votd_name))
votd_name.strip()
votd_name.lower()
votd_name = unicode(re.sub("[-\s]+", "-", votd_name))
if len(votd_name) < 1:
raise ValueError("zero-length votd name")
return votd_name
# Write out a directory and set of empty
# files for a new vulnerability of the day
def build_skeleton(exploit_name, src, dest):
try:
os.makedirs(os.path.join(dest, exploit_name, "demo"))
except OSError:
print "Skipping %s: example already exists" % exploit_name
subprocess.call(["cp", os.path.join(src, "www-template", "template.html"), os.path.join(dest, "%s" % exploit_name, "%s.html" % exploit_name)])
subprocess.call(["touch", os.path.join(dest, "%s" % exploit_name, "notes.markdown")])
subprocess.call(["touch", os.path.join(dest, "%s" % exploit_name, "compatability.markdown")])
# Concatenate html files for selected votds into
# one index.html file.
def build_webpage(votds, src, dest):
with open(os.path.join(dest, "index.html"), 'wb') as destination:
shutil.copyfileobj(open(os.path.join(src, 'www-template', 'prefix.html'), 'rb'), destination)
for votd in votds:
try:
shutil.copyfileobj(open(os.path.join(src, votd, "%s.html" % votd)), destination)
except IOError:
print "Skipping %s: no html file" % votd
shutil.copyfileobj(open(os.path.join(src, 'www-template', 'suffix.html'), 'rb'), destination)
# Zip up the selected votds into one archive suitable
# for downloading.
def build_zip(votds, src, dest):
with zipfile.ZipFile(os.path.join(dest, 'votds.zip'), mode='w') as zfile:
# add files
zfile.write(os.path.join(dest, 'index.html'), 'index.html', compression)
zfile.write(os.path.join(src, 'www-template', 'toc.js'), 'toc.js', compression)
zfile.write(os.path.join(src, 'www-template', 'votd.css'), 'votd.css', compression)
os.chdir(src)
for votd in votds:
zip_folder(zfile, votd)
# Add the contents of a directory to a zip file,
# maintaining the directory structure.
def zip_folder(zfile, folder_name):
folder_name = folder_name.encode('ascii')
for f in glob.glob(os.path.join(folder_name, '*')):
if os.path.isfile(f):
print f
zfile.write(f, f, compression)
elif os.path.isdir(f):
zip_folder(zfile, f)
# Insert documentation for a list of votds into an existing
# index file.
def insert_votds(votds, src, dest):
replace_text = "<!-- insert next one here -->"
index_file = open("index.html", 'r')
index_text = index_file.read()
index_file.close()
insert_text = "\n"
for votd in votds:
try:
votd_file = open(os.path.join("%s" % votd, "%s.html" % votd), 'r')
votd_text = votd_file.read()
insert_text += votd_text
except IOError:
print "Skipping %s: no html file" % votd
finally:
votd_file.close()
insert_text += "\n" + replace_text
index_text = index_text.replace(replace_text, insert_text)
index_file = open("index.html", 'w')
index_file.write(index_text)
index_file.close()
print "Inserted %d vulnerability descriptions." % len(votds)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Build VotD examples.',
formatter_class=RawTextHelpFormatter)
parser.add_argument('command', choices=["new", "www", "add", "zip"], help="""
new: create skeleton directory for new votds
www: compile html page for selection of votds
add: insert votd descriptions into existing index
zip: zip up selection of votds
""")
parser.add_argument('source', type=unicode, help="source directory containing votds")
parser.add_argument('dest', type=unicode, help="destination to output index or zipfile")
parser.add_argument('votds', metavar='V', type=unicode, nargs='+',
help="an exploit to build")
args = parser.parse_args()
if not os.path.exists(args.dest):
print "Destination path %s does not exist." % args.dest
sys.exit(1)
if not os.path.exists(args.source):
print "Source path %s does not exist." % args.source
sys.exit(1)
votds = []
for votd in args.votds:
votds.append(safe_name(votd))
if args.command == "new":
for votd in votds:
build_skeleton(votd, args.source, args.dest)
elif args.command == "www":
build_webpage(votds, args.source, args.dest),
elif args.command == "zip":
build_webpage(votds, args.source, args.dest)
build_zip(votds, args.source, args.dest)
elif args.command == "add":
if os.path.isfile("index.html"):
insert_votds(votds, args.source, args.dest)
else:
print "No index.html, creating one."
build_webpage(votds, args.source, args.dest)