0 | |
FTester - Introduction and Tutorial v1.0
|
1 | |
|
2 | |
The Firewall Tester (ftester for friends), is a tool designed for testing
|
3 | |
firewalls filtering policies, from version 0.6 it also includes an Intrusion
|
|
0 |
|
|
1 |
NOTE: this tool is now outdated and is presented here for historical reasons.
|
|
2 |
|
|
3 |
FTester - Introduction and Tutorial
|
|
4 |
|
|
5 |
The Firewall Tester (ftester for friends), is a tool designed for testing
|
|
6 |
firewalls filtering policies, from version 0.6 it also includes an Intrusion
|
4 | 7 |
Detection System (IDS) testing feature. Basically ftester is made of a packet
|
5 | |
generator tool (ftest) and a sniffer (ftestd), the first script injects custom
|
6 | |
packets with a signature in the data part while the sniffer listens for such
|
7 | |
marked packets, the comparison of the sniffer logs with the injector ones
|
8 | |
permits the identification of firewall filtering rules. Unlike common firewall
|
9 | |
testing tools or packet generators ftester is capable of generating network
|
10 | |
traffic that will looks like real connections to the firewall or IDS system
|
11 | |
tested, this feature allows us to test stateful inspection firewalls (like
|
12 | |
netfilter or ipfilter) and IDS (like snort). Another advantage of this
|
13 | |
architecture is that we can spoof crafted packets source address since the
|
14 | |
sniffer knows which packets are generated by it's counterpart, some tricks
|
15 | |
involving TTL permits the spoofing also when simulating real connections, this
|
16 | |
is described as the 'connection spoofing mode'.
|
|
8 |
generator tool (ftest) and a sniffer (ftestd), the first script injects custom
|
|
9 |
packets with a signature in the data part while the sniffer listens for such
|
|
10 |
marked packets, the comparison of the sniffer logs with the injector ones
|
|
11 |
permits the identification of firewall filtering rules. Unlike common firewall
|
|
12 |
testing tools or packet generators ftester is capable of generating network
|
|
13 |
traffic that will looks like real connections to the firewall or IDS system
|
|
14 |
tested, this feature allows us to test stateful inspection firewalls (like
|
|
15 |
netfilter or ipfilter) and IDS (like snort). Another advantage of this
|
|
16 |
architecture is that we can spoof crafted packets source address since the
|
|
17 |
sniffer knows which packets are generated by it's counterpart, some tricks
|
|
18 |
involving TTL permits the spoofing also when simulating real connections, this
|
|
19 |
is described as the 'connection spoofing mode'.
|
17 | 20 |
|
18 | 21 |
The ftester components are perl scripts so they can be executed on any platform
|
19 | 22 |
with a recent version of perl (at least 5.6.1 is recommended) and the three perl
|
20 | |
modules Net::RawIP, Net::PcapUtils, NetPacket, they can be downloaded at
|
|
23 |
modules Net::RawIP, Net::PcapUtils, NetPacket, they can be downloaded at
|
21 | 24 |
www.cpan.org or using the CPAN shell.
|
22 | 25 |
|
23 | |
Installation is quite simple, just untar the archive ftester-X.X.tar.gz and
|
|
26 |
Installation is quite simple, just untar the archive ftester-X.X.tar.gz and
|
24 | 27 |
everything we need will be decompressed in the ftester-X.X directory, here
|
25 | 28 |
we'll find:
|
26 | 29 |
|
|
29 | 32 |
- ftest.conf (ftest example configuration file)
|
30 | 33 |
- freport (a script for comparing ftest and ftestd log files)
|
31 | 34 |
|
32 | |
the rest is documentation (I recommend reading the man page ftester.8).
|
|
35 |
the rest is documentation (I recommend reading the man page ftester.8).
|
33 | 36 |
|
34 | 37 |
The invocation of ftest and ftestd without options will show an usage summary,
|
35 | 38 |
look at the documentation for a detailed explanation regarding these options and
|
|
89 | 92 |
|
90 | 93 |
here's are a few examples:
|
91 | 94 |
|
92 | |
# SYN packet to 10.1.7.1 port 80
|
|
95 |
# SYN packet to 10.1.7.1 port 80
|
93 | 96 |
192.168.0.10:1024:10.1.7.1:80:S:TCP:0
|
94 | 97 |
|
95 | 98 |
# PSH,ACK reply from 192.168.0.10
|
|
115 | 118 |
stop_signal=192.168.0.1:666:10.1.7.1:666:S:TCP:
|
116 | 119 |
|
117 | 120 |
the stop_signal can be a TCP, UDP or ICMP packet, this packet will cause the
|
118 | |
termination of the sniffer so every packet specified after the stop_signal
|
|
121 |
termination of the sniffer so every packet specified after the stop_signal
|
119 | 122 |
directive wont be seen by ftestd.
|
120 | 123 |
|
121 | |
Let's first see it's basic usage in testing basic non-stateful firewall
|
122 | |
filtering policies. We'll use the ftest script on a machine placed outside the
|
123 | |
firewall and ftestd on a machine placed inside the firewall on the DMZ we want
|
124 | |
to test (of course if we want to test outbound filtering we can reverse ftest
|
|
124 |
Let's first see it's basic usage in testing basic non-stateful firewall
|
|
125 |
filtering policies. We'll use the ftest script on a machine placed outside the
|
|
126 |
firewall and ftestd on a machine placed inside the firewall on the DMZ we want
|
|
127 |
to test (of course if we want to test outbound filtering we can reverse ftest
|
125 | 128 |
and ftestd placement).
|
126 | 129 |
|
127 | 130 |
----------- ------------
|
|
134 | 137 |
|
135 | 138 |
Step 1:
|
136 | 139 |
|
137 | |
For testing which privileged services can be reached from the outside we'll use
|
|
140 |
For testing which privileged services can be reached from the outside we'll use
|
138 | 141 |
the following simple configuration file:
|
139 | 142 |
|
140 | 143 |
- ftest.conf -
|
|
154 | 157 |
|
155 | 158 |
[root@hostb]# ./ftestd -i eth0 -v
|
156 | 159 |
|
157 | |
Let's injects the packets as root on Host A:
|
|
160 |
Let's injects the packets as root on Host A:
|
158 | 161 |
|
159 | 162 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01
|
160 | 163 |
|
|
173 | 176 |
1024 - 192.168.0.10:1025 > 10.1.7.1:1024 S TCP 0
|
174 | 177 |
1025 - 192.168.0.10:1025 > 10.1.7.1:1025 S TCP 0
|
175 | 178 |
1026 - 192.168.0.10:1025 > 10.1.7.1:3128 S TCP 0
|
176 | |
1027 - 192.168.0.10:80 > 10.1.7.1:1025 PA TCP
|
|
179 |
1027 - 192.168.0.10:80 > 10.1.7.1:1025 PA TCP
|
177 | 180 |
# ftest stopped on Tue Jun 4 22:38:42 CEST 2002
|
178 | 181 |
|
179 | 182 |
On Host B ftestd shows the same messages and creates the ftestd.log file.
|
|
223 | 226 |
the outside, https is forwarded to host 10.1.7.5 and the rest, including the
|
224 | 227 |
proxy port is filtered, of course NAT regarding the destination address can be
|
225 | 228 |
detected only if we sniff on a non-switched environment otherwise only port
|
226 | |
address translation or source address translation can be detected.
|
227 | |
|
228 | |
The sniffing of packet 1027 (the PSH,ACK from port 80) demonstrate that we are
|
|
229 |
address translation or source address translation can be detected.
|
|
230 |
|
|
231 |
The sniffing of packet 1027 (the PSH,ACK from port 80) demonstrate that we are
|
229 | 232 |
dealing with a simple firewall that does not perform connection tracking,
|
230 | 233 |
however as of today stateful inspection firewalls are more likely to be found in
|
231 | 234 |
real environments. Stateful inspection firewalls usually performs connection
|
232 | 235 |
tracking and they are not suppose to pass unmatched packets that aren't part of
|
233 | |
a previously initiated connection, for this reason if we need to test the
|
234 | |
filtering policies regarding PSH,ACK and moreover URG,RST,FIN packets we have to
|
235 | |
create a real connection with the proper SYN,SYN-ACK,ACK handshake before
|
236 | |
sending them with the correct sequence numbers, the ftestd process will send the
|
237 | |
correct replies. However when simulating the connection if we are spoofing the
|
238 | |
source address the stack of the destination host will reply to our spoofed
|
239 | |
packets and the real host that we'are spoofing will consequently reset the
|
240 | |
connection since it hasn't started it. So we have to do two things, hiding the
|
241 | |
stack response to the spoofed host and to the firewall and make sure that ftestd
|
242 | |
reply will traverse the firewall by not reaching the spoofed host. Hiding the
|
243 | |
stack response could be done by setting a very low default TTL in
|
244 | |
/proc/sys/net/ipv4/ip_default_ttl (Linux only). Hiding to the spoofed host
|
245 | |
ftestd reply is done by setting its TTL to a low value equal to the hop delay
|
246 | |
between ftestd and the firewall. The -s flag for ftest and the -c flag for
|
247 | |
ftestd must be tuned for this mode, for example use ./ftestd -c 0:3 for
|
248 | |
temporarly setting default stack ttl to 0 and ftestd reply ttl to 3, the
|
|
236 |
a previously initiated connection, for this reason if we need to test the
|
|
237 |
filtering policies regarding PSH,ACK and moreover URG,RST,FIN packets we have to
|
|
238 |
create a real connection with the proper SYN,SYN-ACK,ACK handshake before
|
|
239 |
sending them with the correct sequence numbers, the ftestd process will send the
|
|
240 |
correct replies. However when simulating the connection if we are spoofing the
|
|
241 |
source address the stack of the destination host will reply to our spoofed
|
|
242 |
packets and the real host that we'are spoofing will consequently reset the
|
|
243 |
connection since it hasn't started it. So we have to do two things, hiding the
|
|
244 |
stack response to the spoofed host and to the firewall and make sure that ftestd
|
|
245 |
reply will traverse the firewall by not reaching the spoofed host. Hiding the
|
|
246 |
stack response could be done by setting a very low default TTL in
|
|
247 |
/proc/sys/net/ipv4/ip_default_ttl (Linux only). Hiding to the spoofed host
|
|
248 |
ftestd reply is done by setting its TTL to a low value equal to the hop delay
|
|
249 |
between ftestd and the firewall. The -s flag for ftest and the -c flag for
|
|
250 |
ftestd must be tuned for this mode, for example use ./ftestd -c 0:3 for
|
|
251 |
temporarily setting default stack ttl to 0 and ftestd reply ttl to 3, the
|
249 | 252 |
ip_default_ttl will be restored when a stop_signal is received.
|
250 | 253 |
|
251 | |
The so called 'connection spoofing mode' can be activated with the 'connect='
|
|
254 |
The so called 'connection spoofing mode' can be activated with the 'connect='
|
252 | 255 |
prefix, let's use this mode:
|
253 | 256 |
|
254 | 257 |
- ftest.conf -
|
|
262 | 265 |
|
263 | 266 |
and again:
|
264 | 267 |
|
265 | |
[root@hostb]# ./ftestd -i eth0 -c 0:3 -v
|
266 | |
|
267 | |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1
|
|
268 |
[root@hostb]# ./ftestd -i eth0 -c 0:3 -v
|
|
269 |
|
|
270 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1
|
268 | 271 |
|
269 | 272 |
Sent Syn Probe => 192.168.0.10:1025 > 10.1.7.1:22 S TCP
|
270 | 273 |
Sleeping for 1 seconds
|
|
277 | 280 |
8 - 192.168.0.10:1025 > 10.1.7.1:23 UR TCP 0
|
278 | 281 |
Stop packet => 192.168.0.10:1025 > 10.1.7.1:80 S TCP
|
279 | 282 |
|
280 | |
note that this time ftest is configured to wait 1 second for ftestd replies.
|
|
283 |
note that this time ftest is configured to wait 1 second for ftestd replies.
|
281 | 284 |
|
282 | 285 |
It's useful to see what traffic we are generating using tcpdump:
|
283 | 286 |
|
|
298 | 301 |
15:16:06.032223 192.168.0.10.1025 > 10.1.7.1.23: S [tcp sum ok] 63848:63856(8) win 65535 (DF) (ttl 200, id 6, len 48)
|
299 | 302 |
15:16:06.034946 10.1.7.1.23 > 192.168.0.10.1025: S [tcp sum ok] 64872:64872(0) ack 63856 win 65535 (DF) [tos 0x10] (ttl 200, id 1, len 40)
|
300 | 303 |
15:16:07.051963 192.168.0.10.1025 > 10.1.7.1.23: . [tcp sum ok] ack 1 win 65535 (DF) (ttl 200, id 7, len 40)
|
301 | |
# the correct RST
|
|
304 |
# the correct RST
|
302 | 305 |
15:16:07.061863 192.168.0.10.1025 > 10.1.7.1.23: R [tcp sum ok] 63856:63871(15) win 65535 urg 0 [RST ftestertcpprobe] (DF) (ttl 200, id 8, len 55)
|
303 | 306 |
15:16:07.072021 192.168.0.10.1025 > 10.1.7.1.23: R [tcp sum ok] 63871:63876(5) win 65535 urg 0 [RST ackme] (DF) (ttl 200, id 9, len 45)
|
304 | 307 |
15:16:07.074616 10.1.7.1.23 > 192.168.0.10.1025: . [tcp sum ok] ack 21 win 65535 (DF) [tos 0x10] (ttl 200, id 2, len 40)
|
305 | 308 |
|
306 | |
# the stop_signal
|
|
309 |
# the stop_signal
|
307 | 310 |
15:16:07.083321 192.168.0.10.1025 > 10.1.7.1.80: S [tcp sum ok] 0:11(11) win 65535 (DF) (ttl 200, id 10, len 51)
|
308 | 311 |
|
309 | 312 |
again here's the logs comparison:
|
|
328 | 331 |
5 - 192.168.0.10:1025 > 10.1.7.1:23 UR TCP 0
|
329 | 332 |
|
330 | 333 |
the first RST has been dropped this confirm that we'are probably dealing with a
|
331 | |
stateful inspection firewall.
|
|
334 |
stateful inspection firewall.
|
332 | 335 |
|
333 | 336 |
If more than one packet is specified with the 'connect=' prefix and the same
|
334 | 337 |
connection parameters (source address/port, destination address/port) the
|
335 | |
-r/-F flags must be used to correctly close (with a RST or a FIN handshake) each
|
336 | |
connections, otherwise, if the firewall is performing sequence numbers tracking,
|
337 | |
connections other than the first will be blocked.
|
|
338 |
-r/-F flags must be used to correctly close (with a RST or a FIN handshake) each
|
|
339 |
connections, otherwise, if the firewall is performing sequence numbers tracking,
|
|
340 |
connections other than the first will be blocked.
|
338 | 341 |
|
339 | 342 |
The IDS testing option permits the injection of arbitrary packets with custom
|
340 | 343 |
payload, using a payload that is supposed to trigger an IDS alert we can test
|
341 | |
IDS visibility on the network and it's ability of sniffing fragmented/segmented
|
342 | |
packets. A number of common IDS evasion techniques are also implemented for
|
343 | |
activation during packets injection. The configuration file for this mode will
|
344 | |
use the standard syntax with the 'ids=' and 'ids-conn=' prefixes, additionally
|
345 | |
ftest can directly use a snort (http://www.snort.org) rule definition file
|
|
344 |
IDS visibility on the network and it's ability of sniffing fragmented/segmented
|
|
345 |
packets. A number of common IDS evasion techniques are also implemented for
|
|
346 |
activation during packets injection. The configuration file for this mode will
|
|
347 |
use the standard syntax with the 'ids=' and 'ids-conn=' prefixes, additionally
|
|
348 |
ftest can directly use a snort (http://www.snort.org) rule definition file
|
346 | 349 |
(check documentation for currently supported keywords). Here's a syntax example:
|
347 | 350 |
|
348 | 351 |
- ftest.conf -
|
|
384 | 387 |
|
385 | 388 |
[root@hostb]# ./ftestd -i eth0 -c 0:3 -v
|
386 | 389 |
|
387 | |
Let's injects the packets as root on Host A:
|
388 | |
|
389 | |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F
|
|
390 |
Let's injects the packets as root on Host A:
|
|
391 |
|
|
392 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F
|
390 | 393 |
|
391 | 394 |
Sent Syn Probe => 192.168.0.10:1025 > 10.1.7.1:80 S TCP
|
392 | 395 |
Sleeping for 1 seconds
|
393 | 396 |
Sent Ack Reply => 192.168.0.10:1025 > 10.1.7.1:80 A TCP
|
394 | 397 |
6 - 192.168.0.10:1025 > 10.1.7.1:80 PA TCP 0 "cmd.exe"
|
395 | 398 |
|
396 | |
Immidiately snort alerts us with the following syslog message (notice that snort
|
|
399 |
Immediately snort alerts us with the following syslog message (notice that snort
|
397 | 400 |
also warn us about ftest signature in the SYN packet):
|
398 | 401 |
|
399 | 402 |
Jun 5 16:25:13 lcars snort[4467]: [111:5:1] spp_stream4: DATA ON SYN detection [Classification: Unknown Traffic] [Priority: 3]: {TCP} 192.168.0.10:1025 -> 10.1.7.1:80
|
|
404 | 407 |
|
405 | 408 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F -g 2
|
406 | 409 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F -e stream -p 3
|
407 | |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F -e stream -p 1b
|
|
410 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F -e stream -p 1b
|
408 | 411 |
[root@hosta]# ./ftest -f ftest.conf -v -d 0.01 -s 1 -F -e desync1
|
409 | 412 |
|
410 | 413 |
and so on...
|
411 | 414 |
|
412 | 415 |
Since snort rocks it identifies correctly the triggering payload each time:
|
413 | |
|
|
416 |
|
414 | 417 |
Jun 5 16:29:32 lcars snort[4467]: [111:5:1] spp_stream4: DATA ON SYN detection {TCP} 192.168.0.10:1025 -> 10.1.7.1:80
|
415 | 418 |
Jun 5 16:29:34 lcars snort[4467]: [1:1002:2] WEB-IIS cmd.exe access [Classification: Web Application Attack] [Priority: 1]: {TCP} 192.168.0.10:1025 -> 10.1.7.1:80
|
416 | 419 |
Jun 5 16:30:16 lcars snort[4467]: [111:5:1] spp_stream4: DATA ON SYN detection {TCP} 192.168.0.10:1025 -> 10.1.7.1:80
|