Encryption goes one step further than obfuscation or encoding, making the code impossible to execute without knowing the ‘secret’ used to make the encrypted text. Whether the secret is a password or another file or some system characteristic, these files are the hardest to analyze. For the most part, these are beyond the scope of what we will be looking at because cracking the encryption is non-trivial.
One of the more common password encrypted files that I’ve seen contains a decode
function that looks like this:
function decode($String){
$String = base64_decode($String);
$Salt=$_COOKIE["dolly_password"];
$StrLen = strlen($String);
$Seq = "adfasddsSAAfgdca";
$Gamma = "";
while (strlen($Gamma)<$StrLen)
{
$Seq = pack("H*",sha1($Gamma.$Seq.$Salt));
$Gamma.=substr($Seq,0,8);
}
return $String^$Gamma;
}
This function takes a string that has been encoded using the base64 encoding mechanism as an argument. It then runs through a series of steps to get the decrypted text:
After doing that, it loops through the following operations until Gamma is no longer shorter than the decoded string:
Once the decode function has built this Gamma string, it performs a bitwise operation known as XOR 1 with the decoded original string and returns that value.
The code then continues from there. If the password is set to the incorrect value, the resulting string won’t be valid for the next operation in the code and you will get an error.
If the password is correct, then the payload is executed and the results displayed to the user.
The XOR (exclusive OR) operation compares the binary representation of the arguments and returns a 0 or 1 depending on whether each bit in the string is the same (in which case you get a 0 returned) or different (in which case you get a 1). Example
A ^ A ==> NUL
A
in binary is 01000001
. Since we get a 0 when two digits in the same position are the same, A ^ A
results in 00000000
which is the binary representation of the NUL character.
_ ^ 0 ==> o
_
in binary is 01011111
. The number 0
converted into binary is actually 00110000
. When we XOR these together we get:
01011111
00110000
=======
01101111
This is the binary representation of the lowercase letter o
. ↩