Package Halberd :: Module shell
[hide private]
[frames] | no frames]

Source Code for Module Halberd.shell

  1  # -*- coding: iso-8859-1 -*- 
  2   
  3  """Provides scanning patterns to be used as building blocks for more complex 
  4  scans. 
  5   
  6  Strategies are different ways in which target scans may be done. We provide 
  7  basic functionality so more complex stuff can be built upon this. 
  8  """ 
  9   
 10  # Copyright (C) 2004, 2005, 2006, 2010  Juan M. Bello Rivas <jmbr@superadditive.com> 
 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 2 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, write to the Free Software 
 24  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 25   
 26   
 27  import Halberd.crew 
 28  import Halberd.logger 
 29  import Halberd.reportlib 
 30  import Halberd.clues.file 
 31  import Halberd.clues.analysis as analysis 
 32   
 33   
34 -class ScanError(Exception):
35 """Generic error during scanning. 36 """
37 - def __init__(self, msg):
38 self.msg = msg
39
40 - def __str__(self):
41 return str(self.msg)
42 43
44 -class BaseStrategy:
45 """Defines the strategy used to scan. 46 47 A strategy is a certain way to use the program. Theses can be layered to 48 build a bigger strategy doing more complex things, etc. 49 """
50 - def __init__(self, scantask):
51 self.task = scantask 52 self.logger = Halberd.logger.getLogger()
53
54 - def execute(self):
55 """Executes the strategy. 56 """ 57 pass
58 59 # --------------------------- 60 # Higher-level helper methods 61 # --------------------------- 62
63 - def _scan(self):
64 """Allocates a work crew of scanners and launches them on the target. 65 """ 66 assert self.task.url and self.task.addr 67 68 self.task.clues = [] 69 self.task.analyzed = [] 70 crew = Halberd.crew.WorkCrew(self.task) 71 self.task.clues = crew.scan()
72
73 - def _analyze(self):
74 """Performs clue analysis. 75 """ 76 if len(self.task.clues) == 0: 77 return 78 79 self.task.analyzed = analysis.analyze(self.task.clues) 80 self.task.analyzed = analysis.reanalyze(self.task.clues, 81 self.task.analyzed, self.task.ratio_threshold)
82
83 -class UniScanStrategy(BaseStrategy):
84 """Scan a single URL. 85 """
86 - def __init__(self, scantask):
87 BaseStrategy.__init__(self, scantask) 88 89 if not self.task.url: 90 raise ScanError, 'Didn\'t provide an URL to scan' 91 92 if self.task.addr: 93 # The user passed a specific address as a parameter. 94 self.addrs = [self.task.addr] 95 else: 96 host = Halberd.util.hostname(self.task.url) 97 self.logger.info('looking up host %s... ', host) 98 99 try: 100 self.addrs = Halberd.util.addresses(host) 101 except KeyboardInterrupt: 102 raise ScanError, 'interrupted by the user' 103 104 if not self.addrs: 105 raise ScanError, 'unable to resolve %s' % host 106 107 self.addrs.sort() 108 self.logger.info('host lookup done.') 109 110 if len(self.addrs) > 1: 111 for addr in self.addrs: 112 #self.logger.debug('%s resolves to %s', host, addr) 113 self.logger.info('%s resolves to %s', host, addr)
114
115 - def execute(self):
116 """Scans, analyzes and presents results coming a single target. 117 """ 118 if self.task.save: 119 cluedir = Halberd.clues.file.ClueDir(self.task.save) 120 121 for self.task.addr in self.addrs: 122 self._scan() 123 124 self._analyze() 125 Halberd.reportlib.report(self.task) 126 127 if self.task.save: 128 cluedir.save(self.task.url, 129 self.task.addr, 130 self.task.clues)
131
132 -class MultiScanStrategy(BaseStrategy):
133 """Scan multiple URLs. 134 """
135 - def __init__(self, scantask):
136 BaseStrategy.__init__(self, scantask) 137 138 if not self.task.urlfile: 139 raise ScanError, 'An urlfile parameter must be provided' 140 141 self.urlfp = open(self.task.urlfile, 'r')
142
143 - def _targets(self, urlfp):
144 """Obtain target addresses from URLs. 145 146 @param urlfp: File where the list of URLs is stored. 147 @type urlfp: C{file} 148 149 @return: Generator providing the desired addresses. 150 """ 151 for url in urlfp: 152 if url == '\n': 153 continue 154 155 # Strip end of line character and whitespaces. 156 url = url[:-1].strip() 157 158 host = Halberd.util.hostname(url) 159 if not host: 160 self.logger.warn('unable to extract hostname from %s', host) 161 continue 162 163 self.logger.info('looking up host %s... ', host) 164 try: 165 addrs = Halberd.util.addresses(host) 166 except KeyboardInterrupt: 167 raise ScanError, 'interrupted by the user' 168 self.logger.info('host lookup done.') 169 170 for addr in addrs: 171 yield (url, addr)
172
173 - def execute(self):
174 """Launch a multiple URL scan. 175 """ 176 cluedir = Halberd.clues.file.ClueDir(self.task.save) 177 178 for url, addr in self._targets(self.urlfp): 179 self.task.url = url 180 self.task.addr = addr 181 self.logger.info('scanning %s (%s)', url, addr) 182 self._scan() 183 184 cluedir.save(url, addr, self.task.clues) 185 186 self._analyze() 187 188 Halberd.reportlib.report(self.task)
189
190 -class ClueReaderStrategy(BaseStrategy):
191 """Clue reader strategy. 192 193 Works by reading and analyzing files of previously stored clues. 194 """
195 - def __init__(self, scantask):
196 BaseStrategy.__init__(self, scantask)
197
198 - def execute(self):
199 """Reads and interprets clues. 200 """ 201 self.task.clues = Halberd.clues.file.load(self.task.cluefile) 202 self._analyze() 203 self.task.url = self.task.cluefile 204 Halberd.reportlib.report(self.task)
205 206 207 # vim: ts=4 sw=4 et 208