Howdy! How can we help you?
< All Topics
Print

How to Decode Sendy

How to Decode Sendy.

This is the most comprehensive I could do this.

I will not go into the details of how I figured it all because it would be a writing of several pages. Instead, I will make a short description of what I found. The script has many checks put in place, including a checksum function to prevent the script from running if any file tampering is done, even if inserting or deleting a single space.

We will be using the "_install.php" and the "includes/functions.php" files wich are the ones that are obfuscated. At the very top of those file, there is a block with all the information needed to decode each one.

This writing is how to decode Sendy. Nulling the script is another process. At least you will have the decoded source code.

Take the upper block of the file and look for the 3 "eval(base64_decode())" functions. The second of those functions is the one that we need. In that function are the numbers to decode the rest of the file.

Copy that second function without the "eval()" part into a text file and rename it anything ending with ".php" (Ex: file.php). Now by running a localserver like XAMPP, run the file in the browser (Ex: http://localhost/file.php). You may omit the "http://" part but I left it there to avoid confusion in this explanation.

Note: You even use a live server if you don't want to install XAMPP or any other localserver. You may also use an App for decoding base64 codes, but I will focus in the localserver.

Example of the file contents using the second "eval(base64_decode())" function in the "_install.php" file of Sendy v5.2.5:

<?php
  echo base64_decode("ZnVuY3Rpb24gTzAwTzAwT09PMCgkYSwkYil7JGM9YXJyYXkoODMwLDMyNCwzMiw2Mjg3KTtpZigkYj09NDUpeyRkPXN1YnN0cigkYSwkY1swXSskY1sxXSwkY1syXSk7fWVsc2VpZigkYj09MTM5KXskZD1zdWJzdHIoJGEsJGNbMF0sJGNbMV0pO31lbHNlaWYoJGI9PTE3Mil7JGQ9dHJpbShzdWJzdHIoJGEsJGNbMF0rJGNbMV0rJGNbMl0pKTt9cmV0dXJuJGQ7fQ==");
?>

Notice that the "eval()" function was not included, only the "base4_decode()".

After you run the file in your browser, it will dispkay the function unencoded.

This is the output you get from decoding the above code:

function O00O00OOO0($a,$b){$c=array(830,324,32,6287);if($b==45){$d=substr($a,$c[0]+$c[1],$c[2]);}elseif($b==139){$d=substr($a,$c[0],$c[1]);}elseif($b==172){$d=trim(substr($a,$c[0]+$c[1]+$c[2]));}return$d;}

As you can see, the code is still slightly obfuscated by using function names with "0's" and zeros to deceive. It does not matter because the function name is not important at this time. When I started doing this, I had to replace all function names by readable names, but now that it is all figured out, just forget about the confusing function names.

Now, you can format the function in a more readbale way like this:

function O00O00OOO0( $a, $b ) {

  $c = array( 830, 324, 32, 6287 );

  if( $b == 45 ) {
    $d = substr( $a, $c[0] + $c[1], $c[2] );
  } elseif ( $b == 139 ) {
    $d = substr( $a, $c[0], $c[1] );
  } elseif ( $b == 172 ) {
    $d = trim( substr( $a, $c[0] + $c[1] + $c[2] ) );
  }
  return $d;
}

It is laughable, bcause in the variable array "$c", the number "6287" means nothing. It is just another trick to confuse anyone trying to decode it.

The variable "$a", refers to the whole file as a string, including the opening "<?php" tag.

If variable "$b" is a selector to tell the function what output it expects. For example, when variable $b is "45", then variable "$d" becomes the location of the checksum, which its length runs for 32 characters or bytes. You can figure out by using the "substr()" function (sub-string of "$a", a.k.a the whole file) at a location of $c[0] + c[1], which is value "0" of $c (830) plus value "1" of $c (324), which is the offset of the 1154th character of the file and runs for the length of value "2" of $c, which is 32 (32 characters). Remember that computers start counting by zero, so the array of variable $c is as follows:

$c[0] = 830
$c[1] = 324
$c[2] = 32
$c[3] = 6287 (dummy variable)

And so on for variable "$b" when it is "139" and "172" which are the other possible values it reacts to. It assigns different subfunctions to give different output.

Anyway, that all was for you to start to understand the method used for encoding it.

Now let's cut to the real important part, which is when variable "$b" value is "172". This is the selector for telling the location and length of the complete file to be decoded and grabbing it. The output will be the sum of $c[0] + $c[1] + $c[2] (830 + 324 + 32), which is 1186. That is the offset where the real file begins. They use the trim() function to strip of any extra spaces or other symbols before and after the code resulting from the extraction.

So you need to count from the first character of the whole file (again, including the "<?php" tags) until position 1186. You may easily do this with a text editor like notepad2 or notepad++, which keeps a count of the cursor. Since the count starts with zero, just select in the text editor from the 1st character ("<") until the count shows as 1186 and delete it all because there you will really be in position 1185.

If in doubt, the chunk of code left will always start with "7". All before that "7" should be erased.

Ex: (this is part of the big chunk left)

7Txrc9s4kp+9VfsfEI5vKW1JovxQdtaWVeVLNIlrHTvlR7ZS4ymFIkEJa4pgCDKKksrv2B+0f+y6G+BDD9vyRp7L1t1kbIlAo9HodwOg2R//sCUiL8x8XrPNF+WMuevzpBWPY7t+uBLCS7ibcicVE/5FRnwF6MCTk9hNxVCEIp1VAcRA8bRm+0LFoTsb8CSRibIbrE398L/jvOSBiDjzsiThUco+8UQJGeHooPbMp06/Zr+4vrjon10N3vUvLk/Oz+x6nem+5a4Gszut3V....... AN SO ON

Now copy that code left in the file and put it in a separate PHP file as a variable.

Like this:

<?php
$chunk = '7Txrc9s4kp+9VfsfEI5..... and so on';
?>

Now, to decode it, you will need to "base64_decode()" it and the resulting code must be unziped through the "gzinflate()" function. Also, the output will not be ready to print on the screen, but to print into a file. If you try to print it in the screen you will only see garbage.

So what I do is running the following code into a PHP file in the local server:

<?php
  $chunk = '7Txrc9s4kp+9VfsfEI5..... and so on';

  $output = trim( $chunk );
  $output = base64_decode( $output );
  $output = gzinflate( $output );

  $temp = fopen( 'output.txt', 'w' );
  fwrite( $temp, $d );
  fclose( $temp );
?>

After you run it, you will have a text file with the whole decoded file. Remember to add the "<?php" tag at the beginning, as it will not be there, and rename the file from "output.txt" to "_install.php"

I guess that the PHP function "file_put_contents()" will work too and it is more simple, but I always use the code above as it is working well.

Now the next process is to null it, but that is another write-up.

SUMMARIZING...

1. Take the upper chunk of file "_install" and file "includes/function"
2. For each file, decode de second "eval(base64())" function.
3. Sum the first three of the four values of variabe "$c".
4. Copy everything after the location of the sum above.
5. Decode it in a separate PHP file.
6. Null the script.
Table of Contents