Testing a router or firewall


Introduction

The life of a router is punctuated by several important steps : In each case, network tests are needed to validate administrator's choices. For example : The aim of this article is to present a method for testing routers and firewalls. In this document, we only use the term "router", but the described method can also be applied to stateful inspection firewalls, packet filtering firewalls, proxy firewalls, etc.

Basic idea

The basic idea about tests is to send a packet on one side of the router.
Then, on the other side :

Method

We do not present a generic high level method. Indeed, every network administrator has its own way to setup a device or to solve a problem.
We emphasis on the low level method by presenting key points, which can be linked together in order to construct the high level method of every person. The key points are : Using only these 3 key points, an administrator can test a network.

Tool used

In order to illustrate examples, the free network testing tool netwox is used. Netwox is available at :
http://ntwox.sourceforge.net/

Other tools or network libraries (tcpdump, snoop, ipsend, netcat, telnet, libnet, libpcap, etc.) can also be used, but netwox incorporates all we need in one program.

How to send a packet ?

Well, it depends on protocols supported by our network. For example, in this paper, we focus on IP over Ethernet, and ICMP/UDP/TCP.

Which kind of packets to send ?

The kind of sent packets depends on several factors :

What's the difference between IP level and Ethernet level ?

When a packet is sent at IP level, the local IP stack : So, the user doesn't have to bother with Ethernet. However, this method doesn't allow to do tricky stuff with Ethernet, and sometimes with IP itself because the sender IP stack rejects the packet.
When a packet is sent at Ethernet level, it is directly sent on the network without going through the IP stack. It is more complicated because the user has to set Ethernet addresses, but can allow to do tricky things. To obtain the Ethernet address of a computer on the LAN, use "netwox 3" :
# netwox 3 192.168.10.2
  IP address:  192.168.10.2
  Hostname:    computer2
  Hostnames:   computer2,computer2.example.com
  Eth address: 00:40:95:46:11:23
Don't forget that the destination Ethernet address has to be set to :

How to send an ICMP packet at IP level ?

We can use "netwox 41" :
# netwox 41 --ip4-src "192.168.10.1" --ip4-dst "192.168.11.3" --icmp-type "8" \
  --icmp-code "0" --icmp-data "12345678 'my data'"
IP______________________________________________________________________.
|version |  ihl   |       tos       |              totlen               |
|___4____|___5____|_____0x00=0______|_____________0x0023=35_____________|
|                id                 |  DfMf          offsetfrag         |
|___________0x3DB4=15796____________|0_0_0____________0x0000=0__________|
|       ttl       |    protocol     |             checksum              |
|_____0x00=0______|_____0x01=1______|______________0xE6D1_______________|
|                                source                                 |
|_____________________________192.168.10.1______________________________|
|                              destination                              |
|_____________________________192.168.11.3______________________________|
ICMP4_echo request______________________________________________________.
|      type       |      code       |             checksum              |
|_____0x08=8______|_____0x00=0______|___________0x3F01=16129____________|
12 34 56 78  6d 79 20 64  61 74 61                     # .4Vxmy data
To obtain help about parameters, just enter "netwox 41 --help"

How to send an ICMP packet at Ethernet level ?

We can use "netwox 37" :
# netwox 37 --device Eth0 --eth-src 00:40:33:E0:2C:42 --eth-dst 00:40:95:46:41:BC \
  --ip4-src "192.168.10.1" --ip4-dst "192.168.11.3" --icmp-type "8" --icmp-code "0" \
  --icmp-data "12345678 'my data'"
Ethernet________________________________________________________________.
| 00:40:33:E0:2C:42->00:40:95:46:41:BC type:0x0800                      |
|_______________________________________________________________________|
IP______________________________________________________________________.
|version |  ihl   |       tos       |              totlen               |
|___4____|___5____|_____0x00=0______|_____________0x0023=35_____________|
|                id                 |  DfMf          offsetfrag         |
|___________0xCCE7=52455____________|0_0_0____________0x0000=0__________|
|       ttl       |    protocol     |             checksum              |
|_____0x00=0______|_____0x01=1______|______________0x579E_______________|
|                                source                                 |
|_____________________________192.168.10.1______________________________|
|                              destination                              |
|_____________________________192.168.11.3______________________________|
ICMP4_echo request______________________________________________________.
|      type       |      code       |             checksum              |
|_____0x08=8______|_____0x00=0______|___________0x3F01=16129____________|
12 34 56 78  6d 79 20 64  61 74 61                     # .4Vxmy data
Following command is equivalent, but is less easy to understand.
# netwox 37 -d Eth0 -a 00:40:33:E0:2C:42 -b 00:40:95:46:41:BC -l 192.168.10.1 \
  -m 192.168.11.3 -o 8 -p 0 -q "12345678 'my data'"

How to send an UDP packet at Ethernet level ?

We can use "netwox 35" :
# netwox 35 -d "Eth0" -a "1:2:3:4:5:6" -b "7:8:9:a:b:c" -l "1.2.3.4" \
  -m "5.6.7.8" -o "1234" -p "53"
Ethernet________________________________________________________________.
| 01:02:03:04:05:06->07:08:09:0A:0B:0C type:0x0800                      |
|_______________________________________________________________________|
IP______________________________________________________________________.
|version |  ihl   |       tos       |              totlen               |
|___4____|___5____|_____0x00=0______|_____________0x001C=28_____________|
|                id                 |  DfMf          offsetfrag         |
|___________0x95D5=38357____________|0_0_0____________0x0000=0__________|
|       ttl       |    protocol     |             checksum              |
|_____0x00=0______|_____0x11=17_____|______________0x14E9_______________|
|                                source                                 |
|________________________________1.2.3.4________________________________|
|                              destination                              |
|________________________________5.6.7.8________________________________|
UDP_____________________________________________________________________.
|            source port            |         destination port          |
|____________0x04D2=1234____________|_____________0x0035=53_____________|
|              length               |             checksum              |
|_____________0x0008=8______________|___________0xEAC3=60099____________|
Now you are familiar with netwox, do not hesitate to use netwag :
- run netwag
- click on Search notebook
- at the right, there is "[*] show all [ ] search [.....]"
- in [.....], enter "udp"
- the list of tool will shrink
- select line "35 : Spoof EthernetIp4Udp"
- click on Run notebook
- click on Form sub-notebook
- enter values
- press on Generate (or "Run it")
- press on Run (or "Run it")

How to send a TCP packet at Ethernet level ?

We can use "netwox 36" :
# netwox 36 -d "Eth0" -a "1:2:3:4:5:6" -b "7:8:9:a:b:c" -l "1.2.3.4" \
  -m "5.6.7.8" -p "80" -C
Ethernet________________________________________________________________.
| 01:02:03:04:05:06->07:08:09:0A:0B:0C type:0x0800                      |
|_______________________________________________________________________|
IP______________________________________________________________________.
|version |  ihl   |       tos       |              totlen               |
|___4____|___5____|_____0x00=0______|_____________0x0028=40_____________|
|                id                 |  DfMf          offsetfrag         |
|___________0xAB70=43888____________|0_0_0____________0x0000=0__________|
|       ttl       |    protocol     |             checksum              |
|_____0x00=0______|_____0x06=6______|______________0xFF4C_______________|
|                                source                                 |
|________________________________1.2.3.4________________________________|
|                              destination                              |
|________________________________5.6.7.8________________________________|
TCP_____________________________________________________________________.
|            source port            |         destination port          |
|____________0x04D2=1234____________|_____________0x0050=80_____________|
|                                seqnum                                 |
|_________________________0x512355F1=1361270257_________________________|
|                                acknum                                 |
|_____________________________0x00000000=0______________________________|
|  doff  |reserved CwEcUrAc PsRsSyFi|              window               |
|___5____|0_0_0_0__0_0_0_0__0_0_1_0_|_____________0x0000=0______________|
|             checksum              |              urgptr               |
|___________0xF398=62360____________|_____________0x0000=0______________|

How to verify the arrival of a packet ?

To check if a packet arrives on a network, we have to use a sniffer. We might however encounter problems :
To display packets "netwox 7" can be used :
# netwox 7
 ETH_____________________________________________________________________.
 | 00:40:33:e0:c2:24 vers 00:40:95:46:14:cb         type : 0x0800        |
 |_______________________________________________________________________|
 IP______________________________________________________________________.
 |version |  ihl   |       tos       |              totlen               |
 |___ 4___|___ 5___|_______  0_______|____________0054h=   84____________|
 |                id                 |xxDfMf         fragoffset          |
 |____________0052h=   82____________|0_0_0__________0000h=    0_________|
 |       ttl       |    protocol     |          header checksum          |
 |_____40h= 64_____|_____01h=  1_____|_______________E502h_______________|
 |                                source                                 |
 |______________________________192.168.10.1_____________________________|
 |                              destination                              |
 |______________________________192.168.10.3_____________________________|
 ICMP____________________________________________________________________.
 |      type       |      code       |             checksum              |
 |_____08h=  8_____|_____00h=  0_____|____________AA90h=43664____________|
 A1 02 00 00  7B D7 E1 3A  61 57 03 00  08 09 0A 0B     # ....{..:aW......
 0C 0D 0E 0F  10 11 12 13  14 15 16 17  18 19 1A 1B     # ................
 1C 1D 1E 1F  20 21 22 23  24 25 26 27  28 29 2A 2B     # ...~ !"#$%&'()*+
 2C 2D 2E 2F  30 31 32 33  34 35 36 37                  # ,-./01234567

Various displaying methods can be selected (use netwag to learn which values can be put in parameter --hdrencode or --dataencode).

How to simulate a testing computer ?

When computer A wants to reach computer B :
So, when we simulate a computer, we have to answer to ARP requests, in order to inform other computers. For example, to simulate the presence of 192.168.10.2, and saying its Ethernet address is 12:34:56:78:90:ab, we can use :
# netwox 73 -i 192.168.10.2 -e 12:34:56:78:90:ab

First example

In this example, we want to verify that : Both 192.168.10.1 and 192.168.11.3 are "real" computers (we do not have to simulate them)

So, the testing procedure is :

Second example

In this example, we want to verify that : The computer 192.168.10.1 is "real" and 192.168.11.4 is simulated with Ethernet address 12:34:12:34:12:34. So, the testing procedure is :

Third example

In this example, we want to verify that : The computer 192.168.10.2 is simulated with Ethernet address 12:34:12:34:12:34. The computer 192.168.11.3 is real. So, the testing procedure is :

Other examples

Several other examples could be written using the same methods. This is left as an exercise for the reader.

Conclusion

Validating the configuration of a router is a long task, mainly if we want to verify the security of the device. The knowledge of key points, and the usage of generic tools can however simplify administrators' job. This paper only described the tests which can be done. Using these tests and they knowledge, administrators can elaborate their own method to configure or secure a router or a firewall.