# ****************************************************** # Copyright 2004: Commonwealth of Australia. # # Developed by the Computer Network Vulnerability Team, # Information Security Group. # Department of Defence. # # David Collett # Michael Cohen # # ****************************************************** # Version: FLAG $Version: 0.87-pre1 Date: Thu Jun 12 00:48:38 EST 2008$ # ****************************************************** # # * This program is free software; you can redistribute it and/or # * modify it under the terms of the GNU General Public License # * as published by the Free Software Foundation; either version 2 # * of the License, or (at your option) any later version. # * # * This program is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY; without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # * GNU General Public License for more details. # * # * You should have received a copy of the GNU General Public License # * along with this program; if not, write to the Free Software # * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ****************************************************** """ Module for analysing Log files """ import pyflag.Reports as Reports import pyflag.FlagFramework as FlagFramework from pyflag.FlagFramework import query_type import pyflag.LogFile as LogFile import pyflag.DB as DB import pyflag.conf config=pyflag.conf.ConfObject() import re import plugins.LogAnalysis.Whois as Whois import pyflag.Registry as Registry from pyflag.ColumnTypes import ColumnType, StringType description = "Log Analysis" order = 35 class ListLogFile(Reports.report): """ Lists the content of the log file using the table UI object """ parameters = {"logtable":"casetable"} name="List log file contents" family = "Log Analysis" description="This report simply lists the log entries in a searchable/groupable table" def form(self,query,result): try: result.case_selector() result.selector('Select Log Table','logtable', "select table_name as `key`, table_name as value from log_tables", case=query['case']) except KeyError: pass def display(self,query,result): if (query.has_key('limit')): result.heading("Log File in Table %s" % query['logtable']) else: result.heading("Log File in Table %s" % query['logtable']) dbh = DB.DBO(query['case']) ## Fetch the driver to use: dbh.execute("select * from log_tables where table_name='%s' limit 1",(query['logtable'])) row=dbh.fetch() if not row: raise Reports.ReportError("Log Table %s not found" % query['logtable']) try: ## Instantiate the driver on this case: log = LogFile.load_preset(query['case'], row['preset']) except KeyError,e: raise Reports.ReportError("Unable to load the preset %s for table %s " % (row['preset'],query['logtable'])) ## Display it now: log.display(query['logtable'],result); class CreateLogPreset(Reports.report): """ Creates a new type of log file in the database, so that they can be loaded using the Load Log File report""" parameters = {"log_preset":"any", "final":"any"} name="Create Log Preset" family = "Log Analysis" description="Create new preset log type" order=40 def reset(self,query): dbh = self.DBO(None) dbh.delete("log_preset", where="name = %r" % query['log_preset']) def display(self,query,result): result.heading("New log file preset %s created" % query['log_preset']) result.link("Load a log file", query_type(case=None, family='Load Data', report='LoadPresetLog', log_preset=query['log_preset'])) return result def form(self,query,result): try: ## Try to get the driver log=Registry.LOG_DRIVERS.dispatch(query['driver'])() ## Ask the driver to render a form: log.form(query,result) except KeyError,e: ## Chose a driver to use: result.const_selector("Select Log Processor", 'driver', Registry.LOG_DRIVERS.class_names , Registry.LOG_DRIVERS.class_names ) class BandWidth(Reports.report): """ Calculates the approximate bandwidth requirements by adding the size of each log entry within time period """ parameters = {"logtable":"casetable","timestamp":"sqlsafe","size":"sqlsafe"} name = "Estimate Bandwidth" family = "Log Analysis" hidden=True description="Estimate approximate bandwidth requirements from log file" def form(self,query,result): dbh = self.DBO(query['case']) result.para("This report approximates the amount of bandwidth used by the server that produced the log file. This is done by adding the total number of bytes transfered within a specified time preiod (called a bin). Bins are specified in seconds. The result is a graph showing how many bytes were transfered per bin.") try: result.case_selector() result.meta_selector(query['case'],'Select Log Table','logtable') dbh.execute("select * from `%s` limit 1",query['logtable']) columns = [ d[0] for d in dbh.cursor.description ] result.const_selector("Timestamp column:",'timestamp',columns,columns) result.const_selector("Size column:",'size',columns,columns) except KeyError: pass def display(self,query,result): dbh = self.DBO(query['case']) try: bin_size=int(query['bin_size']) except KeyError: bin_size=60 query['bin_size']=str(bin_size) result.heading("Bandwidth estimate from log %s"%query['logtable']) result.start_table() result.start_form(query) result.textfield('Bin Size (Seconds):','bin_size') result.end_form(None) result.end_table() if query.has_key('graph'): new_query=query.clone() del new_query['graph'] del new_query['limit'] result.link("Click here to view table",new_query) params={'timestamp':query['timestamp'],'bin_size':bin_size,'size':query['size'],'logtable':query['logtable']} try: start=int(query['limit']) if not start: raise KeyError except KeyError: dbh.execute('select unix_timestamp(min(%(timestamp)s)) as `min` from %(logtable)s'%params) start=dbh.fetch()['min'] params['start']=start result.para("") dbh.execute('select unix_timestamp(%(timestamp)s) as `timestamp`,floor(unix_timestamp(%(timestamp)s)/%(bin_size)s)*%(bin_size)s as `Unix Timestamp`,from_unixtime(floor(unix_timestamp(%(timestamp)s)/%(bin_size)s)*%(bin_size)s) as `DateTime`,sum(%(size)s) as `Count` from %(logtable)s where `%(timestamp)s`>from_unixtime("%(start)s") and `%(timestamp)s`