Networking Setup
In order for this attack to work, we will need to do a bit of configuration.
We will first assign an IP address to our wlan0 interface.
The IP we use doesn’t matter
because once the user’s system detects that it can’t reach the Internet,
it will automatically open the IP address of the router in the browser,
which is also the host of the captive portal.
As clients are connecting to us
and in order for them to reach our captive portal,
they need an IP configuration.
Thankfully, the first thing the user will do is request a DHCP lease.
We will provide it using dnsmasq,
a small DNS and DHCP server we can install with apt.
Let’s create our DHCP configuration file.
The first part of the configuration file
includes standard settings like the listening IP address,
and the range of IP addresses to be assigned
along with the DHCP lease time.
We also need to conduct DNS spoofing
so that the response for most DNS requests will point back to us
with the exception of rare cases.
To do this, we will append the necessary lines to the configuration file.
Although we are only spoofing a few generic top-level domains,
this should cover most of the website domains
a connected user will attempt to access.
To help Windows detect the captive portal,
we have to resolve this domain,
to a specific IP address that Windows knows the result of.
Now that the configuration file is complete,
let’s start dnsmasq with the configuration file option
followed by the path of our configuration file.
After startup,
dnsmasq will create a file containing its process ID.
This will let us find and kill the process when we are done.
We can inspect syslog to confirm it started successfully.
Using netstat,
we can confirm it is listening on port 53 for DNS and on 67 for DHCP.
Although port 67 is open,
it is listening on all IP addresses,
even though we specifically configured it to listen on a specific IP
with the listen-address parameter.
This appears to be a bug.
DHCP is a broadcast protocol
and clients send broadcast frames
to get any potential listening DHCP server to give them a lease.
For that reason, dnsmasq isn’t listening on a specific IP address
but a broadcast address.
Although it is listening on all adresseses
it will only listen to broadcast traffic on the interface we specified.
Netstat doesn’t display that information.
The same goes for DNS on port 53.
Sometimes clients ignore DNS settings provided in the DHCP lease,
so we will use an nftables rule to force redirect
all DNS requests back to our server.
To do this, we first need to install nftables with apt.
Next, we’ll add the rules we need.
This is the rule that will redirect DNS requests to our server.
In Apache’s site configuration,
we need to add mod_rewrite and mod_alias rules
so that the captive portal is set properly.
We’ll add our rules before the VirtualHost closing tag.
These additions will require two modules to be enabled.
For the first four and the last two instructions,
we need the redirect module.
For the “RedirectMatch” additions in-between,
we need the alias module.
Let’s enable the rewrite and alias modules using a2enmod.
Next, we'll restart Apache using systemcontrol,
and then check to ensure the portal is correctly displayed locally
by pointing a browser to localhost.
Excellent.
Everything appears to be operating correctly.
Special Case for Chrome
Chrome doesn’t automatically check for captive portals on startup like Firefox.
Typing a URL will trigger the captive port
but with this configuration, a search will fail.
This may be because Chrome encodes the search
and automatically prepends the search URL,
which is HTTPS.
With just HTTP in our Apache configuration,
we will fail to connect to the website because the port isn’t listening.
This can be remedied by making a HTTPS section in Apache.
Note that making this would break the portal functionality
in Firefox because of the self-signed certificate.
Because of this, we solely recommended using this approach
in an environment where only Chrome is used.
In this Chrome-specific configuration,
the port needs to be changed from 80 to 443,
the rewrite and redirect URLs need to be updated from http to https,
and finally, an SSL certificate needs to be added.
The final step would be to enable the ssl module with a2enmod,
before restarting Apache.