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
19) # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20) # GNU General Public License for more details.
21) #
22) # You should have received a copy of the GNU General Public License
23) # along with this program. If not, see <http://www.gnu.org/licenses/>.
24)
25) import ConfigParser, os, glob, pprint, re, optparse, sys
26)
27)
28) def versioncompare(safe_version,find_version):
29) if safe_version==[""]: return True
30) for i in range(min(len(find_version),len(safe_version))):
31) if int(find_version[i])<int(safe_version[i]):
32) return True
33) if int(find_version[i])>int(safe_version[i]):
34) return False
35) return (len(find_version)<len(safe_version))
36)
37) def vulnprint(appname,version,safeversion,vuln,filename,subdir):
38) appdir='/'.join(os.path.abspath(filename).split('/')[:-1-subdir])
39) print "%(appname)s %(version)s (%(safeversion)s) %(vuln)s %(appdir)s" % vars()
40)
41) pp = pprint.PrettyPrinter(indent=4)
42)
43) # Command-line options
44) parser = optparse.OptionParser()
45) parser.add_option("-a", "--all", action="store_true", dest="ALL",
46) help="Show all webapps found, not just vulnerable")
47) parser.add_option("-d", "--debug", action="store_true", dest="DEBUG",
48) help="Show lots of debugging output, mainly useful for development")
49) opts, args = parser.parse_args()
50)
51) # Parse vulnerability database
52) config = ConfigParser.ConfigParser()
53) config.read(glob.glob('/usr/share/freewvs/*.freewvs'))
54) config.read(glob.glob('/usr/local/share/freewvs/*.freewvs'))
55) config.read(glob.glob(os.path.dirname(sys.argv[0])+'/freewvsdb/*.freewvs'))
56)
57) vdb = []
58) for sect in config.sections():
59) item={}
60)
61) # base options
62) item['name']=sect
63) item['safe']=config.get(sect,'safe')
64) item['file']=config.get(sect,'file')
65) item['vuln']=config.get(sect,'vuln')
66) item['subdir']=int(config.get(sect,'subdir'))
67)
68) # match magic
69) item['variable']=[]
70) for var in config.get(sect,'variable').split(","):
71) item['variable'].append(re.compile(re.escape(var)+r"[^0-9.]*[.]*([0-9.]*[0-9])[^0-9.]"))
72)
73) # optional options
74) if config.has_option(sect,'extra_match'): item['extra_match']=config.get(sect,'extra_match')
75) else: item['extra_match']=False
76) if config.has_option(sect,'add_minor'): item['add_minor']=config.get(sect,'add_minor')
77) else: item['add_minor']=False
78) if config.has_option(sect,'old_safe'): item['old_safe']=config.get(sect,'old_safe').split(",")
79) else: item['old_safe']=[]
80)
81) vdb.append(item)
82) if opts.DEBUG: pp.pprint(vdb)
83)
84)
85) # start the search
86)
87) for dir in args:
88) for root,NULL,files in os.walk(dir):
89) for filename in files:
90) for item in vdb:
91) if filename == item['file']:
92) mfile=os.path.join(root,filename)
93) file=open(mfile)
94) filestr=file.read()
95) file.close()
96)
97) if item['extra_match']: ematch=(filestr.find(item['extra_match'])!=-1)
98) else: ematch=True
99)
100) findversion=[]
101) for var in item['variable']:
102) var = var.search(filestr)
103) if not var:
104) findversion=False
105) break
106) else:
107) findversion.append(var.group(1))
108)
109) if findversion and ematch:
110) findversion='.'.join(findversion)
111)
112) # Very ugly phpbb workaround
113) if item['add_minor']:
114) findversion=findversion.split('.')
115) findversion[-1]=str(int(findversion[-1])+int(item['add_minor']))
116) findversion='.'.join(findversion)
117)
118) if not (versioncompare(item['safe'].split('.'),findversion.split('.'))) or item['old_safe'].count(findversion)>0:
|