For years I’ve been using Draytek routers for various reasons. The interface is useable for people who aren’t fulltime doing IP routing and easy to configure. They are also very reliable and well priced unlike some other brands.

Today I needed something special though. At a customer site some fishy things were happening in the network. To monitor it we needed to see the NAT Session Table quite often. So often that it became tedious. Logging into a Draytek is easy; just fill in the login form and bang you are in. Until someone else logs in or your session times out. Both were happening and it was a nuisance. Time to script it.

Googling on Draytek + Script gave a few results which were less than useful. Some of the examples showed the http://user:pass@ format for logging in. A quick test showed that it was not working on this router.

Fair enough, lets try POSTing it directly into the form; Curl can do that. Find the form field names (ah: there they are: sUsername and sSysPass) and go. Inspired by http://ask.metafilter.com/18923/How-do-you-handle-authentication-via-cookie-with-CURL I typed:

curl -c cookie.txt -d “sUserName=admin&sSysPass=secret” http://192.168.1.1/weblogin.htm

Mmm weird, we get a redirect instead of a cookie.

At this moment I got diverted and thought doing it via Telnet (no SSH) would be quicker. Well forget about that too; the command-line uses a funny paginator which is not optional. Getting a complete listing without interaction would be an interesting challenge. Back to the web interface. What is it doing at login?

Pasted_Image_11_03_16_16_16

The view source on the login page is interesting isn’t it? Luckily there is an easy way to revert the obfuscation; just paste it in at http://jsbeautifier.org and you can read the code. Browsing through it one can spot the code for submitting the form data quite easily:

function submitPara() {
 var frmSub = document.frmSub;
 var fwElmIdx = 2;
 frmSub.method = "post";
 frmSub.action = "cgi-bin/wlogin.cgi";
 frmSub
[0].name = "aa"; frmSub[0].value = encode(f.sUserName.value); frmSub[1].name = "ab"; frmSub[1].value = encode(f.sSysPass.value);

The sneaky bastards! Instead of using sUserName and sSysPass as form fields they submit them using a different name! aa for the username and ab for the password! No wonder I got a redirect earlier, I was feeding it the wrong data..

And it even gets better; they have an encode() function which scrambles the data.
Luckily the encode() function is defined just above the submitPara function. When you copy the complete function and paste it into the console of a browser you will have the functional function at your fingertips…

Pasted_Image_11_03_16_16_25

Once you’ve typed encode(“admin”) and encode(“secret”) you know what you need to feed it:

curl -c cookie.txt -d "aa=YWRtaW4&ab=c2VjcmV0" http://192.168.1.1/cgi-bin/wlogin.cgi

And yup, a cookie.txt was created, after some more digging I found the direct url to the IP NAT session list I needed and I can fetch one every time when needed via:

curl -b cookie.txt http://192.168.1.1/doc/ipnatpm.sht

The result is an almost clean text file embedded in some HTML fragments; easy to clean and process.

Great stuff, thanks for making such an interesting login page Draytek 😉

Happy chopping!