Category Archives: Cryptography

Using WhatsMyIP.org Without JavaScript — Deobfusticating Code

29 Jul 2011

I’ll start this post off by saying if you are someone who polls a site constantly for your IP use: http://whatismyip.akamai.com and not http://www.whatsmyip.org not only is the on the worlds largest CDN but it is just the IP nothing more.

I’ve been annoyed for a long time, I regular use whatsmyip.org to check my IP for various reasons, I have a bit of trust in the site, but I do not trust the transport (HTTP) so I don’t allow JavaScript by default. Especially if there is an unpatched flaw in my browser you won’t see me enable JavaScript/Flash/whatever until it’s fixed unless it’s for a site I trust and it over HTTPS.

That out of the way whatsmyip.org did two things:

Your IP Address is <span id="ip">123.123.123.123</span>

Made the IP in the HTML just something random but valid and added obfuscated JavaScript with a weak cipher to protect it.
Of course there is no point going crazy about this as anyone with enough time to decode it can easily use the address I provided above.

After a quick look at the HTML I saw something of interest

<script type="text/javascript" src="tech/addthis.php"></script>

http://www.whatsmyip.org/tech/addthis.php provides your IP with a bit of obfuscation, I was procrastinating on the book I’m writing so I gave it a shot.
Decoding the hex encoded elements of the array was easy.

With my rule to never reinvent the wheel I did a quick Google search and found

String.prototype.decodeEscapeSequence = function() {
    return this.replace(/\\x([0-9A-Fa-f]{2})/g, function() {
        return String.fromCharCode(parseInt(arguments[1], 16));
    });
};

Source: http://stackoverflow.com/questions/4209104/decoding-hex-string-in-javascript

After making the code look nicer and deobfuscating it I came up with:

function thisIP(data, key, iv)
{
	var something=0;
	data = data-key;
	data = data/iv;

	ip = Math.floor(data/16777216)+'.'
	+Math.floor((data%16777216)/65536)+'.'
	+Math.floor(((data%16777216)%65536)/256)+'.'
	+Math.floor((((data%16777216)%65536)%256));
	return ip;
}

I gave it a go and bingo my IP was decoded, so I quickly whipped up a Greasemonkey script.

// ==UserScript==
// @name           What's My IP.org Without JavaScript
// @namespace      stevenroddis.whatsmyiporg
// @author         Steven Roddis
// @copyright      stevenroddis.com
// @description    Decrypts the IP so you don't need to enable JavaScript.
// @include        http://www.whatsmyip.org/*
// @include        http://*.whatsmyip.org/*
// ==/UserScript==
function thisIP(data, key, iv)
{
	var something=0;
	data = data-key;
	data = data/iv;

	ip = Math.floor(data/16777216)+'.'
	+Math.floor((data%16777216)/65536)+'.'
	+Math.floor(((data%16777216)%65536)/256)+'.'
	+Math.floor((((data%16777216)%65536)%256));
	return ip;
}

GM_xmlhttpRequest({
	method:"GET",
	url:'http://www.whatsmyip.org/tech/addthis.php',
	onload:function(r) {
		data = r.responseText.match(/\[.+?,.+?,([0-9]+),.+?,.+?,.+?,.+?,.+?,.+?,([0-9]+),([0-9]+)/);
		document.getElementById('ip').innerHTML = thisIP(data[1], data[2], data[3]); //so what's on the page is a fake IP
		document.getElementById('ip').style.display = 'inline';
	}
});

And now whatsmyip.org is usable again. :)

National Australia Bank’s Useless Client Side Encryption

27 Jul 2011

I was making a Firefox Extension to quickly check my account balance at one of the banks I use. They have some annoying password policies 6-8 characters [A-Za-z0-9] but they do lock out an account after a couple of failed attempts and require out of band authentication (SMS). So after I finished what should have worked, the response I was getting was constantly bad password or client ID. After some digging I found the password submitted kept changing each time. (I didn’t know it wasn’t my password the first time, because who in the right mind doesn’t use a password manager)

After a few moments of looking over the included scripts I came across this in the JavaScript.

//p is the real password
function NABcrypt(p,k,a) {
//Looks for repeated chars
  for (var i=a.length-1;i>0;i--) {
    if (i!=a.indexOf(a.charAt(i))) {
	  a=a.substring(0,i)+a.substring(i+1);
	}
  }
  var r=new Array(p.length);
  for (var i=0;i<p.length;i++) {
    r[i]=p.charAt(i);
    var pi=a.indexOf(p.charAt(i));
    if (pi>=0 && i<k.length) {
      var ki=a.indexOf(k.charAt(i));
      if (ki>=0) {
	    pi-=ki;
		if (pi<0) pi+=a.length;
	    r[i]=a.charAt(pi);
	  }
    }
  }
  return r.join("");
}

A simple key based subistution cipher k changes and a is 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.

I’ve only come across something similar before in aSSL (a broken by design transport security). I can’t for the life of me think of why this would be useful, if it is to protect against client side malware, a simple software keylogger would already have the password.

Please don’t do this.

I felt Responsible Disclosure did not apply as there is no risk, transport layer security is implemented.