a4dc558e26f17a19065822e88f7357d04d69c24d
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
Bernd Wurst Add XML string escaping

Bernd Wurst authored 16 years ago

26) from xml.sax.saxutils import escape
Hanno Böck initial commit

Hanno Böck authored 17 years ago

27) 
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

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

Hanno Böck authored 17 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 17 years ago

40) 
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

41) 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

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

Bernd Wurst authored 16 years ago

43)     if not style:
Hanno Böck replace print with function...

Hanno Böck authored 14 years ago

44)         print ("%(appname)s %(version)s (%(safeversion)s) %(vuln)s %(appdir)s" \
45)               % vars())
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

46)     elif style=='fancy':
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

49)             if safeversion!="":
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

50)                 print (_("Vulnerable %(appname)s %(version)s found, please update to " \
51)                         "%(safeversion)s or above.") % vars())
Hanno Böck add support for unfixed apps

Hanno Böck authored 16 years ago

52)             else:
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

53)                 print (_("Vulnerable %(appname)s %(version)s found, no fixed version available." \
54)                         ) % vars())
Hanno Böck some i18n fixes

Hanno Böck authored 16 years ago

55)             if vuln[:3] == "CVE":
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

56)                 print (_("http://cve.mitre.org/cgi-bin/cvename.cgi?name=%(vuln)s") \
57)                         % vars())
Hanno Böck some i18n fixes

Hanno Böck authored 16 years ago

58)             else:
59)                 print (vuln)
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

60)         else:
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

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

Hanno Böck authored 16 years ago

62)         print
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

63)     elif style=='xml':
64)         state = 'vulnerable'
65)         if safeversion == 'ok':
66)             state = 'ok'
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

67)         print ('  <app state="%s">' % state)
68)         print ('    <appname>%s</appname>' % escape(appname))
69)         print ('    <version>%s</version>' % escape(version))
70)         print ('    <directory>%s</directory>' % escape(appdir))
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

71)         if state == 'vulnerable':
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

72)             print ('    <safeversion>%s</safeversion>' % escape(safeversion))
73)             print ('    <vulninfo>%s</vulninfo>' % escape(vuln))
74)         print ('  </app>')
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

75) 
Hanno Böck initial commit

Hanno Böck authored 17 years ago

76) 
77) pp = pprint.PrettyPrinter(indent=4)
78) 
79) # Command-line options
80) parser = optparse.OptionParser()
81) parser.add_option("-a", "--all", action="store_true", dest="ALL",
82)                   help="Show all webapps found, not just vulnerable")
83) 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

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

Bernd Wurst authored 16 years ago

86) 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

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

Bernd Wurst authored 16 years ago

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

Hanno Böck authored 17 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 17 years ago

132) 
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

133) if opts.OUTPUT == 'xml':
Hanno Böck more print to function conv...

Hanno Böck authored 14 years ago

134)   print ('<?xml version="1.0" ?>')
135)   print ('<freewvs>')
Hanno Böck initial commit

Hanno Böck authored 17 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 14 years ago

178)                                     print ("File "+mfile)
Hanno Böck fix lot's of pylint issues...

Hanno Böck authored 16 years ago

179)                                 vulnprint(item['name'], findversion, \
Hanno Böck add fancy output

Hanno Böck authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Hanno Böck authored 16 years ago

182)                         else:
183)                             if opts.DEBUG:
Hanno Böck replace print with function...

Hanno Böck authored 14 years ago

184)                                 print ("File "+mfile)
Hanno Böck better code for old versions 6

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Hanno Böck authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Hanno Böck authored 16 years ago

198) 
199)                     else:
200)                         if opts.DEBUG:
Hanno Böck replace print with function...

Hanno Böck authored 14 years ago

201)                             print ("regexp failed for " + \
202)                                   item['name'] + " on " + mfile)
Bernd Wurst add XML output format

Bernd Wurst authored 16 years ago

203) 
204) if opts.OUTPUT == 'xml':