Archive for the ‘reverse engineering’ Category

Decoding Encoded PHP Codes Part I (The First One)

Friday, November 14th, 2008

Okay its the first part of the script. The second part was published earlier. That time I kept place for this post. And here it is.Its another script that I got from a Guy. This time he was trying to crack the script. :D He didnt want to buy another so need to crack it.Well I am not a cracker, that guy sent me the script over messenger and told me “what type of script it is??”. I saw it and felt why not decode it.

The script was encoded many times iteratively. So I had to decode it that way to get the final output. I wrote a console php application to decode it. I’ll give you the script at the end of this post.

The script I got was something like following. I shortened it so that it fits my post.

$x=gzinflate(base64_decode('DdZFDsQGEkDRq2SXRF6YSQORmZm9GZkZ2tS2Tz99g1Lp61X9899
Q7byNLFFQPhOl/mVjRGf1oqHbcM6dllwFWTOBSW9s+skpCLM4WeTHX66NGnpmN3nIVOz4fMi9gUX
Hskmh9jS8zpkJ9DGohZbcYBuA/rwBqtl8UAt2xbOgSRkI5TvwfO4DUpTvtI0d1S06jUIpAzPLGv3sef8t
CjvR6Ceibo6PVE+Cc5QrAOmG9pfJglOZG58soOau2cal17Vl4vj34zUFuzWPzJ4Z+gI7MkuWpPUT4PH
CCVl6AIatNthVl5O7CSlOlX9kWrihG3aeQsQqRZAinFdVncZxVwYwBK8nzkm2XQ1/ZQpO/BwKzEpqxo
4A9dpX9okTd80CNZxfIEg/AJUCrzUf/78+++///XHP78n8P8='));

As you can see its base64 encoding and gz compression which took place to obfuscate. I just echo the $x; and found this.

?><? eval(gzinflate(base64_decode('DZbHDsTWDUV/JTvbmIV6Q+IY0lPvvW0CSaPeRxq
1r8/sCRLE4bng/9zz//Ko9s+LN+2qkasr38M8+2ksT9y6L+V3++QefZgiOYrQu1Ca2+BMR4y4oZ0
ZogcFJPx2BSJQuAZPiGTfT4TBL1eggAlirCq8OXSDstfIfYFyGX5+nHYMPmdeCZ+dR3fwZkFe0M
cvm5o5HZGtWYZuMQKbyqdv3LptjIbhH5UjreQDxYtde4GFE3GHguUHN9Xf5mxQUH61z+8Z+z8
='))); ?><?

Note there are something special about this code.

  1. php ending (?>) and starting (<?) tag is attached to the end and start.
  2. there is an eval() call.

Beside these the whole script is same!! The “?><?” part is harmless. I dont have to worry about it. My target is to replace the eval() call by a variable. something like usingi “$y=(gzinflate(base…” instead of “eval(gzinflate(base…”. See! Its a little change. I did it with the following code.

$x[0]=" "; // was '?'
$x[1]="\$"; // was '>'
$x[2]="y"; // was '<'
$x[3]="="; // was '?'
$x[4]=" "; // was ' '
$x[5]=" "; // was 'e'
$x[6]=" "; // was 'v'
$x[7]=" "; // was 'a'
$x[8]=" "; // was 'l'

What I am doing here is just replaceing the “?><? eval” with ” $y= “. After that the whole string ($x) will be like. I am accesing the string by index because its faster and I still dont konw how many iteration I need.

$y=   (gzinflate(base64_decode('DZbHDsTWDUV/JTvbmIV6Q+IY0lPvvW0CSaPeRxq1r8/
sCRLE4bngP9zzKo9s+LN+2qkasr38M8+2ksT/9y6L+V3++QefZgi/OYrQu1Ca2+/BMR4y4oZ0ZogcFJPx2BSJQuAZPiGTfT4TBL1eggAlirCq8OXSDstfIfYFyGX5+nH
YMPmdeCZ+dR3fwZkFe0Mcvm5o5HZGtWYZuMQKbyqdv3LptjIbhH5UjreQDxYtde4GF
E3GHguUHN9Xf5mxQUH61z+8Z+z8='))); ?><?

Now If I eval this code which is inside $x variable, I’ll get the new value. Lets see what it is. Just execute eval($x). I got this.

?><? eval(gzinflate(base64_decode('DZa1DsQIEkR/ZbPdlQMz
6WBlZo95bCcnMzP762/CzlrV9arrn//++58jPp/6reZiz7ZCSpOtILD/5U
U25cVff4pxKvOTq/A+C6ppuTXVh9byYSN4xjjDj0roMHq2hNehyBvzF
AgAIAha51nezgidtHNmcERfsXo/w=='))); ?><?

Hey, Its the same thing again. Ha ha. So lets make a loop and do it iteratively. see the following code.

$i=0;
while(strpos($x,"eval")!== false){
$len = strlen($x); // Current length of the code
echo "[".($i+1).":$len]".PHP_EOL.$x.PHP_EOL;
// Echoing the code.
$x[0]=" ";
$x[1]="\$";
$x[2]="y";
$x[3]="=";
$x[4]=" ";
$x[5]=" ";
$x[6]=" ";
$x[7]=" ";
$x[8]=" ";
eval($x);
// Puting the code in $y by this call.
$x = $y; // Substituting the previous code by the new one.
$i++;
}

The idea is I’ll loop through the code as long as I find there is an eval() call. If there is an eval() call I’ll just remove the eval and put the code to some other variable. So it wont get eval()<code/>ed but will be saved. Its done by eval($x) Then for iteration I am substituting my previous code (cause I dont need it anymore).

If you execute the code you’ll see the length of the code is reducing in each iteration. Also you’ll get lots of output. When the loop breaks, you know that there is no eval() call. That means there is no dynamic code execution. But there might be base64_decode or gzinflate()</code>. Why not check it? The last code was saved in $x. So lets echo $x.

In my case the output was the actual code that was written. Here is a sample code from there.

echo "<html>\n";
echo "<head>\n";
echo "<title>Ilegal Script</title>\n";
echo "</head>\n";
echo "<body>\n";
echo "<h1 align=\"center\"><font face=\"Verdana\" color=\"#FF0000\">Ilegal Script</font></h1>\n";
echo "<p align=\"center\"><font face=\"Verdana\"><b>Sorry! The license for this script is not avaliable for this domain ( $domain_name
)</b></font></p>\n";

So. At last its decoded.

Well things can be different. There is no gurranty that you’ll get the actual code in this stage. There can be further decoding.

Here is my final code that did the trick.

$x=gzinflate(base64_decode('DdZFDsQGEkDR.....'));
$i=0;
while(strpos($x,"eval")!== false):
$len = strlen($x);
echo "[".($i+1).":$len]".PHP_EOL.$x.PHP_EOL;
$x[0]=" ";
$x[1]="\$";
$x[2]="y";
$x[3]="=";
$x[4]=" ";
$x[5]=" ";
$x[6]=" ";
$x[7]=" ";
$x[8]=" ";
eval($x);
$x = $y;
$i++;
endwhile;
echo ($i+1).":".PHP_EOL.$x.PHP_EOL;

Happy Deobfuscation. :D

Decoding Encoded PHP Codes Part II

Saturday, August 9th, 2008

Its very common in these days that you buy script from web and after a while you need modification but the developer is out of reach. So you have to be satisfied with the current script. You may not modify it by yourself because most commercial scripts are encrypted or obfuscated.   Today, I’ll describe my experience about decoding an obfuscated php script.

First of all. Don’t start looking for part I. Because there is no part one. I have done this sort of things many times. But I forget to write.  There was another php script I have decoded months ago. That’ll be first part. Now this is second part. Just keeping a place for first part.

Okay. Lets start.

I got an script. I don’t know what does it do. What I saw, the script was obfuscated.  I wont give you the full script but I’ll give you a patter of the script.

Here is the raw script I got.

<?php
$o="QAAAOzh3b3cKDW5pZGiLwAGJXNvbnQndGR1bndzJwCgELRjAFAnaGlrfidzaCcEXCUToXoKDWQKmG9iZGwC1C8TcSsR4isjEHECQTg5";eval(base64_decode("JGxsbD0wO2V2YWwoYmFzZTY0X2RlY29k3VKR3hzYkd4c2JHeHNiR3hzYkNnMk1Da3VJajhpT3c9PSIpKTtldmFsKCRsbGxsbGxsbGwpOw=="));return;
?>

See, the raw data. Its format looks like base64 encoded. Though you can see base64_decode function is called, it does not assure that successive raw data will be also base64 encoded. I’ll not touch $o variable. Because, its static.  $o is not used in eval() statement. so Its not the obfuscated code I guess. I may not be right.

Note, The base64 data is truncated at the middle section. Their size was huge.

Now I did the following,

<?php
$eval_data = "JGxsbD0wO2V2YWwoYmFzZTY0X2RlY29k3VKR3hzYkd4c2JHeHNiR3hzYkNnMk1Da3VJajhpT3c9PSIpKTtldmFsKCRsbGxsbGxsbGwpOw==";
// Decoding base64 data
$a = base64_decode($eval_data);
echo $a;
?>

It shows an nearly unreadable php code fragment.

$lll=0;$code=(base64_decode("JGxsbGxsbGxsbGxsPSdiYXNlNjRfZGVjb2RlJzs="));echo $code;eval(base64_decode("JGxsbGxsbGxsbGxsPSdiYXNlNjRfZGVjb2RlJzs="));$ll=0;$code=($lllllllllll("JGxsbGxsbGxsbGw9J29yZCc7"));echo $code;eval($lllllllllll("JGxsbGxsbGxsbGw9J29yZCc7"));$llll=0;$lllll=3;$code= ... ... ... ... ... ... ... ... ... ... ... ... ... ...
... ... ... ... ... ... ... ... ... ... ... ...
... ... ... ... ... ... ... ... ... ... ... ... ... ($lllllllllll("JGxsbGxsbGxsbC49JGxsbGxsbGxsbGwuJGxsbGxsbGxsbGxsbCg2MCkuIj8iOw=="));echo $code;eval($lllllllllll("JGxsbGxsbGxsbC49JGxsbGxsbGxsbGwuJGxsbGxsbGxsbGxsbCg2MCkuIj8iOw=="));$code=($lllllllll);echo $code;eval($lllllllll);$lllllllllll='base64_decode';$llllllllll='ord';$l=$lllllllllll($o);$lllllllllllll='strlen';$llllllllllll='chr';$lllllllll="?".$llllllllllll(62);$lllllllll.=$lllllllll

But you’ll see something about this code. (I used regular expression for pattern)

  • variables are like /^\$l{3,}/ which mathces $lll, $llll, $lllll and so on.
  • some base64 strings again. /”[a-zA-Z0-9\+\/]+={0,2}”/ matches all these strings.
  • all base64 strings are started by “J” !!
  • Lots of eval() call as expected

In the above code fragment only the base64 strings were needed to decode. Cause others were only simple php syntax. Nothing special. So I extract the base64s and decode to observe it.

<?php
// extract any base64 data in the new string
$m = array();
preg_match_all('|"(JGx[a-zA-Z0-9=]+)"|',$a,$m);
// yes the patter is a bit different. ;)
// watch the variables;
print_r($m);
// Decode the strings.
foreach ($m[1] as $v){
echo base64_decode($v)."\n";
}?>

After decoding, I saw something like this.

$lllllllllll='base64_decode';
$llllllllll='ord';
$lllllllllllll='strlen';
$llllllllllll='chr';
$lllllllll="?".$llllllllllll(62);
$lllllllll.=$llllllllll.$llllllllllll(60)."?";

Ha ha. see? how the native functions are obfuscated.

Remember there was some eval() calls. They were used to dynamically evaluate php code. My target was to just echoing the code before it executes. Something like echo $x; eval($x). Say There is a code
eval($d)
I need to convert it to
echo $d; eval($d)

The following magic regular expression does the trick

//modify the code to echo before eval
$a1= preg_replace('|eval(\([^;]+\));|','$code=$1;echo $code;eval$1;',$a);
// here $a contains the first base64 decoded data. see code above.

Our code is modified. so when it will execute, it’ll show the dynamic php code.

We are almost there. Remember, the first base64 string was passed in an eval() ??

So, we’ll  just put the new modified code in eval() and call it.

That’s it as you have guessed

//eval finally to see the code. ;)
eval($a1);

That’ll make you see the code.

Here is what I have seen ;)

include_once('license.php');
//valid license

…. …. ….

Hope to write my first part soon.


Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
Based on a work at talk.cmyweb.net.