09bc4973567a78dbbe4fa95e5ad5b9356adb65be
Hanno Böck initial commit

Hanno Böck authored 17 years ago

1) #!/usr/bin/python -tO
2) 
3) # freewvs 0.1 - the free web vulnerability scanner
4) #
5) # http://source.schokokeks.org/freewvs/
6) #
7) # Copyright 2007 Hanno Boeck, schokokeks.org <hanno@schokokeks.org>
8) #
9) # Contributions by
10) # Fabian Fingerle <fabian@datensalat.eu>
11) #
12) # This program is free software: you can redistribute it and/or modify
13) # it under the terms of the GNU General Public License as published by
14) # the Free Software Foundation, either version 3 of the License, or
15) # (at your option) any later version.
16) #
17) # This program is distributed in the hope that it will be useful,
18) # but WITHOUT ANY WARRANTY; without even the implied warranty of
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

19) # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
Hanno Böck initial commit

Hanno Böck authored 17 years ago

20) # GNU General Public License for more details.
21) #
22) # You should have received a copy of the GNU General Public License
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

23) # along with this program.    If not, see <http://www.gnu.org/licenses/>.
Hanno Böck initial commit

Hanno Böck authored 17 years ago

24) 
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

25) import ConfigParser, os, glob, pprint, re, optparse, sys, gettext
Hanno Böck initial commit

Hanno Böck authored 17 years ago

26) 
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

27) gettext.textdomain('freewvs')
28) _ = gettext.gettext
Hanno Böck initial commit

Hanno Böck authored 17 years ago

29) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

30) def versioncompare(safe_version, find_version):
31)     if safe_version == [""]:
32)         return True
33)     for i in range(min(len(find_version), len(safe_version))):
34)         if int(find_version[i])<int(safe_version[i]):
35)             return True
36)         if int(find_version[i])>int(safe_version[i]):
37)             return False
38)     return (len(find_version)<len(safe_version))
Hanno Böck initial commit

Hanno Böck authored 17 years ago

39) 
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

40) def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, style = None):
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

41)     appdir = '/'.join(os.path.abspath(vfilename).split('/')[:-1-subdir])
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

42)     if not style:
43)         print "%(appname)s %(version)s (%(safeversion)s) %(vuln)s %(appdir)s" \
44)               % vars()
45)     elif style=='fancy':
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

46)         print _("Directory: %(appdir)s") % vars()
Hanno Böck indentation fix

Hanno Böck authored 16 years ago

47)         if safeversion!="ok":
Hanno Böck add support for unfixed apps

Hanno Böck authored 16 years ago

48)             if safeversion!="":
49)                 print _("Vulnerable %(appname)s %(version)s found, please update to " \
50)                         "%(safeversion)s or above.") % vars()
51)             else:
52)                 print _("Vulnerable %(appname)s %(version)s found, no fixed version available." \
53)                         ) % vars()
Hanno Böck some i18n fixes

Hanno Böck authored 16 years ago

54)             if vuln[:3] == "CVE":
55)                 print _("http://cve.mitre.org/cgi-bin/cvename.cgi?name=%(vuln)s") \
56)                         % vars()
57)             else:
58)                 print (vuln)
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

59)         else:
Hanno Böck some i18n fixes

Hanno Böck authored 16 years ago

60)             print _("%(appname)s %(version)s found." ) % vars()
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

61)         print
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

62)     elif style=='xml':
63)         state = 'vulnerable'
64)         if safeversion == 'ok':
65)             state = 'ok'
66)         print '  <app state="%s">' % state
67)         print '    <appname>%s</appname>' % appname
68)         print '    <version>%s</version>' % version
69)         print '    <directory>%s</directory>' % appdir
70)         if state == 'vulnerable':
71)             print '    <safeversion>%s</safeversion>' % safeversion
72)             print '    <vulninfo>%s</vulninfo>' % vuln
73)         print '  </app>'
74) 
Hanno Böck initial commit

Hanno Böck authored 17 years ago

75) 
76) pp = pprint.PrettyPrinter(indent=4)
77) 
78) # Command-line options
79) parser = optparse.OptionParser()
80) parser.add_option("-a", "--all", action="store_true", dest="ALL",
81)                   help="Show all webapps found, not just vulnerable")
82) parser.add_option("-d", "--debug", action="store_true", dest="DEBUG",
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

83)                   help="Show lots of debugging output, mainly useful"+ \
84)                   "for development")
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

85) parser.add_option("-f", "--fancy", action="store_const", dest="OUTPUT", const="fancy",
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

86)                   help="Show more fancy output")
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

87) parser.add_option("-x", "--xml", action="store_const", dest="OUTPUT", const="xml",
88)                   help="Output results as XML")
Hanno Böck initial commit

Hanno Böck authored 17 years ago

89) opts, args = parser.parse_args()
90) 
91) # Parse vulnerability database
92) config = ConfigParser.ConfigParser()
93) config.read(glob.glob('/usr/share/freewvs/*.freewvs'))
94) config.read(glob.glob('/usr/local/share/freewvs/*.freewvs'))
95) config.read(glob.glob(os.path.dirname(sys.argv[0])+'/freewvsdb/*.freewvs'))
96) 
97) vdb = []
98) for sect in config.sections():
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

99)     item = {}
100) 
101)     # base options
102)     item['name'] = sect
103)     item['safe'] = config.get(sect, 'safe')
104)     item['file'] = config.get(sect, 'file')
105)     item['vuln'] = config.get(sect, 'vuln')
106)     item['subdir'] = int(config.get(sect, 'subdir'))
107) 
108)     # match magic
109)     item['variable'] = []
110)     for var in config.get(sect,'variable').split(","):
111)         item['variable'].append(re.compile(re.escape(var)+
112)                                 r"[^0-9.]*[.]*([0-9.]*[0-9])[^0-9.]"))
113) 
114)     # optional options
115)     if config.has_option(sect,'extra_match'):
116)         item['extra_match'] = config.get(sect,'extra_match')
117)     else:
118)         item['extra_match'] = False
119)     if config.has_option(sect,'add_minor'):
120)         item['add_minor'] = config.get(sect,'add_minor')
121)     else:
122)         item['add_minor'] = False
123)     if config.has_option(sect,'old_safe'):
124)         item['old_safe'] = config.get(sect,'old_safe').split(",")
125)     else:
126)         item['old_safe'] = []
127) 
128)     vdb.append(item)
129) if opts.DEBUG:
130)     pp.pprint(vdb)
Hanno Böck initial commit

Hanno Böck authored 17 years ago

131) 
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

132) if opts.OUTPUT == 'xml':
133)   print '<?xml version="1.0" ?>'
134)   print '<freewvs>'
Hanno Böck initial commit

Hanno Böck authored 17 years ago

135) 
136) # start the search
137) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

138) for fdir in args:
139)     for root, NULL, files in os.walk(fdir):
140)         for filename in files:
141)             for item in vdb:
142)                 if filename == item['file']:
143)                     mfile = os.path.join(root, filename)
144)                     file = open(mfile)
145)                     filestr = file.read()
146)                     file.close()
147) 
148)                     if item['extra_match']:
149)                         ematch = (filestr.find(item['extra_match']) != -1)
150)                     else:
151)                         ematch = True
152) 
153)                     findversion = []
154)                     for var in item['variable']:
155)                         var = var.search(filestr)
156)                         if not var:
157)                             findversion = False
158)                             break
159)                         else:
160)                             findversion.append(var.group(1))
161) 
162)                     if findversion and ematch:
163)                         findversion = '.'.join(findversion)
164) 
165)                         # Very ugly phpbb workaround
166)                         if item['add_minor']:
167)                             findversion = findversion.split('.')
168)                             findversion[-1] = str(int(findversion[-1])+
169)                                             int(item['add_minor']))
170)                             findversion = '.'.join(findversion)
171) 
172)                         if not (versioncompare(item['safe'].split('.'), \
173)                                 findversion.split('.'))) or \
174)                                 item['old_safe'].count(findversion)>0:
175)                             if opts.ALL:
176)                                 if opts.DEBUG:
177)                                     print "File "+mfile
178)                                 vulnprint(item['name'], findversion, \
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

179)                                           "ok", "", mfile, item['subdir'], \
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

180)                                           opts.OUTPUT)
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

181)                         else:
182)                             if opts.DEBUG:
183)                                 print "File "+mfile
Hanno Böck better code for old versions 6

Hanno Böck authored 16 years ago

184)                             safev="9999"
Hanno Böck print more intelligent warn...

Hanno Böck authored 16 years ago

185)                             for ver in item['old_safe']:
186)                                 if (versioncompare(ver.split('.'), \
Hanno Böck better code for old versions 3

Hanno Böck authored 16 years ago

187)                                     findversion.split('.') ) and \
Hanno Böck better code for old versions 6

Hanno Böck authored 16 years ago

188)                                     not versioncompare(ver.split('.'), \
Hanno Böck better code for old versions 3

Hanno Böck authored 16 years ago

189)                                     safev.split('.')) ):
Hanno Böck print more intelligent warn...

Hanno Böck authored 16 years ago

190)                                     safev=ver
Hanno Böck really fix safeversions

Hanno Böck authored 16 years ago

191)                             if safev=="9999":
Hanno Böck print more intelligent warn...

Hanno Böck authored 16 years ago

192)                                 safev=item['safe']
193) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

194)                             vulnprint (item['name'], findversion, \
Hanno Böck print more intelligent warn...

Hanno Böck authored 16 years ago

195)                                        safev, item['vuln'], \
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

196)                                        mfile, item['subdir'], opts.OUTPUT)
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

197) 
198)                     else:
199)                         if opts.DEBUG:
200)                             print "regexp failed for " + \
201)                                   item['name'] + " on " + mfile