1ETTERFILTER(8) System Manager's Manual ETTERFILTER(8)
2
3
4
6 etterfilter - Filter compiler for ettercap content filtering engine
7
8
10 etterfilter [OPTIONS] FILE
11
12
13
15 The etterfilter utility is used to compile source filter files into
16 binary filter files that can be interpreted by the JIT interpreter in
17 the ettercap(8) filter engine. You have to compile your filter scripts
18 in order to use them in ettercap. All syntax/parse errors will be
19 checked at compile time, so you will be sure to produce a correct
20 binary filter for ettercap.
21
22
23 GENERAL OPTIONS
24
25 -o, --output <FILE>
26 you can specify the output file for a source filter file. By
27 default the output is filter.ef.
28
29
30 -t, --test <FILE>
31 you can analyze a compiled filter file with this option. etter‐
32 filter will print in a human readable form all the instructions
33 contained in it. It is a sort of "disassembler" for binary fil‐
34 ter files.
35
36
37 -d, --debug
38 prints some debug messages during the compilation. Use it more
39 than once to increase the debug level ( etterfilter -ddd ... ).
40
41
42 -w, --suppress-warnings
43 Don't exit on warnings. With this option the compiler will com‐
44 pile the script even if it contains warnings.
45
46
47 STANDARD OPTIONS
48
49 -v, --version
50 Print the version and exit.
51
52
53 -h, --help
54 prints the help screen with a short summary of the available
55 options.
56
57
58
59
60 SCRIPTS SYNTAX
61 A script is a compound of instructions. It is executed sequen‐
62 tially and you can make branches with the 'if' statements. 'if'
63 and 'if/else' statements are the only supported. No loops are
64 implemented. The syntax is almost like C code except that you
65 have to put 'if' blocks into graph parentheses '{' '}', even if
66 they contain only one instruction.
67
68 NOTE: you have to put a space between the 'if' and the '('. You
69 must not put the space between the function name and the '('.
70
71 Example:
72 if (conditions) { }
73 func(args...);
74
75
76 The conditions for an 'if' statement can be either functions or
77 comparisons. Two or more conditions can be linked together with
78 logical operators like OR '||' and AND '&&'.
79
80 Example:
81 if (tcp.src == 21 && search(DATA.data, "ettercap")) {
82 }
83
84 Pay attention to the operator precedence. You cannot use paren‐
85 theses to group conditions, so be careful with the order. An AND
86 at the beginning of a conditions block will exclude all the
87 other tests if it is evaluated as false. The parsing is left-to-
88 right, when an operator is found: if it is an AND and the previ‐
89 ous condition is false, all the statement is evaluated as false;
90 if it is an OR the parsing goes on even if the condition is
91 false.
92
93 Example:
94 if (ip.proto == UDP || ip.proto == TCP && tcp.src == 80) {
95 }
96
97 if (ip.proto == TCP && tcp.src == 80 || ip.proto == UDP) {
98 }
99
100 the former condition will match all udp or http traffic. The
101 latter is wrong, because if the packet is not tcp, the whole
102 condition block will be evaluated as false. If you want to make
103 complex conditions, the best way is to split them into nested
104 'if' blocks.
105
106 Since etterfilter support both IP address families, you should
107 care whether you use 'ip.proto' which is specific for the IPv4
108 address family or it's IPv6 couterpart 'ipv6.nh'. Especially for
109 the L4 protocol matching using 'ip.proto' and/or 'ipv6.nh', you
110 should be careful if you're really acting on the right protocol.
111 This should be enforced using the L3 protocol identifier
112 'eth.proto'.
113
114 Example:
115 if (eth.proto == IP && ip.proto == TCP && tcp.dst == 80 ||
116 tcp.src == 80) {
117 }
118
119 if (eth.proto == IP6 && ipv6.nh == TCP && tcp.dst == 80 ||
120 tcp.src == 80) {
121 }
122
123 if (tcp.dst == 80 || tcp.src == 80) {
124 }
125
126 The first example correctly matches http traffic only on IPv4
127 while the second would match http traffic only on IPv6. The
128 thrid example matches http regardless it's IP address familiy.
129
130
131 Every instruction in a block must end with a semicolon ';'.
132
133 Comparisons are implemented with the '==' operator and can be
134 used to compare numbers, strings or ip addresses. An ip address
135 MUST be enclosed within two single quotes (eg. '192.168.0.7' or
136 '2001:db8::2'). You can also use the 'less than' ('<'), 'greater
137 than' ('>'), 'less or equal' ('<=') and 'greater or equal'
138 ('>=') operators. The lvalue of a comparison must be an offset
139 (see later)
140
141 Example:
142 if (DATA.data + 20 == "ettercap" && ip.ttl > 16) {
143 }
144
145 Assignments are implemented with the '=' operator and the lvalue
146 can be an offset (see later). The rvalue can be a string, an
147 integer or a hexadecimal value.
148
149 Example:
150 ip.ttl = 0xff;
151 DATA.data + 7 = "ettercap NG";
152
153 You can also use the 'inc' and 'dec' operations on the packet
154 fields. The operators used are '+=' and '-='. The rvalue can be
155 an integer or a hexadecimal value.
156
157 Example:
158 ip.ttl += 5;
159
160 More examples can be found in the etter.filter.examples file.
161
162
163 OFFSET DEFINITION
164 An offset is identified by a virtual pointer. In short words, an
165 offset is a pointer to the packet buffer. The virtual pointer is
166 a tuple <L, O, S>, where L is the iso/osi level, O is the offset
167 in that level and S is the size of the virtual pointer. You can
168 make algebraic operations on a virtual pointer and the result is
169 still an offset. Specifying 'vp + n' will result in a new vir‐
170 tual pointer <L, O+n, S>. And this is perfectly legal, we have
171 changed the internal offset of that level.
172
173 Virtual pointers are in the form 'name.field.subfield'. For
174 example 'ip.ttl' is the virtual pointer for the Time To Live
175 field in the IP header of a packet. It will be translated as
176 <L=3, O=9, S=1>. Indeed it is the 9th byte of level 3 and its
177 size is 1 byte. 'ip.ttl + 1' is the same as 'ip.proto' since the
178 10th byte of the IP header is the protocol encapsulated in the
179 IP packet. Note that since etterfilter also supports processing
180 of IPv6, the above mentioned only applies for IPv4 packets while
181 counterpart in IPv6 would be 'ipv6.nh'.
182
183 The list of all supported virtual pointers is in the file etter‐
184 filter.tbl. You can add your own virtual pointers by adding a
185 new table or modifying the existing ones. Refer to the comments
186 at the beginning of the file for the syntax of etterfilter.tbl
187 file.
188
189
190
191 SCRIPTS FUNCTIONS
192
193 search(where, what)
194 this function searches the string 'what' in the buffer 'where'.
195 The buffer can be either DATA.data or DECODED.data. The former
196 is the payload at layer DATA (ontop TCP or UDP) as it is trans‐
197 mitted on the wire, the latter is the payload decoded/decrypted
198 by dissectors.
199 So, if you want to search in an SSH connection, it is better to
200 use 'DECODED.data' since 'data' will be encrypted.
201 The string 'what' can be binary. You have to escape it.
202
203 example:
204 search(DATA.data, "\x41\x42\x43")
205
206
207
208 regex(where, regex)
209 this function will return true if the 'regex' has matched the
210 buffer 'where'. The considerations about 'DECODED.data' and
211 'DATA.data' mentioned for the function 'search' are the same for
212 the regex function.
213
214 NOTE: regex can be used only against a string buffer.
215
216 example:
217 regex(DECODED.data, ".*login.*")
218
219
220
221 pcre_regex(where, pcre_regex ... )
222 this function will evaluate a perl compatible regular expres‐
223 sion. You can match against both DATA and DECODED, but if your
224 expression modifies the buffer, it makes sense to operate only
225 on DATA. The function accepts 2 or 3 parameters depending on the
226 operation you want. The two parameter form is used only to match
227 a pattern. The three parameter form means that you want to make
228 a substitution. In both cases, the second parameter is the
229 search string.
230 You can use $n in the replacement string. These placeholders are
231 referred to the groups created in the search string. (e.g.
232 pcre_regex(DATA.data, "^var1=([:digit:]*)&var2=([:digit:]*)",
233 "var1=$2&var2=$1") will swap the value of var1 and var2).
234 NOTE: The pcre support is optional in ettercap and will be
235 enabled only if you have the libpcre installed. The compiler
236 will warn you if you try to compile a filter that contains pcre
237 expressions but you don't have libpcre. Use the -w option to
238 suppress the warning.
239
240 example:
241 pcre_regex(DATA.data, ".*foo$")
242 pcre_regex(DATA.data, "([^ ]*) bar ([^ ]*)", "foo $1 $2")
243
244
245
246 replace(what, with)
247 this function replaces the string 'what' with the string 'with'.
248 They can be binary string and must be escaped. The replacement
249 is always performed in DATA.data since is the only payload which
250 gets forwarded. The 'DECODED.data' buffer is used only inter‐
251 nally and never reaches the wire.
252
253 example:
254 replace("ethercap", "ettercap")
255
256
257
258 inject(what)
259 this function injects the content of the file 'what' after the
260 packet being processed. It always injects in DATA.data. You can
261 use it to replace the entire packet with a fake one using the
262 drop() function right before the inject() command. In that case
263 the filtering engine will drop the current packet and inject the
264 fake one.
265
266 example:
267 inject("./fake_packet")
268
269
270
271 log(what, where)
272 this function dumps in the file 'where' the buffer 'what'. No
273 information is stored about the packet, only the payload is
274 dumped. So you will see the stream in the file. If you want to
275 log packets in a more enhanced mode, you need to use the etter‐
276 cap -L option and analyze it with etterlog(8).
277 The file 'where' must be writable to the user EC_UID (see
278 etter.conf(5)).
279
280 example:
281 log(DECODED.data, "/tmp/interesting.log")
282
283
284
285 msg(message)
286 this function displays a message to the user in the User Mes‐
287 sages window. It is useful to let the user know whether a par‐
288 ticular filter has been successful or not.
289
290 example:
291 msg("Packet filtered successfully")
292
293
294
295 drop() this function marks the packet "to be dropped". The packet will
296 not be forwarded to the real destination.
297
298 example:
299 drop()
300
301
302
303 kill() this function kills the connection that owns the matched packet.
304 If it is a TCP connection, a RST is sent to both sides of the
305 connection. If it is an UDP connection, an ICMP PORT UNREACHABLE
306 is sent to the source of the packet.
307
308 example:
309 kill()
310
311
312
313 exec(command)
314 this function executes a shell command. You have to provide the
315 full path to the command since it is executed without any envi‐
316 ronment. There is no way to determine if the command was suc‐
317 cessful or not. Furthermore, it is executed asynchronously since
318 it is forked by the main process.
319
320 example:
321 exec("/bin/cat /tmp/foo >> /tmp/bar")
322
323
324
325
326 execinject(command)
327 this function operates similar to the inject function except
328 that it uses the output of a shell command to inject data rather
329 than the contents of a file. It always injects in DATA.data.
330 You can use it to replace the entire packet with a fake one
331 using the drop() function right before the execinject() command.
332 In that case the filtering engine will drop the current packet
333 and inject the fake one.
334
335
336 example:
337 execinject("/bin/cat /tmp/foo")
338
339
340
341 exit() this function causes the filter engine to stop executing the
342 code. It is useful to stop the execution of the script on some
343 circumstance checked by an 'if' statement.
344
345 example:
346 exit()
347
348
349
350
352 Here are some examples of using etterfilter.
353
354 etterfilter filter.ecf -o filter.ef
355
356 Compiles the source filter.ecf into a binary filter.ef
357
358
359
360
362 Alberto Ornaghi (ALoR) <alor@users.sf.net>
363 Marco Valleri (NaGA) <naga@antifork.org>
364
366 Emilio Escobar (exfil) <eescobar@gmail.com>
367 Eric Milam (Brav0Hax) <jbrav.hax@gmail.com>
368
370 Mike Ryan (justfalter) <falter@gmail.com>
371 Gianfranco Costamagna (LocutusOfBorg) <costamagnagianfranco@yahoo.it>
372 Antonio Collarino (sniper) <anto.collarino@gmail.com>
373 Ryan Linn <sussuro@happypacket.net>
374 Jacob Baines <baines.jacob@gmail.com>
375
377 Dhiru Kholia (kholia) <dhiru@openwall.com>
378 Alexander Koeppe (koeppea) <format_c@online.de>
379 Martin Bos (PureHate) <purehate@backtrack.com>
380 Enrique Sanchez
381 Gisle Vanem <giva@bgnett.no>
382 Johannes Bauer <JohannesBauer@gmx.de>
383 Daten (Bryan Schneiders) <daten@dnetc.org>
384
385
386
387
389 etter.filter.examples
390 ettercap(8) etterlog(8) etter.conf(5) ettercap_curses(8) ettercap_plug‐
391 ins(8) ettercap-pkexec(8)
392
393ettercap 0.8.2 ETTERFILTER(8)