Monthly Archives: July 2011

My View on Security Seals for Websites

30 Jul 2011

This will be a quick post because the answer is very simple but many times businesses ask me if it is worth the money.

  • Great for business, it builds customer confidence (shouldn’t even matter much who the seal is issued by)
  • Does not mean the website is secure, many times have websites with “Mcafee Secure” seal (previously “Hacker Safe”) been vulnerable to XSS, SQLi etc.

-S

Flow Bypass Attacks For Fun and Profit

30 Jul 2011

An interesting vulnerability that I’ve seen more and more frequently in web applications is Flow Bypass, I’m sure there are other names for it “Insufficient Process Validation” is one I’ve heard mentioned. Today we usually hear about XSS and SQLi very frequently. I’ve actually used this to exploit for my own fun, a staff control panel which looks like it was made in 2002 (Did I mention it says copyright 2009) and even uses frames :( makes you read all “urgent” messages before using it. Today I had 22, 19 of which were “please change your password it is about to expire”. I big deal of fuss is made on how they log the view message events and how if you have “read” it and don’t take notice you are in big trouble. I’ve made many Greasemonkey scripts to make the application more usable, such as direct links and a ajax staff search.

Which got me thinking, could it be as simple as just accessing the URL you normally goto after reading the messages? Yes and no, since I haven’t used frames since the 90′s it took be a while to figure out you can’t have a body if you use a frameset.

So I combined a redirect to a data uri that contained my session token (always passed via url in this app, *sigh*) which created the frameset you would normally see. It was done, I had completely bypassed reading any messages.

After whipping up a quick script to request the mail url via XHR I had a nice link in the navbar “22 unread message” which was clickable to read the messages.

Of course that is all fun, but imagine the impact of bypassing the intended flow of a web app for profit. Web developers need to understand they are not programming a client side application, they are responding to requests where anything can be manipulated. All data in a request is untrusted, a quick example is paying for a domain name and then going to a page to register it, just skip the payment page and head on over to register unlimited domains.

I’ve got a presentation on this topic later this year.

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.

An Idea I’ve Had For A Long Time

25 Jul 2011

It started off as a lab project, never intended for outside use. The idea was malware that could continue to spread by learning about vulnerability in other software.

The first edition was a language based parser for milw0rm advisories which worked quiet well, but had the flaw that it could be stopped by milw0rm.

The latest edition (still years back) would scan web server logs for remote file injection attempts and then use those on other servers. This had the advantage that other hackers with their log file filling attempts of hacking web applications could be harnessed with little effort.

I’d thought I’d just write a quick post about my idea, so that when we see malware like this I can smile.

Legal note: No outside servers were attacked.

P.S. I won’t be releasing my code for this.

reCAPTCHA Mailhide Google Dork

25 Jul 2011

I’ve always had the snow memory are never use it for anything useful, however I thought I’d share with the world rather than keep it to myself. The impact is that a spammer can enumerate what should be hidden e-mail addresses with the aid of CAPTCHA cracking services such as deCAPTCHA.

Google Dork

site:mailhide.recaptcha.net inurl:d?k

You can use this query, or scan the web yourself looking for these URLs. The best way would be to create your own e-mail hiding script, one that is unique, that way spam bots won’t have a clue what they’re doing.

Spamming users of recaptcha would be a waste of energy they are very unlikely to succumb to offers of cheap Viagra. However social engineering attacks would still be viable.

phpBB AJAX Chat/Shoutbox MOD CSRF Vulnerability

25 Jul 2011

Title: phpBB AJAX Chat/Shoutbox MOD CSRF Vulnerability

Release Date: 2011-04-30

Product Affected: http://startrekaccess.com/community/viewtopic.php?f=127&t=8675

Responsible Disclosure:

After repeated attempts to get the vendor to fix this flaw, he has told me to “Please stop taking up my time with something this trivial.” I have provided a risk assessment, sources on CSRF including OWASP and my implementation on how to fix it.

If after a reasonable attempt to make the vendor realise it is a vulnerability, the vendor refuses to acknowledge the flaw, the vulnerability will be publicly published.

First vendor contact was made on 2011-04-24 and continued till the 29th where he cut contact.

Discription:

All actions taken on chat.php are not protected against CSRF, this includes add and delete chat messages.

Solution:

This solution carries no warranty or guarantees, that said it works with the version I have.

In config.php
$secretKey = ‘CHANGE THIS TO SOMETHING SECURE’;

in shout.php
116: ‘CHAT_MAC’      => hash_hmac(‘ripemd160′, $user->data['user_id'], $secretKey)

in chat.php
49:
$chatMAC = request_var(‘mac’, ”);

56:
if($mode AND $chatMAC != hash_hmac(‘ripemd160′, $user->data['user_id'], $secretKey)) //action taken
{
die(‘Hacking attempt! (CSRF)’);
}

257:  ‘CHAT_MAC’      => hash_hmac(‘ripemd160′, $user->data['user_id'], $secretKey)

in templates:
after param = ‘mode=’ + mode;
Add param += ‘&mac=’ + ‘{CHAT_MAC}’;