# Pantera - Web Pen-Test Proxy # # FILENAME : panteraAnalyzer.py # CODER : Simon Roses Femerling # DATE : 11/28/2005 # LAST UPDATE : 06/29/2006 # ABSTRACT : Used by Pantera to perform analysis on data. # # - Roses Labs Innovations (RL+I) # Roses Labs # http://www.roseslabs.com # # Copyright (c) 2003-2006 Roses Labs. # # You may not distribute, transmit, repost this software for commercial # purposes without Roses Labs written permission. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, publish, # distribute the Software, and to permit persons to whom the Software # is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ''' @author: Simon Roses Femerling @license: GNU General Public License 2.0 or later @contact: pantera.proxy@gmail.com @organization: OWASP / Roses Labs ''' ''' PanteraPassiveAnalyzer (PPA): Pantera passive analysis engine. ''' import threading import Queue import sys import time import re import md5 import string import panteraSnitch import pickle ############################################################################################# # classes ############################################################################################# ############################################################################################# # FUNC : class PanteraPassiveAnalyzer # PARAMS : threading.Thread # RETURN : ... # ABSTRACT : PPA Analyzer class PanteraPassiveAnalyzer(threading.Thread): ''' ''' """Base class for PanteraPassiveAnalyzer (PPA)""" ############################################################################################# # FUNC : def __init__ # PARAMS : ppa, input, value, con # RETURN : ... # ABSTRACT : Init PPA Analyzer internal variables def __init__(self, ppa, input, project_id, connection): ''' ''' self._ppa = ppa self._input = input self._project_id = project_id self._connection = connection threading.Thread.__init__(self) self._input_obj = "" # EOF: def __init__ ############################################################################################# # FUNC : def run # PARAMS : ... # RETURN : ... # ABSTRACT : Analyze page using PPA plugins and insert into DDBB def run(self): ''' ''' """Main function""" while True: try: feed = self._input.get_nowait() except Queue.Empty: #print >>sys.stderr, "feeder thread %s reached end of job queue" % self break self._input_id, self._input_obj = feed self.data = {} # all valid tags for DDBB self.data['have_ssl'] = 0 self.data['have_email'] = 0 self.data['have_script'] = 0 self.data['have_form'] = 0 self.data['have_cookie'] = 0 self.data['have_session_id'] = 0 self.data['have_external_link'] = 0 self.data['have_comment'] = 0 self.data['have_vuln'] = 0 self.data['have_hidden'] = 0 self.data['have_auth_form'] = 0 self.data['have_object'] = 0 self.data['have_querystr'] = 0 self.data['have_postauth'] = 0 self.data['have_auth'] = 0 self.data['method'] = "'" + self._input_obj.clientheader.verb + "'" m = md5.new(self._input_obj.serverbody.printme()) self.data['page_hash'] = "'" + m.hexdigest() + "'" self.data['return_code'] = "'" + self._input_obj.serverheader.returncode + "'" self.data['return_msg'] = "'" + self._input_obj.serverheader.returnmessage + "'" self.data['version'] = "'" + self._input_obj.serverheader.version + "'" ext = self._input_obj.clientheader.URL.split(".")[-1] ext = ext.lower() self.data['host'] = "'" + self._input_obj.clientheader.connectHost + "'" self.data['extension'] = "'" + ext + "'" add_vuln = "" # Begin running plugins for mod in self._ppa.GetPlugins(): mod_dat = self._ppa.GetPluginData(mod) if mod_dat is None: continue check = self._ppa.CheckTag(mod_dat['tag']) if check == 1 and mod_dat.has_key('tag'): do_class = self._ppa.GetPluginClass(mod,mod_dat['id']) if do_class is None: continue dc = do_class() dc.InitAnalyzer() dc.BeginAnalyzer(self._input_obj) t = dc.GetHave() if t != '' and t != 'recon' and dc.GetResult() == 1: # Set flag 1 on some tags (script, comment, etc...) icheck = self._ppa.CheckTag(t) if icheck == 1: self.data['have_'+t] = 1 # not be best but will do :/ r = dc.GetType() if r != "" and dc.GetResult() == 1: #we got data l = dc.GetTypeData() for n in l: d = {} d['project_id'] = self._project_id d['type'] = "'" + r + "'" d['value'] = n d['domain'] = "'" + self._input_obj.clientheader.connectHost + "'" self._connection.Insert_Project_Info(d) if dc.GetCheckResultData()==1: for a_v in dc.GetResultData(): a_v = string.replace(a_v,"'","") # make sure not ' goes into DDBB add_vuln += a_v + "|<>|" f = dc.GetOtherType() if f != "": icheck = self._ppa.CheckTag(f) if icheck == 1: self.data['have_'+f] = 1 # End running plugins # Begin Pantera Snitch ps = panteraSnitch.PanteraSnitch(self._input_obj.printBody(1)) p = ps.BeginSnitch() if p == 0: u = ps.ReturnURLS() c = ps.ReturnComment() s = ps.ReturnScript() o = panteraSnitch.PanteraSnithStore() o.InsertStore(self._input_id,u,c,s) od = pickle.dumps(o,1) self._connection.Insert_Snitch(self._project_id, self._input_id, od) # End Pantera Snitch # Insert data into page_info_t if add_vuln != "": self.data['vuln_data'] = "'" + add_vuln + "'" self.data['project_id'] = self._project_id self.data['link_id'] = self._input_id self._connection.Insert_New_Page(self.data) # EOF: def run # RL+I EOF