$Id: captive-portals,v 1.2 2021/11/23 02:53:38 nanons Exp $

Using captive portals
=====================

Public wireless access points are sometimes gated behind captive
portals, i.e. web interfaces which request manual approval of terms of
service or login credentials before Internet access is allowed.

Captive portals are mainly implemented through 3 different types of
redirects: HTTP, DNS, or ICMP.  In all cases, using a web browser to
connect to any clearnet HTTP website (not HTTPS!) is required to access
the captive portal page.

DNS redirects
=============

The default DHCP and SLAAC nameserver autoconfiguration should pass
captive portals based on DNS redirection.  Using unwind(8) in addition
will circumvent autoconfigured nameservers that filter queries.

To enable unwind(8):

	# rcctl enable unwind
	# rcctl start unwind

If you set up a custom DNS in resolv.conf(5) already and don't use
unwind(8), check the unwind.conf(5) man page for instructions on adding
forwarders.

ICMP redirects
==============

To enable ICMPv4 redirection:

	# sysctl net.inet.icmp.rediraccept=1
	# echo net.inet.icmp.rediraccept=1 >> /etc/sysctl.conf

ICMPv6 redirection is automatically enabled if "inet6 autoconf" is used
in the respective network interface's hostname.if(5) file.

ICMP redirects can be whitelisted with the following pf.conf(5) rules:

	pass in on egress inet proto icmp from (egress:network) icmp-type redir
	pass in on egress inet6 proto icmp6 from (egress:network) icmp6-type redir

MAC spoofing
============

In most cases a captive portal can be completely bypassed without
having to access its web interface by hijacking the MAC address of
another user who authenticated to the captive portal beforehand.
Keep in mind that this will deny network access to the target user.

"athn0" will be used as the example network interface here.
To list wireless network interfaces:

	$ ifconfig wlan | egrep "^[a-z0-9]+:"

Bring up the interface and scan for nearby access points:

	# ifconfig athn0 up
	# ifconfig athn0 scan

In the ifconfig(8) output, wireless access points are identified with
a name preceded by "nwid". If the "nwid" line is missing "wpa" or "wep"
options, then no password is required to connect the network.

Remove any previously configured IP addresses and then connect:

	# ifconfig athn0 -inet -inet6
	# ifconfig athn0 nwid "coffee_shop"

Wait a minute to receive traffic from other connected users, then list
their MAC addresses (under "Ethernet Address" and "Linklayer Address"):

	$ arp -an
	$ ndp -an

Choose a MAC address from the list and set it as the interface address:

	# ifconfig athn0 lladdr c0:ff:ee:12:34:56

Another MAC address may need to be chosen if the original target hasn't
authenticated yet.

Finally, enable DHCP and SLAAC to acquire the target's IP address:

	# ifconfig athn0 inet autoconf
	# ifconfig athn0 inet6 autoconf

If the target reconnects to the network, the MAC address will be
hijacked back and you will be denied access until you reconnect:

	# ifconfig athn0 down
	# ifconfig athn0 up

