3 ms·
Author here. The ruleset in the blog post is correct. The rationale of the example ruleset is the following: we want to block TCP, UDP and ICMPv6 traffic from t
by enrico204 3y ago
Author here. The ruleset in the blog post is correct. The rationale of the example ruleset is the following: we want to block TCP, UDP and ICMPv6 traffic from the attacker, while allowing other protocols.
Note that IPv6 packets are matched against all rules, while IPv6 fragments are matched against rules that contain network-level information only (as fragments don't have upper layer headers, except for the first fragment).
If the scrubbing is enabled, then `pf` is supposed to reassemble all fragments, so that there is no more fragmented traffic (= all rules are applied to all IPv6 packets). Normally, it works.
In this case, we tricked the firewall by sending an "atomic fragment" that is composed by multiple fragmented headers (this is forbidden by various RFCs). These headers trigger the reassembly mechanism of `pf`, but the packet is "re-assembled" only once: when it enters the rule matcher (after the reassembly), it is still considered a fragment, and all rules with transport-level (and higher) protocol information are skipped.
So, the "block-pass" pair at the end is used to exploit this behavior (in other words, we can decide which rule we match by playing with IPv6 fragment header).
PS: an "atomic fragment" is a IPv6 packet that is fragmented using only one fragment. Surprisingly, it is supported by RFCs.
- mmsc 3y agoThank you for the response! I read "allow the rest" to mean "the rest of everything", rather than "the rest of the protocols". Based on your explanation, does that mean if the restriction was block in quick on $ATTACKER_IF inet6 label "Block all connections from the attacker" it would not succumb to this vulnerability? Great job with this, btw.