Skip to main content

Command Palette

Search for a command to run...

WIFI Captive Portal without Browser

With IWCTL and CURL only.

Updated
2 min read
WIFI Captive Portal without Browser
J

I am a developer in Seattle with interests in Security (cyber and IRL), machine learning, and distributed systems.

I’ve been trying to install Omarchy on a separate partition on a single SSD.

First obstacle was to connect to free WIFI, but hit a captive portal. In the Arch install prompt, I only have access zsh, iwctl, and curl. No browser. A curl to the gateway 192.168.1.1 will try to redirect to captive portal, so allow it to redirect:

curl 192.168.1.1

<html>
<body>You are being <a href='https://sub.domain-auth.com/splash/9wXhbaKc.7.938/?mac=DD%3AEA%3ADB%3AEE%3AFF&real_ip=172.26.XXX.XXX&client_ip=10.XXX.XXX.XXX&client_mac=DD:EA:DB:EE:FF:CD&vap=7&a=8b7471f4ae0bf59f5f0a425068c05d96f4801b9e&b=4049582&auth_version=5&key=963a1acedda28327500efe0537b47243b51b5191&acl_ver=P5082015V2&continue_url=http%3A%2F%2F192.168.1.1%2F'>redirected</a>.</body></html>

So allow for redirection with cURL with -L and store the response cookies with —cookie-jar:

curl -L 192.168.1.1 --cookie-jar cookies

var _request = new XMLHttpRequest();
var url = 'https://sub.domain-auth.com/splash/9wXhbaKc.7.938/grant?continue_url=CONTINUE_URL_PLACEHOLDER';
_request.open('HEAD', window.location, true);
_request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
_request.onreadystatechange = function() {
  if (_request.readyState === 4) {
    var continue_url = _request.getResponseHeader('Continue-Url');
    window.location.href = url.replace('CONTINUE_URL_PLACEHOLDER', continue_url);
  };
};
_request.send(null);
})(this); return false;">Accept &amp; Connect</a>

With --vv option, I can see the cookies stored for sub.domain-auth.com. The JavaScript just makes a HEAD call and replaces the CONTINUE_URL_PLACEHOLDER header with response header value from continue_url which is also just http://www.domain.com. Use the stored cookies with —cookie or -b.

curl -I -vv "https://sub.domain-auth.com/splash/9wXhbaKc.7.938/grant?continue_url=CONTINUE_URL_PLACEHOLDER" "X-Requested-With: XMLHttpRequest" --cookie cookies

We get a 200 back, but need to finish auth with a GET o simulate the redirect (window.location.href).

curl -L -vv "https://sub.domain-auth.com/splash/9wXhbaKc.7.938/grant?continue_url=http://www.domain.com" --cookie cookies

We get the redirect back and can ping google.com without packets filtered.

Similar approach could be used for other portals that would require form postback.

References