Unlocking WebLock Pro

by Schnarf

A while ago I was reading some forums and someone posted a link to WebLock Pro (weblockpro.com).  The website claims "Breakthrough technology finally puts an end to website theft..."  The author Mike Chen, sells this software for $49.95.  So, to put it simply, he posted two blocks of unescaped code and the decrypted '_c' variable, and encouraged anyone else to "give it a try."  I did, and these are my results.

Before posing the Perl script, I'm going to explain how it works.  I'll use the example of weblockpro.com/home.php.  First, go to "View Page Source."

All you see should be: "<Page protected by WebLockPro.com>"

When I first saw the, followed by whitespace, I was curious whether he used some sort of whitespace-only encoding.  However, that's not the case.  Scroll down, then a bit to the right.  There's block of JavaScript.  First, there's an:

eval(unescape("%77%69..."))

This is simple to decode.  It results in:

windows.status="Page protected by WebLockPro.com";_dw=document.write;document.write=null;

Next is a variable called "_c", which is followed by a second block of escaped code which is evaluated.  When "unescaped," it comes out as:

function _x(s) {
   s=unescape(s);
   t=Array();
   t[0]="";
   j=0;
	
   for (i = 0; i < s.length; i++) {
      t[j] += String.fromCharCode(s.charCodeAt(i) + (i%2 == 0 ? : -1));
         if ((i+1) % 300 == 0) {
   	   j++;
	   t[j]="";
	 }
    }

    document.write=_dw;
    u="";
 
    for (i=0; i < t.length; i++) {
       u += t[i];
    }

    document.write(u);
    u="";

    t=Array();
    _dw=document.write;
    document.write=null;
}

This function is referenced after the second block of escaped code.

"_x" is the function which actually decrypts the data and writes it to the document.

Looking at the first block of code and then this again, there is a bit of trickery; document.write is saved to "_dw", then null is assigned to document.write, causing document.write not to work.

In order to write data, "_dw" is assigned back to document.write, the function is used, then null is again assigned to it.

We can see on the last line the call to "_x", the parameter of which is the actual encrypted page data.

Really, in the entire process of figuring this out, there was no cracking of any code, merely unescaping or otherwise unobfuscating one block of code to understand the next.

Now, my only task was to convert the JavaScript function to Perl, which was no feat.  The culmination of this work resulted in the following Perl script:

#!/usr/bin/perl
# The DMCA says: "a person who has lawfully obtained the right to use a copy of
# a computer program may circumvent a technological measure that effectively 
# controls access to a particular portion of that program for the sole purpose 
# of identifying and analyzing those elements of the program that are necessary
# to achieve interoperability of an independently created computer program with
# other programs... to the extent that any such acts of identification and 
# analysis do not constitute infringement under this title."
#
# This script is, of course, only to ensure interoperability with 
# non-javascript-compatible browsers.
#
# by Schnarf (2600, vol. 20, no. 4)
#
# Open the file
open (F, $ARGV[0]) or die "Could not open $ARGV[0] for reading: $!\n";
	@raw = <F>;
close (F);

$page = join ("\n", @raw);

# Get the data to decrypt
$data = getData ($page);
# Now decode that data
$final = decode ($data);
# Print it to STDOUT
print $final;

# This just grabs the parameter to _x
sub getData {
	my $page = shift;

	my $start = index ($page, '_x("');
	if ($start == -1) {
		die ("Could not locate start of raw data!\n");
	}
	my $end = index ($page, '");</script>', $start + 4);
	if ($end == -1) {
		die ("Could not locate end of raw data!\n");
	}
	$start += 4;

	return substr ($page, $start, $end - $start);
}

# This is just _x converted to perl
sub decode {
	my $s = shift;
	$s = unescape ($s);
	my @t = ();
	my @j = ();
	my $i;

	for ($i = 0; $i < length ($s); $i++) {
		$t[$j] .= chr (ord(substr($s, $i, 1)) + ($i % 2 == 0 ? 1 : -1));
		if (($i + 1) % 300 == 0) {
				$j++;
				$t[$j] = '';
		}
	}

	my $u = '';

	for ($i = 0; $i < $#t; $i++) {
		$u .= $t[$i];
	}

	return $u;
}

sub unescape {
	my $str = shift;

	$str =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge;

	return $str;
}

This Perl script takes one argument: the filename containing the data.  For example:

$ wget http://www.weblockpro.com/home.php
$ ./decode.pl home.php > fyad.html

The decrypted page will now be in fyad.html.

Other Stuff

There is a method of rich format copy/pasting to get around the obfuscation.  In Mozilla, "Select all/copy, fire up composer, paste, add base href (too lazy to grab all the images), save."

The only downside is that it doesn't copy JavaScript or other non-visible elements.

It's not hard to make this Perl script into a CGI proxy.

Where does this stand with the DMCA?  Check the comments of my Perl script.

Thanks to: R1CH (www.r1ch.net) and Xenomorph (www.xenomorph.net).

Shout outs: #cpp, snafa, redhackt, mish, madcow, zeet, and g0thm0g.

Code: decode.pl

Return to $2600 Index