HackLu CTF 2012 – Mini Zombie Business (100) Write-up

22 – Mini Zombie Business

As time passes by and the zombie apocalypse seems to stay for a while businesses have to adapt to survive. Food store chains offer brains and biscuits for their limping customers and fox on Fire seems to be a all-time-zombie-favourite, too. Since a lot of zombies have a broad band connection businesses strive to get online stores back up again. It’s just that webdesign seems to be quite hard for zombie employees.
They obfuscate all their code (god knows why).

Here is an example of a miserable attempt to create a working website. https://ctf.fluxfingers.net:2076/mini/

This webpage had some heavily obfuscated Javascript, with an escaped sequence of about 1 Mb:

<script>
eval(unescape("%65%76%61%6c%28%75%6e%65%73%63%61%70%65%28%22%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%37%35%25%36%65%25%36%35%25%37%33%25%36%33%25%36%31%25%37%30%25%36%35%25%32%38%25%32%32%25%32%35%25%33%36%25%33%35%25%32%35%25%33%37%25%33%36%25%32%35%25%33%36%25%33%31%25%32%35%25%33%36%25%36%33%25%32%35%25%33%32%25%33%38%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%36%35%25%32%35%25%33%36%25%33%35%25%32%35%25%33%37%25%33%33%25%32%35%25%33%36%25%33%33%25%32%35%25%33%36%25%33%31%25%32%35%25%33%37%25%33%30%25%32%35%25%33%36%25%33%35%25%32%35%25%33%32%25%33%38%25%32%35%25%33%32%25%33%32%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%31%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%36%25%33%33%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%38%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%36%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%33%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%33%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%31%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%30%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%38%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%32%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%37%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%31%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%33%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%32%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%38%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%37%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%33%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33....................................................."));

I tried to deobfuscate that huge chunk with a couple of lines of Python code, but it turned out that the result of doing eval(unescape(huge_escaped_sequence)) on that giant string was another eval(unescape(huge_escaped_sequence))!

So I decided to download the web page to my machine and do some little changes on the JS code in order to make it deobfuscate itself. Basically, I converted that huge JS line into a string, and made it repeatedly eval() itself as long as the result of the eval() started with “eval(unescape(“:

		<script>
		var x = 'eval(unescape("%65%76%61%6c%28%75%6e%65%73%63%61%70%65%28%22%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%37%35%25%36%65%25%36%35%25%37%33%25%36%33%25%36%31%25%37%30%25%36%35%25%32%38%25%32%32%25%32%35%25%33%36%25%33%35%25%32%35%25%33%37%25%33%36%25%32%35%25%33%36%25%33%31%25%32%35%25%33%36%25%36%33%25%32%35%25%33%32%25%33%38%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%36%35%25%32%35%25%33%36%25%33%35%25%32%35%25%33%37%25%33%33%25%32%35%25%33%36%25%33%33%25%32%35%25%33%36%25%33%31%25%32%35%25%33%37%25%33%30%25%32%35%25%33%36%25%33%35%25%32%35%25%33%32%25%33%38%25%32%35%25%33%32%25%33%32%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%36%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%31%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%36%25%33%33%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%32%25%32%35%25%33%33%25%33%38%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%36%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%36%25%32%35%25%33%33%25%33%35%25%32%35%25%33%32%25%33%35%25%32%35%25%33%33%25%33%37%25%32%35%25%33%33%25%33%33%25%32%35%25%33%32%25%33%35%25%32........................................................."))';

		var count = 0;
		while (x.slice(0,14)=="eval(unescape("){
			//Remove "eval(" from the beginning of the string, and also the last parenthesis, so I get something like 'unescape(%41%42...)'
			x = x.substr(5, x.length - 5 - 1);
			x = eval(x);
			count++;
		}
		//Result: 6 nested obfuscation layers!
		alert(count + ' obfuscation layers!');
		alert(x);
		</script>

After running that self-deobfuscating code, I got this still-obfuscated JS code:

(\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e(){\u0061=\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074.\u0061.d\u0061t\u0061set.\u0061;\u0073=a[27]+a[5]+a[18]+a[1]+a[12]+a[10]+a[19]+a[18]+a[7]+a[4]+a[2]+a[27]+a[5]+a[23]+a[31]+a[33]+a[34]+a[10]+a[27]+a[31]+a[20]+a[24]+a[19]+a[14]+a[20]+a[12]+a[31]+a[32]+a[38]+a[8]+a[12]+a[25]+a[7]+a[8]+a[2]+a[12]+a[7]+a[25]+a[19]+a[14]+a[8]+a[7]+a[36]+a[36]+a[36]+a[37]+a[32]+a[33]+a[39]+a[39]+a[32];\u0066\u006c\u0061\u0067=a[0]+a[22]+a[2]+a[13]+a[17]+a[7]+a[12]+a[2]+a[25]+a[12]+a[21]+a[28]+a[9]+a[5]+a[14]+a[2]+a[18]+a[25]+a[28]+a[2]+a[22]+a[22]+a[28]+a[4]+a[2]+a[21]+a[28]+a[8]+a[24]+a[24]+a[21]+a[28]+a[4]+a[2]+a[21];\u0078=a[12]+a[2]+a[25]+a[12]+a[21]+a[7]+a[3]+a[24]+a[2]+a[10]+a[18]+a[30];\u0061\u0072\u0067\u0075\u006d\u0065\u006e\u0074\u0073[1*0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+0x00000001-0x00001].\u0064\u0061\u0074\u0061\u0073\u0065\u0074.\u0061=\u0073+\u0078+'\x22)\x61\x6c\x65\x72\x74\x28\x22'+\u0066\u006c\u0061\u0067+\u0075\u006e\u0065\u0073\u0063\u0061\u0070\u0065('\x25\x32\x32\x25\x32\x39\x25\x33\x42\x25\x32\x30\x25\x37\x44\x25\x33\x42')})(\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074.\u0067\u0065\u0074\u0045\u006c\u0065\u006d\u0065\u006e\u0074\u0042\u0079\u0049\u0064('\x61'));\u0065\u0076\u0061\u006c(\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074.\u0067\u0065\u0074\u0045\u006c\u0065\u006d\u0065\u006e\u0074\u0042\u0079\u0049\u0064('\141')['\144\x61\x74\x61\163\x65\x74'].\u0061);

By deobfuscating that code I got this:

(function(){a=document.a.dataset.a;s=a[27]+a[5]+a[18]+a[1]+a[12]+a[10]+a[19]+a[18]+a[7]+a[4]+a[2]+a[27]+a[5]+a[23]+a[31]+a[33]+a[34]+a[10]+a[27]+a[31]+a[20]+a[24]+a[19]+a[14]+a[20]+a[12]+a[31]+a[32]+a[38]+a[8]+a[12]+a[25]+a[7]+a[8]+a[2]+a[12]+a[7]+a[25]+a[19]+a[14]+a[8]+a[7]+a[36]+a[36]+a[36]+a[37]+a[32]+a[33]+a[39]+a[39]+a[32];flag=a[0]+a[22]+a[2]+a[13]+a[17]+a[7]+a[12]+a[2]+a[25]+a[12]+a[21]+a[28]+a[9]+a[5]+a[14]+a[2]+a[18]+a[25]+a[28]+a[2]+a[22]+a[22]+a[28]+a[4]+a[2]+a[21]+a[28]+a[8]+a[24]+a[24]+a[21]+a[28]+a[4]+a[2]+a[21];x=a[12]+a[2]+a[25]+a[12]+a[21]+a[7]+a[3]+a[24]+a[2]+a[10]+a[18]+a[30];arguments[1*0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+0x00000001-0x00001].dataset.a=s+x+'")alert("'+flag+unescape('%22%29%3B%20%7D%3B')})(document.getElementById('a'));eval(document.getElementById('a')['dataset'].a);

Putting some indentation on that code and inserting it into the HTML I got this (note that I’ve added an alert(flag) statement after the construction of the flag):

<html>
	<head>
		<title>Mini Zombie Business</title>
		<style>body{b\0061 ckground:#000;text-\000061 lign:center}</style>
	</head>
	<body>
		<form/name="a"/data-a="Fcabdux ehiktgmaj:nopylqrsvf_wz(&quot;){}.?L="></form>
		<div/id="a"></div>
		<img/src="zomb.png"/onclick="dafuq()"/>
		<script>
(function(){
	a=document.a.dataset.a;
	s=a[27]+a[5]+a[18]+a[1]+a[12]+a[10]+a[19]+a[18]+a[7]+a[4]+a[2]+a[27]+a[5]+a[23]+a[31]+a[33]+a[34]+a[10]+a[27]+a[31]+a[20]+a[24]+a[19]+a[14]+a[20]+a[12]+a[31]+a[32]+a[38]+a[8]+a[12]+a[25]+a[7]+a[8]+a[2]+a[12]+a[7]+a[25]+a[19]+a[14]+a[8]+a[7]+a[36]+a[36]+a[36]+a[37]+a[32]+a[33]+a[39]+a[39]+a[32];
	alert(s);
	flag=a[0]+a[22]+a[2]+a[13]+a[17]+a[7]+a[12]+a[2]+a[25]+a[12]+a[21]+a[28]+a[9]+a[5]+a[14]+a[2]+a[18]+a[25]+a[28]+a[2]+a[22]+a[22]+a[28]+a[4]+a[2]+a[21]+a[28]+a[8]+a[24]+a[24]+a[21]+a[28]+a[4]+a[2]+a[21];x=a[12]+a[2]+a[25]+a[12]+a[21]+a[7]+a[3]+a[24]+a[2]+a[10]+a[18]+a[30];
	alert(flag);
	arguments[1*0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+0x00000001-0x00001].dataset.a = s + x +'")alert("' + flag + unescape('%22%29%3B%20%7D%3B')
	})(document.getElementById('a'));eval(document.getElementById('a')['dataset'].a);
	</script>
	</body>
</html>

So after loading that HTML in the browser I got an alert box with the flag for this challenge: tasty_humans_all_day_erry_day.

Advertisements

2 thoughts on “HackLu CTF 2012 – Mini Zombie Business (100) Write-up

  1. Hi,

    I resolved it in 30 seconds using firebug… I inspected the dom, and like many JS obfuscator, it was simply adding the deobfuscated script in plain.
    Still fun 🙂

  2. Hi Aris,
    Cool, I didn’t know it could be solved that way with Firebug. I’ve just loaded the Mini Zombie Business challenge a minute ago, fired up Firebug, and under the “Script” tab, there’s a list of dynamically eval()’ed scripts, and the last one is the deobfuscated one 🙂
    Thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s