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
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
35 """Generic error during scanning.
36 """
39
42
43
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 """
53
55 """Executes the strategy.
56 """
57 pass
58
59
60
61
62
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
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
84 """Scan a single URL.
85 """
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
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
113 self.logger.info('%s resolves to %s', host, addr)
114
131
133 """Scan multiple URLs.
134 """
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
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
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
189
191 """Clue reader strategy.
192
193 Works by reading and analyzing files of previously stored clues.
194 """
197
205
206
207
208