293deef3448a7c87fee048dd732d04da34da9f92
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()
44)         print _("Vulnerable %(appname)s %(version)s found, please update to "+ \
45)                 "%(safeversion)s or above.") % vars()
46)         if vuln[:3] == "CVE":
47)             print _("http://cve.mitre.org/cgi-bin/cvename.cgi?name=%(vuln)s"
48)                     % vars())
49)         else:
50)             print (vuln)
51)         print
52)     else:
53)         print "%(appname)s %(version)s (%(safeversion)s) %(vuln)s %(appdir)s" \
54)               % vars()
Hanno Böck initial commit

Hanno Böck authored 17 years ago

55) 
56) pp = pprint.PrettyPrinter(indent=4)
57) 
58) # Command-line options
59) parser = optparse.OptionParser()
60) parser.add_option("-a", "--all", action="store_true", dest="ALL",
61)                   help="Show all webapps found, not just vulnerable")
62) 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

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 17 years ago

67) opts, args = parser.parse_args()
68) 
69) # Parse vulnerability database
70) config = ConfigParser.ConfigParser()
71) config.read(glob.glob('/usr/share/freewvs/*.freewvs'))
72) config.read(glob.glob('/usr/local/share/freewvs/*.freewvs'))
73) config.read(glob.glob(os.path.dirname(sys.argv[0])+'/freewvsdb/*.freewvs'))
74) 
75) vdb = []
76) for sect in config.sections():
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

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

Hanno Böck authored 17 years ago

109) 
110) 
111) # start the search
112) 
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

156)                         else:
157)                             if opts.DEBUG:
158)                                 print "File "+mfile
159)                             vulnprint (item['name'], findversion, \
160)                                        item['safe'], item['vuln'], \
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

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