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

smf/upf allow uplink forwarding of IPv6 packets with wrong global source IPv6 address outside allocated 64 prefix #1354

Closed
pespin opened this issue Feb 8, 2022 · 9 comments

Comments

@pespin
Copy link
Contributor

pespin commented Feb 8, 2022

This situation is tested by TTCN3 test GGSN_Tests.TC_pdp6_act_deact_gtpu_access, which can be found here:
https://git.osmocom.org/osmo-ttcn3-hacks/tree/ggsn_tests/GGSN_Tests.ttcn#n983

The test triggers the situation using GTPv1C setup from my currently WIP branch, but I suspect the same is happening when the already supported GTPv2C is in use, since this affects the user plane path.

In that test, a subscriber is emulated creating an IPv6 session towards open5gs-smf/upf. It then sends a few stuff over the userplane to test several situations.

This part is showing an issue with open5gs implementation:

		/* Check if we can use valid global src addr, should work */
		var OCT16 saddr_glob := f_ipv6_global(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
		f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_glob, dns1_addr));
		f_wait_icmp6_echo_reply(ctx);

		/* Assert that packets with wrong global src addr are dropped by GGSN */
		var OCT16 saddr_wrong := f_ipv6_mangle(saddr_glob);
		f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_wrong, dns1_addr));
		f_wait_gtpu_fail(ctx);

So it first sends a ping request using the proper IPv6 source IP address, which consists of the first 64 bit prefix obtained through RouterSolicitation and RouterAdvertisement, and whatever value it wishes on the last 64 bits. This one is properly forwarded, and the ping response comes back OK.

Then, it builds up a new IPv6 address containing a 64 bit prefix different than the one which was allocated for the subscriber, and it sends a ping request with it. It can be seen with wireshark that the ping request is actually forwarded outside of the GTP tunnel, and the peer answers back with pong response, and only then the response packet is dropped, since there's no routing for that address.

However, the ping request went through and was forwarded to the Internet side, which seems to be wrong.

The UPF should check the source IP address of uplink IPv6 packets and only allow:

  • link-local address containing the final 64 bit token allocated during session created time.
  • global address containing the initial 64 bit prefix allocated through RouterAdvertisement

Packets coming from the GTP tunnel containing other source IP addresses should be dropped.

@laf0rge
Copy link
Contributor

laf0rge commented Feb 8, 2022

I think this is actually security related, as the current behavior seems to permit source address spoofing. There is no legitimate use case of one subscriber sending packets from an address outside from their allocated prefeix/address.

Does the same also apply to IPv4? Or does the SMF/UPF check the source IP address in the IPv4 case?

@pespin
Copy link
Contributor Author

pespin commented Feb 8, 2022

I bet it's the case for IPv4 too, since I don't recall seeing any check in gtp-path.c in upfd/smfd. It only checks for PFCP rules to forward packets over GTP UPFD->SMFD, and if it doesn't match, it just forwards any packet to the tunnel.
Now the question would be whether this logic needs to be added to UPFD by SMFD through PFCP rules or whether this needs to be checked explicitly by UPFD.

@pespin
Copy link
Contributor Author

pespin commented Feb 8, 2022

I confirm I see the bug in IPv4 too (TTCN3 test TC_pdp46_act_deact_gtpu_access)

@acetcom
Copy link
Member

acetcom commented Feb 13, 2022

Hi @pespin and @laf0rge

I have a few questions, I don't know much about network security, so I hope you understand what I'm saying.

In relation to this problem, would there be any problem if I restrict the source address to IPv6 64bit prefix? Is it ok even if UPF drops packets that use a different 64-bit prefix?

For IPv4, can you figure out that the source address has been faked with? I was wondering how can we block the source address with UPF?

I hope open5gs can also prevent source address spoofing if possible.

Thanks a lot!
Sukchan

@laf0rge
Copy link
Contributor

laf0rge commented Feb 13, 2022

In relation to this problem, would there be any problem if I restrict the source address to IPv6 64bit prefix? Is it ok even if UPF drops packets that use a different 64-bit prefix?

I would consider the "reasonable" approach to be:

  • only permit the assigned IPv4 address for IPv4
  • only permit the assigned link-local / global prefix for IPv6

This should be a sane default configuration. I'm not sure 3GPP makes any requirement about it.

@acetcom
Copy link
Member

acetcom commented Feb 14, 2022

Hi @laf0rge and @pespin

I've added code to check for source address spoofing.

Let me know if there's anything more I need to do.

Thank you so much for suggesting it.
Sukchan

@pespin
Copy link
Contributor Author

pespin commented Feb 14, 2022

Hi @acetcom I run the TTCN3 tests again with the patch applied (current main + my gtpv1c patches to be able to run GGSN_Tests testsuite) and the situation is now indeed better.

There's still one scenario where osmo-upfd is forwarding packets with wrong address:
In an IPv6 (or IPv4v6) APN, UE creates a PDP Context requesting an IPv6 address and in the response it gets 64 bit token, lets say "whatever::2" . So then the UE is expected to do a Router Solicitation using "fe80::2" as source address (link-local address + 64 bit suffix assigned in PDP Context Response or Create Session Response).
However, I see in the tests that if the UE uses whatever other link local address than the one it was assigned (for instance ""fe80::1:2:3:4" instead of "fe80::2"), the open5gs-upfd is still forwarding the packet to the open5gs-smfd, and the open5gs-smfd is answering with a Routing Advertisement and the open5gs-upfd then forwards it back to the UE. The correct behavior would be to drop the Router Solicitation at the UPF and not forward it to the SMF in first place.

This is happening because your patch only validates source IP address on the path sending the packet through the tun device to towards the Internet, but not the path fowarding packets through GTP to the SMF.

@acetcom
Copy link
Member

acetcom commented Feb 14, 2022

Hi @pespin

Oops! That's my mistake. I've updated it.

Thanks a lot!
Sukchan

@pespin
Copy link
Contributor Author

pespin commented Feb 14, 2022

Hi @acetcom , all related tests seem to be passing now, thanks for looking at it!
Closing the ticket(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants