Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropping packets with IPv4/IPv6 options #111

Closed
m00nbsd opened this issue Aug 6, 2020 · 2 comments
Closed

Dropping packets with IPv4/IPv6 options #111

m00nbsd opened this issue Aug 6, 2020 · 2 comments

Comments

@m00nbsd
Copy link
Contributor

m00nbsd commented Aug 6, 2020

Description

It would be nice to add an option in NPF allowing to drop packets with IPv4/IPv6 options. This is an important yet missing feature, and IPv4/IPv6 options are a significant problem in network security.

The point is that IPv4/IPv6 options are big enablers when it comes to exploitation: they are hard to parse (that is the parser can easily be buggy), and they allow to push the actual payload farther in the mbuf, in a way that makes it a lot easier to exploit buffer overflows.

Two years ago I wrote a patch for that using BPF. Unfortunately I realized it wasn't correct, because when a connection already exists NPF does a pass-through of the packet without applying BPF rules, meaning that the subsequent TCP packets in the stream could have IPv4/IPv6 options and NPF would accept them.

Patch Suggestion

Probably the correct way to proceed is using npf-params, with ip4.drop_options and ip6.drop_options, along the lines of:

 		/* Retrieve the complete header. */
 		if ((u_int)(ip->ip_hl << 2) < sizeof(struct ip)) {
 			return NPC_FMTERR;
 		}
+		if (npf->ip4_drop_options && (ip->ip_hl != 5)) {
+			return NPC_FMTERR;
+		}
 		ip = nbuf_ensure_contig(nbuf, (u_int)(ip->ip_hl << 2));
 		if (ip == NULL) {
 			return NPC_FMTERR;
 		}
 			case IPPROTO_HOPOPTS:
 			case IPPROTO_DSTOPTS:
 			case IPPROTO_ROUTING:
+				if (npf->ip6_drop_options) {
+					return NPC_FMTERR;
+				}
 				hlen = (ip6e->ip6e_len + 1) << 3;
 				break;

By default I think that IPv4/IPv6 options should be dropped, like PF does.

@rmind
Copy link
Owner

rmind commented Aug 6, 2020

@m00nbsd:

  • Adding ip4.drop_options and ip6.drop_options parameters sounds good. The user should also be able to do rule-based filtering of options, but that is a separate patch.
  • I'd swap the checks in the first patch fragment, i.e.: if (ip->ip_hl != 5 && npf->ip4_drop_options) ...
  • Not sure about dropping by default; there are still couple useful options. I would say let's introduce the parameters with defaults being "off" and then initiate a discussion on NetBSD tech-net. Based on the feedback, we can then decide to flip the defaults from "off" to "on".

Would you like to make a pull request (PR)?

@rmind
Copy link
Owner

rmind commented Aug 7, 2020

Fixed by #112

@rmind rmind closed this as completed Aug 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants