Hacking a Query String

Allan Kelly : Hacking a Query String

Automating Web Form submission with some small tools

At the ACCU 2006 conference in Oxford, we were faced with a free Wireless LAN login which was limited to 20 users. This is fine after about 20 minutes into a session, when laptops logged in during the breaks have timed-out on the LAN and so slots are available. During breaks though, it's common to see people forlornly hitting 'refresh' on their browsers, hoping to grab a free slot. After a bit of this, I scripted it. This is a quick description of how I did that.

Starting with the obvious stuff, turning on my Apple iBook got me connected to the 'tmobile' wireless LAN. However, there was no internet access available until I opened a browser and typed in the ACCU username and password, which were supplied on little pieces of paper from the registration desk: username G-Randolph.group@t-mobile.co.uk, password ACCU. After that, my browser was able to access the internet as well as my mail programs. So, I guess the wireless infrastructure is recording my MAC address (not Apple Mac! MAC here is the unique ID of my wireless card. All ethernet devices have a MAC address. Mine's 00:14:51:87:41:9f) and keeping a record of the last activity. If I login, then do nothing with the network for 15 minutes, it times me out. Fair enough.

So, there are 2 options. First, write a little pinger to keep my network connection up. This is very simple:

$ while [ 1 ] ; do wget -q www.google.com ; sleep 30 ; done

But that's bad citizenship. You're basically hogging the connection which someone else will need, so don't do that. Very naughty.

Instead, we'll write a wee thing that tries to get a connection - the equivalent of automating the 'refresh' button press on the LAN login page. That page says "Login has been rejected. There are already too many users using this account." The address of that page is https://hotspot.t-mobile.net/wlan/start.do

So, the first thing to do is to look at the page. We have to fill in the username, the password, and click 2 checkboxes to say we agree to the 'Terms & Conditions' and the 'Privacy policy'. (Well, I read those thoroughly, as you can imagine). Now, view source. Search for the word 'Username', and we find the relevant section of the HTML. The input element lines are copied below.

<input type="text" name="username" value="G-Randolph.group@t-mobile.co.uk" maxlength="72">
<input type="password" name="password" value="ACCU" maxlength="72">
<input type="checkbox" name="strAGB" value="AGB" checked="checked">
<input type="checkbox" name="strHinweis" value="Zahlungsbedingungen" checked="checked">
		  

From this, it's straight-forward to construct a query string - the page URL plus these parameters. If you don't know query strings, there's basically 3 syntax rules: the query string comes after the page URL, starts with a ?, each name-value pair is joined with =, and each name-value pair is seperated with a &. In the <input> elements above, the important attributes are name and value - the other stuff's just GUI fluff (with all due respect to GUI writers).

So, we get this query string (all on one line).

https://hotspot.t-mobile.net/wlan/index.do?username=G-Randolph.group@t-mobile.co.uk
&password=ACCU&strAGB=AGB&strHinweis=Zahlungsbedingungen
		  

Now, we need to make this request to the server. Well, it's https so we need a SSL-enabled client. Your browser is one, so test with that: paste the string above into the address bar, and presto! It's as if you had submitted the 'proper' form. It's important to realise that you have NOT submitted a form, which is an HTTP POST operation - you have submitted an HTTP GET request, with all the required information in the URL string.

The point here is to let the computer do the grunt-work, so we've not got much advantage yet. We need to use a script to do this. I use perl for all this sort of stuff - I've been at it for years, and I'm very comfortable with it. Python, Ruby and innumerable other scripting languages no doubt do the job. Here's a perl solution wrapped in a shell script.

We're going to use 2 perl libraries - LWP for basic web stuff, and Crypt::SSLeay for the SSL encryption stuff. perl generally comes with the cpan program for accessing and installing CPAN modules. On a unix system such as the Mac this is typically used with sudo cpan install LWP and sudo cpan install Crypt::SSLeay.

OK, now we simply chuck the query string at the server with the GET program, which LWP has installed in /usr/bin/GET. (Remember you need to enclose the URL in quotes to avoid the shell interpreting the & as background operators.) All of this on one line:

GET 'https://hotspot.t-mobile.net/wlan/index.do?
username=G-Randolph.group@t-mobile.co.uk
&password=ACCU
&strAGB=AGB
&strHinweis=Zahlungsbedingungen'
		  

This works. If there are too many users on the network (like just now, 3 minutes before the keynote starts), the response HTML contains the line

<p class="error">Login has been rejected. There are already too many users using this account.</p>
                  

If we get on, then the success page contains the string 'You are now online with high-speed access'.

So, we can now build a little script which looks for either of these strings and re-tries if not successful. This is as old as the hills, there's more than one way to do it, and I solve it with:

#!  /bin/sh
SLEEP=20
URL="https://hotspot.t-mobile.net/wlan/index.do"
URL="${URL}?username=G-Randolph.group@t-mobile.co.uk"
URL="${URL}&password=ACCU"
URL="${URL}&strAGB=AGB"
URL="${URL}&strHinweis=Zahlungsbedingungen"
SUCCESS='You.are.now.online.with.high-speed.access'
GET="/usr/bin/GET $URL"
while [ "0$GETOUT" == "0" ] ; do
    GETOUT=`$GET | grep $SUCCESS`
    if [ "0$GETOUT" == "0" ] ; then
        echo "Rejected at $(date), retrying in $SLEEP seconds..."
        sleep $SLEEP
    fi
done
echo "Connected at $(date)"

                  

Cookies

The t-mobile access application does set a ccookie on your browser, but I didn't find it was required in my script. Here it is anyway. If this had been required, we would have had to ensure the Cookie was passed correctly so I'm pretty glad it's not used!
hotspot.t-mobile.net /wlan JSESSIONID=08610FAB4B39BD940927A903CB556729.TMOWLanPortalNode116
                  
   
Last Updated
Fri Oct 17 23:53:36 2008