Я тут задался вопросом, надо ли пересобирать пакеты на маршрутизаторе, который фильтрует трафик ACL. Другими словами, использовать или не использовать ip virtual-reassembly.
RFC-1858 описывает различные атаки с использованием ip fragmentation. Нас интересует случай IP fragment overlap при котором последующий фрагмент перепишет L4 информацию предыдущего при сборке пакета на destination хосте. Если, например, удалось бы в первом фрагменте объявить, что это SYN пакет на порт tcp/80, а во втором переписать этот порт на tcp/3306, установив Fragment Offset в 0, то мы получили бы отличный способ ходить на закрытые ACL порты.
Я нашел вот этот документ, который рассказывает, что это невозможно сделать. Не поверив написанному, я решил проверить сам.
Взял ненужный 2600 маршрутизатор и сделал на нем
interface Ethernet0/0 ip address 10.50.200.200 255.255.0.0 secondary ip address 10.1.200.200 255.255.0.0 ip access-group test in ip access-list extended test permit tcp any host 10.50.200.100 eq www deny ip any any |
Использовал hping для генерации пакетов и tethereal, чтобы смотреть что проходит, а что нет.
# hping3 -S 10.50.200.100 -p 80 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes len=46 ip=10.50.200.100 ttl=64 DF id=0 sport=80 flags=SA seq=0 win=5840 rtt=54.7 ms len=46 ip=10.50.200.100 ttl=64 DF id=0 sport=80 flags=SA seq=1 win=5840 rtt=1.8 ms len=46 ip=10.50.200.100 ttl=64 DF id=0 sport=80 flags=SA seq=2 win=5840 rtt=1.9 ms --- 10.50.200.100 hping statistic --- 3 packets tramitted, 3 packets received, 0% packet loss round-trip min/avg/max = 1.8/19.5/54.7 ms |
Проходит. Ничего удивительного, мы разрешили порт 80 в ACL
А на порт 81
# hping3 -S 10.50.200.100 -p 81 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN --- 10.50.200.100 hping statistic --- 4 packets tramitted, 3 packets received, 25% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
не проходит, маршрутизатор отвечает ICMP . Опять-таки, ничего удивительного.
Поставили флаг More Fragments, Fragment Offset = 0.
# hping3 -x -S 10.50.200.100 -p 80 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes --- 10.50.200.100 hping statistic --- 6 packets tramitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
Ответов не видно, потому-что на destination они не собираются из-за отсутствия last fragment.
Но если посмотреть в tethereal
0.000000 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=0) 1.000342 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=0) 2.000619 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=0) 3.004922 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=0) |
То видно, что пакеты доходят до хоста.
Флаг More Fragments, Fragment Offset = 0, порт 81
# hping3 -x -S 10.50.200.100 -p 81 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN ICMP Packet filtered from ip=10.1.200.200 name=UNKNOWN --- 10.50.200.100 hping statistic --- 4 packets tramitted, 3 packets received, 25% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
На порт 81 уже не проходит.
Т.е. при Fragment Offset = 0 срабатывают ACL.
Интересно увеличить Fragment Offset и посмотреть, что будет. Тут надо обратить внимание, что в стандарте протокола IPv4 написано
Fragment Offset (bits 51 — 63)
The fragment offset field, measured in units of eight-byte blocks,
is 13 bits long and specifies the offset of a particular fragment
relative to the beginning of the original unfragmented IP datagram.
The first fragment has an offset of zero. This allows a maximum
offset of (213 – 1) × 8 = 65,528 which would exceed the maximum IP
packet length of 65,535 with the header length included.
Т.е. значение 0x01 будет соответствовать off=8, а значение 0x02 — off=16. Т.е. все значения offset можно указать только кратные 8ми.
Попробуем с Fragment Offset = 8.
# hping3 -x -g 8 -S 10.50.200.100 -p 80 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes --- 10.50.200.100 hping statistic --- 8 packets tramitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
Ответов нет, tethereal тоже ничего не показывает.
Порт 81
# hping3 -x -g 8 -S 10.50.200.100 -p 81 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes --- 10.50.200.100 hping statistic --- 5 packets tramitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
Результат аналогичный.
Т.е. маршрутизатор просто выкидывает пакеты с Fragment Offset = 8.
А вот уже с Fragment Offset = 16 и выше отлично пропускает, причем на любой порт.
# hping3 -x -g 16 -S 10.50.200.100 -p 81 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes --- 10.50.200.100 hping statistic --- 6 packets tramitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms |
# hping3 -x -g 16 -S 10.50.200.100 -p 80 HPING 10.50.200.100 (ath0 10.50.200.100): S set, 40 headers + 0 data bytes --- 10.50.200.100 hping statistic --- 4 packets tramitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms [root@dyeldandi ~]# |
0.000000 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 1.000353 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 2.000815 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 4.305195 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 5.305509 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 6.305812 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) 7.306096 10.1.3.78 -> 10.50.200.100 IP Fragmented IP protocol (proto=TCP 0x06, off=16) |
Но Fragment Offset = 16 — это уже далеко за тем местом, где указываются tcp порты, а значит, ACL может со спокойной совестью пропускать, проверять там уже нечего.
Как резюме: Для проверки ACL собирать пакеты на CISCO маршрутизаторе не надо.
А когда надо? Только если используется Cisco IOS Firewall, как описано вот в этом документе.
Спасибо за внимание.