Sexy Pandalog

Osu, Tatakae, Sexy Pandas blog

 

November 29, 2008

POC’08 Scripting #1 (Woos writeup)

Filed under: conferences, writeups — at 20:00

This year at the POC conference there was an special “event”. The staff organized a hacking/reversing challenge called “Hacker’s Dream” that was composed by two crackmes, two script deobfuscation tests, two malware-like samples to analyze and a network forensics challenge to solve. You can download the second place report slides (in korean) (seems that the winner team was unable to attend the conference and therefore, the second one had to do the speech). During this speech, one of our pandas was checking his own writeup against the speaker’s one and also had the oportunity to chat with other people that tried the challenge. That panda (yes it’s you, moron) missed to solve two parts of the challenge, one of them being Scripting#1. So while talking with somebody that solved this particular part and also had a report, we managed to convince her to translate it. Finally, after some panda laziness, here we have the POC’08 Scripting#1 writeup by Woos. Enjoy!

Note: As it seems that the original contest files are no longer available on the POC webpage, you can download here the Scripting#1 challenge.

 

 

POC Hacker’s Dream Script#1

The html contents are encoded using US-ASCII charset we need to use tools like 8to7 or ASCIIExploit:

> ASCIIExploit d index.html >> decoded.html

During the analysis of the decoded html, we found the following suspicious JavaScript code:

<SCRIPT LANGUAGE="JavaScript" id="mineGame3">
// *******************************************************************************
// This is the script for the security of the game.
// *******************************************************************************
 
document.write( unescape('........'));
 
dF('.........');
</script>

After decoding the unescape, we see that it was hiding the dF()’s funcion body. Now we have to execute this script and look at the contents of the ‘t’ variable.

<script>
function dF(s)
{
  var s1=unescape(s.substr(0,s.length-1));
  var t='';
 
  for(i=0;i<s1.length;i++)
    t+=String.fromCharCode(s1.charCodeAt(i)-s.substr(s.length-1,1));
 
  document.write(unescape(t));
}
</script>

The contents of ‘t’ is a new script (we will call it “Password Script”):

<script language=JavaScript>
function l11111l(l1111ll)
{
  try
  {
    ll111II(ll11ll11l);
    for(var IIIlIII = 0; IIIlIII < ll111ll.length; IIIlIII++)
    {
      IIIIIII += ll111ll.charCodeAt(IIIlIII)
    }
    IIIIIII = IIIIIII % 200000;
    var lllIlll = new Array; 
    lllIlll = l1111ll.split(",");
    var IIIIIll = ""; 
    for(var IIIlIII = 0; IIIlIII < lllIlll.length; IIIlIII++)
    { 
      IIIIIll += String.fromCharCode(((lllIlll[IIIlIII])-IIIIIII) ^ llIlIII.charCodeAt(IIIlIII%llIlIII.length));
    }
 
    var IIIlllI=IIIIIll.length,lIlIlIl,IIlllII,IlllIll,IlIlIlI=(512*2),llIlIIl=0,llIllll=0,lllllll=0;
 
    for(llIIIII= Math.ceil(IIIlllI/IlIlIlI);llIIIII>0;llIIIII--)
    {
      IlllIll=''; 
      for(lIlIlIl=Math.min(IIIlllI,IlIlIlI);lIlIlIl>0; lIlIlIl--,IIIlllI--)
      {
        lllllll|=(IIIlIIl[ IIIIIll.charCodeAt(llIlIIl++)-48])<<llIllll;
        if(llIllll)
        {
          IlllIll+=String.fromCharCode(209^lllllll&255);
          lllllll>>=8;
          llIllll-=2
        } else {
          llIllll=6
        };
      } 
      ll111II(IlllIll) 
    } 
  } 
  catch(error) {}
}
</script>
<script language=JavaScript>
var IIIlIIl=Array(63,12,6,53,0,48,43,54,42,47,0,0,0,0,0,0,59,13,25,30,50,60,1,18,61,8,16,56,20,49,51,21,45,28,22,31,35,5,14,23,27,37,2,0,0,0,0,55,0,11,33,9,19,40,41,15,62,3,39,10,32,17,44,36,24,7,52,26,29,58,57,46,4,34,38);
 
l11111l("71496,71517,71488,71525,71484,71487,71467,71528,71541,71503,71531,71511,71530,71530,71546,71482,71515,71499,71531,71511,71442,71540,71525,71497,71516,71474,71507,71464,71441,71449,71525,71526,71542,71540,71546,71474,71443,71543,71477,71532,71506,71448,71448,71492,71546,71542,71486,71471,71455,71522,71455,71475,71565,71477,71459,71467,71464,71473,71488,71478,71473,71475,71452,71453,71548,71527,71524,71558,71554,71531,71450,71553,71502,71495,71450,71480,71445,71506,71558,71553,71481,71484,71509,71525,71563,71503,71448,71463,71474,71442,71454,71528,71473,71488,71454,71510,71484,71501,71450,71526,71489,71455,71458,71551,71549,71551,71537,71507,71562,71455,71450,71485,71567,71470,71553,71501,71554,71459,71565,71464,71443,71481,71562,71447,71537,71526,71486,71466,71481,71484,71498,71467,71455,71489,71523,71533,71446,71487,71553,71488,71443,71501,71485,71553,71562,71476,71513,71519,71445,71492,71458,71453,71480,71448,71451,71453,71464,71533,71512,71479,71460,71455,71488,71479,71567,71497,71512,71518,71554,71452,71554,71448,71449,71557,71561,71453,71447,71494,71447,71510,71497,71462,71485,71553,71494,71466,71469,71510,71449,71516,71527,71441,71454,71526,71442,71464,71506,71468,71471,71524,71465,71475,71477,71532,71498,71475,71448,71492,71561,71546,71538,71501,71562,71531,71531,71538,71502,71526,71552,71509,71513,71481,71474,71508,71529,71559,71550,71517,71538,71565,71495,71445,71484,71531,71553,71442,71468,71501,71568,71526,71536,71513,71527,71542,71552,71563,71534,71466,71484,71496,71461,71458,71508,71498,71462,71513,71554,71448,71442,71532,71498,71448,71475,71568,71542,71514")</script>

This is the decoded “Password Script”. You will notice that some elements referenced by the function can’t be found anywhere. This information must be hidden, so we must take a look at the rest of the html/javascript code. Intuition tells us that the “Password Script” is not useful by itself, so in order to confirm this we used Microsoft Visual Web Developer and got the clue while debugging. Something is being written into variable “mineCount2″:

mineList2=document.getElementById('mineGame2').innerHTML.split('\r\n');		 					
mineCount2 = "";	  	  		
 
for(c=4; c < (e+4); c++)	 		 		 
{	  	  		
	mineName2=mineList2[c];	 		 		 
 
	for(f=0; f < d; f++)	 		 		 
	{		 					
		y = ((mineName2.length - (8*d)) + (f*8));		 	 	  
		v = 0;		 					
		for(x = 0; x < 8; x++)	 	   		
		{		 			 	
			if(mineName2.charCodeAt(x+y) > 9)	  				 
			{	   		  
				v++;	  		 	 
			}	  			  
			if(x != 7)	 	   		
			{		 			 	
				v = v << 1;		 					
			}		 	 	  
		}		 					
		mineCount2 += String.fromCharCode(v);	  	  		
	}	  	    
}	  			  
document.write(mineCount2);

And the contents of “mineCount2″ after script execution:

<script>  var  ll11ll11l  =  "var  llIlIII  =  arguments.callee.toString();  var  ll111ll  =  llIlIII + 
\"asec\" + location.hostname; var IIIIIII = 0;"; ll111II=eval; </script>

But that doesn’t gives us the password, as there are two things we still need to do. First, define the correct value for the hostname. We will use the hostname referred in the “BASE HREF” directive, that is “ahnlab-security.com”. But you don’t need to modify the location.hostname value, just modify the script and replace the hostname with the desired value.

The second thing we need to take care about is that we’re handling a “javascript string” that is something hard to debug. For that reason we did a complete rewrite of this part of the script. Also we had some problems when calling “arguments.callee.toString();” so our workaround hack consisted in putting an html-id to the “Password Script” in order to access its contents:

<script>       
    var ll11ll11l = ""; 
    var test = document.getElementById('password_script_id').innerHTML.split('\r\n'); 
    var llIlIII = test[1];   
    var ll111ll = llIlIII + "asecahnlab-security.com";
    var IIIIIII = 0;       
    ll111II=document.write;

And the last “document.write” tells us the password:


Scripting1 solved

Scripting1 solved


EOF

Ok then, here ends our first imported writeup. Thanks again to Woos and all the people that made this amazing challenge.

See you!

1 Comment »

  1. Tora opa made my solution better~~ thanks, ^ ^

    Comment by woos — December 1, 2008 @ 13:44

Comments RSS

Leave a comment

Valid XHTML 1.0 Valid CSS 2