c2ed542d776566c12e1531f02611aba051f9d686
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) 
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

40) def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, fancy):
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])
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

42)     if fancy:
43)         print _("Directory: %(appdir)s") % vars()
Hanno Böck indentation fix

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

56)         else:
Hanno Böck some i18n fixes

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

58)         print
59)     else:
60)         print "%(appname)s %(version)s (%(safeversion)s) %(vuln)s %(appdir)s" \
61)               % vars()
Hanno Böck initial commit

Hanno Böck authored 17 years ago

62) 
63) pp = pprint.PrettyPrinter(indent=4)
64) 
65) # Command-line options
66) parser = optparse.OptionParser()
67) parser.add_option("-a", "--all", action="store_true", dest="ALL",
68)                   help="Show all webapps found, not just vulnerable")
69) 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

70)                   help="Show lots of debugging output, mainly useful"+ \
71)                   "for development")
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

72) parser.add_option("-f", "--fancy", action="store_true", dest="FANCY",
73)                   help="Show more fancy output")
Hanno Böck initial commit

Hanno Böck authored 17 years ago

74) opts, args = parser.parse_args()
75) 
76) # Parse vulnerability database
77) config = ConfigParser.ConfigParser()
78) config.read(glob.glob('/usr/share/freewvs/*.freewvs'))
79) config.read(glob.glob('/usr/local/share/freewvs/*.freewvs'))
80) config.read(glob.glob(os.path.dirname(sys.argv[0])+'/freewvsdb/*.freewvs'))
81) 
82) vdb = []
83) for sect in config.sections():
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

84)     item = {}
85) 
86)     # base options
87)     item['name'] = sect
88)     item['safe'] = config.get(sect, 'safe')
89)     item['file'] = config.get(sect, 'file')
90)     item['vuln'] = config.get(sect, 'vuln')
91)     item['subdir'] = int(config.get(sect, 'subdir'))
92) 
93)     # match magic
94)     item['variable'] = []
95)     for var in config.get(sect,'variable').split(","):
96)         item['variable'].append(re.compile(re.escape(var)+
97)                                 r"[^0-9.]*[.]*([0-9.]*[0-9])[^0-9.]"))
98) 
99)     # optional options
100)     if config.has_option(sect,'extra_match'):
101)         item['extra_match'] = config.get(sect,'extra_match')
102)     else:
103)         item['extra_match'] = False
104)     if config.has_option(sect,'add_minor'):
105)         item['add_minor'] = config.get(sect,'add_minor')
106)     else:
107)         item['add_minor'] = False
108)     if config.has_option(sect,'old_safe'):
109)         item['old_safe'] = config.get(sect,'old_safe').split(",")
110)     else:
111)         item['old_safe'] = []
112) 
113)     vdb.append(item)
114) if opts.DEBUG:
115)     pp.pprint(vdb)
Hanno Böck initial commit

Hanno Böck authored 17 years ago

116) 
117) 
118) # start the search
119) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

120) for fdir in args:
121)     for root, NULL, files in os.walk(fdir):
122)         for filename in files:
123)             for item in vdb:
124)                 if filename == item['file']:
125)                     mfile = os.path.join(root, filename)
126)                     file = open(mfile)
127)                     filestr = file.read()
128)                     file.close()
129) 
130)                     if item['extra_match']:
131)                         ematch = (filestr.find(item['extra_match']) != -1)
132)                     else:
133)                         ematch = True
134) 
135)                     findversion = []
136)                     for var in item['variable']:
137)                         var = var.search(filestr)
138)                         if not var:
139)                             findversion = False
140)                             break
141)                         else:
142)                             findversion.append(var.group(1))
143) 
144)                     if findversion and ematch:
145)                         findversion = '.'.join(findversion)
146) 
147)                         # Very ugly phpbb workaround
148)                         if item['add_minor']:
149)                             findversion = findversion.split('.')
150)                             findversion[-1] = str(int(findversion[-1])+
151)                                             int(item['add_minor']))
152)                             findversion = '.'.join(findversion)
153) 
154)                         if not (versioncompare(item['safe'].split('.'), \
155)                                 findversion.split('.'))) or \
156)                                 item['old_safe'].count(findversion)>0:
157)                             if opts.ALL:
158)                                 if opts.DEBUG:
159)                                     print "File "+mfile
160)                                 vulnprint(item['name'], findversion, \
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

161)                                           "ok", "", mfile, item['subdir'], \
162)                                           opts.FANCY)
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

163)                         else:
164)                             if opts.DEBUG:
165)                                 print "File "+mfile
Hanno Böck print more intelligent warn...

Hanno Böck authored 16 years ago

166)                             safev=""
167)                             for ver in item['old_safe']:
168)                                 if (versioncompare(ver.split('.'), \
Hanno Böck better code for old versions 3

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

172)                                     safev=ver
173)                             if safev=="":
174)                                 safev=item['safe']
175) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

177)                                        safev, item['vuln'], \
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

178)                                        mfile, item['subdir'], opts.FANCY)