$kernel->infect(): Creating a cryptovirus for Symfony2 apps

56
MALICIOUS CRYPTOGRAPHY IN SYMFONY APPS Raul Fraile @raulfraile

description

Slides for my presentation at the Symfony Valencia meetup on creating a cryptovirus for Symfony2 apps. Video (in Spanish): http://www.youtube.com/watch?v=rLHzmA0UuIw

Transcript of $kernel->infect(): Creating a cryptovirus for Symfony2 apps

Page 1: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

MALICIOUS CRYPTOGRAPHY IN SYMFONY APPS

Raul Fraile@raulfraile

Page 2: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• PHP/Symfony2 developer at

• PHP 5.3 Zend Certified Engineer

• Symfony Certified Developer

• BS in Computer Science. Ms(Res) student in Computing Technologies.

• Open source: LadybugPHP

ABOUT $ME

Page 3: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

STUFF WE’LL TALK ABOUT

Page 4: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Cryptovirology studies how to use cryptography to design malicious software.

• Closely related to ransomware and private information retrieval.

• A fundamental twist in cryptography.

CRYPTOVIROLOGY

Page 5: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

CRYPTOVIROLOGY

Public Key Cryptography

Symfony Internals

Hiding Strategies

Protection Strategies

Page 6: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

CREATING OUR OWN CRYPTOVIRUS

…for fun and profit!

Page 7: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

WARNING• This is not a real virus, just a

proof of concept. • Symfony is not more

vulnerable than other frameworks, this talk takes Symfony just as an example.

• We assume that the virus is already in the target computer.

KEEP CALM

Page 8: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#1 Get public key from the hacker server

GET public_key

Hacker serverApp server

Page 9: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#2 Infect the Symfony 2.x app

app[_dev].php

bootstrap.php.cache

Kernel events

Page 10: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#3 (a) Use the public key to encrypt data

app[_dev].php

bootstrap.php.cache

Kernel events

Database

User uploads

Logs

Page 11: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#4 (a) Pay to get the private key to decrypt data

GET private_key

Hacker serverApp server

Page 12: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#3 (b) Intercept user/passwords and save them encrypted

app[_dev].php

bootstrap.php.cache

Kernel events

raul

Submit

User

*****Password

Page 13: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

OUR CRYPTOVIRUS#4 (b) Get user/password pairs using a backdoor

GET users

Hacker serverApp server

Page 14: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PUBLIC KEY CRYPTOGRAPHY

Page 15: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Public key (asymmetric) cryptography requires two different keys: public and private.

• Based on one-way functions (trapdoors), which are easy to compute in one direction, but believed to be difficult to find its inverse.

• Most used one-way functions: integer factorization, discrete logarithm and elliptic curves.

PUBLIC KEY CRYPTOGRAPHY

Page 16: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PUBLIC KEY CRYPTOGRAPHY

WANT SEND image.jpg

AliceA A

BobB B

B

image.jpg

101101001011001 Chuck

Page 17: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PUBLIC KEY CRYPTOGRAPHY

Page 18: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

p = 115307171677547 q = 190761112638809 n = p * q = 21996124364443030184426121523

Having p and q, calculate n Having n, calculate p and q

Multiplication Factorization

PUBLIC KEY CRYPTOGRAPHY

SlowFastnot in Polinomial time

n = 21996124364443030184426121523 = p * q = … = 115307171677547 * 190761112638809

Page 19: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Open Source toolkit for SSL/TLS, as well as a full-strength general purpose cryptography library.

• PHP extension: php-openssl.

OPENSSL

Page 20: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

$config = array( "digest_alg" => "sha512", "private_key_bits" => 4096, "private_key_type" => OPENSSL_KEYTYPE_RSA, ); !// Create the private and public key $resource = openssl_pkey_new($config); !// Extract the private key openssl_pkey_export($resource, $privKey); !// Extract the public key $pubKey = openssl_pkey_get_details($res); $pubKey = $pubKey[“key"];

PHP + OPENSSL

Page 21: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PHP + OPENSSL

-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5gclOxvP9AyrUkk01b+b aa3TQSclpol0B/2bU8e54DfJkCermqN8aHQFhscWtDQeQjZMBMa3LPjql/QW0cgw knXrG0Ns+pk8960v8y1TBUK/AeOTfYJJ00A4Od6g7fA5oMOeI8IMaCD1eSJC5Fzi bhVUygxMzc4ctqqvnJGDd7BPKo8Dg8pFHPnNF6hj7rb/JogWq9qiKZEXFRwMnJSg … -----END PUBLIC KEY-----

-----BEGIN PRIVATE KEY----- YungQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDmByU7G8/0DKtS oTTVv5tprdNBJyWmiXQH/ZtTx7ngN8mQJ6uao3xodAWGxxa0NB5CNkwExrcs+OqX uBbRyDCSdesbQ2z6mTz3rS/zLVMFQr8B45N9gknTQDg53qDt8Dmgw54jwgxoIPV5 nkLkXOJuFVTKDEzNzhy2qq+ckYN3sE8qjwODykUc+c0XqGPutv8miBar2qIpkRcV gAyclKCPdhrW9OZiWX7IbhM95BwNJ3JZtPhWNA42IBlwv1tPMbiKnRcLC0FEL0qK Iv7z1uPMaCYo+HioCcECUXj6b2nuDbdNIpXHQr98fC+vjxJWmd6zfcXG98h0eBrp nbXU9SvNdX1fzHmDRrAl+NselZK5SHgyYY5aUb4gyyxQ+dVCWTaZQ1MmYZxiu4g4 a20tJHHYqkFV7ogS8u+Kfq4h/SlJ2wHeEhE4An1hXlEJXIZpK/z0+quScgKiqx9t oBhkG44f4KIVfpqg9RKgrg9yFaavFjWJSIbXh+ciuLDDI/150as5pFKAtENuVXjS xmrbpbbxeamKHNSD6O+wFbOaOw/r4NEWd1/p0AZ+qBRNl4fgCMCxRWDui6txjKGK oiFVf6Brf3xg/69KoCTS3svJ4Kmm0TB8tloXKRW/qXhFkQJpn12wCwuazPE98nep xApa2zTc7xcLt4ISJYHNCRX+n3puFwIDAQABAoICAB/K6QhsZaeTgLJUz+qjGvXW … -----END PRIVATE KEY-----

Page 22: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

$data = “Creating a cryptovirus for Symfony2 apps”; !// Encrypt the data openssl_public_encrypt($data, $encrypted, $pubKey); !// Decrypt the encrypted data openssl_private_decrypt($encrypted, $decrypted, $privKey);

PHP + OPENSSL

Page 23: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

SYMFONY INTERNALS

Page 24: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

kernel.request

Request

Response

kernel.controller

kernel.view kernel.response

kernel.terminate

kern

el.e

xcep

tion

KERNEL EVENTS

Page 25: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• kernel.request is dispatched as soon as the request arrives. Listeners can return a Response and “end” the execution.

• kernel.controller is dispatched once the controller has been resolved. Listeners can manipulate the Controller callable.

KERNEL EVENTS

Page 26: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• kernel.view is dispatched only if the Controller does not return a Response object.

• kernel.response allows to modify or replace the Response object after its creation.

KERNEL EVENTS

Page 27: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• kernel.exception is dispatched if there is an uncaught exception. Last chance to convert an Exception object into a Response object.

• kernel.terminate is dispatched once the response has been sent. Allows to run expensive post-response jobs.

KERNEL EVENTS

Page 28: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• The bootstrap.php.cache file is created to improve performance, reducing IO operations.

• Just a copy&paste of common classes and interfaces that will be used for sure.

BOOTSTRAP FILE

Page 29: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

BOOTSTRAP FILE

{ "name": "symfony/framework-standard-edition", "scripts": { "post-install-cmd": [ ..., “Sensio\\Bundle\\DistributionBundle\\Composer \\ScriptHandler::buildBootstrap", ... ], "post-update-cmd": [ ..., “Sensio\\Bundle\\DistributionBundle\\Composer \\ScriptHandler::buildBootstrap", ... ] } }

Page 30: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

HIDING THE VIRUS

Page 31: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Virus definitions. Antivirus software scans files to find matches. Useful for known malware (up-to-date antivirus).

• Heuristics allow antivirus software to identify new or modified malware, even without virus definition files. Based on system calls, network packets, kernel events…

ANTIVIRUS

Page 32: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

unlink(__FILE__);

REMOVING ITSELF

Page 33: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

$originalCode = "phpinfo();"; !// encode with base65 n times $encoded = $originalCode; $times = 5; for ($i=0; $i<$times;$i++) { $encoded = base64_encode($encoded); } !// generate hidden code $code = sprintf('eval(%s"%s"%s);', str_repeat('base64_decode(', $times), $encoded, str_repeat(')', $times) ); $code = gzdeflate($code); !var_dump($code); // K-K??HJ,N53...

GZIP + BASE64

Page 34: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

eval(gzinflate($code));

GZIP + BASE64

Page 35: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Polymorphic code is code that uses a polymorphic engine to mutate while keeping the original algorithm intact.

• Makes it difficult for antivirus software to recognise the code as it constantly changes.

• Emulation (sandbox) may be used.

POLYMORPHIC CODE

Page 36: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

echo 'Hello world!'; !echo 'Hello' . ' ' . 'world!'; !printf('Hello world!'); !file_put_contents('php://stdout', 'Hello world!'); printf('%c%c%c%c%c%c%c%c%c%c%c%c', 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21 );

POLYMORPHIC CODE

Page 37: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

All of them print “Hello world!”, but using different code which generate different AST/opcodes.

POLYMORPHIC CODE

Page 38: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

POLYMORPHIC CODE

Op Operands1 ECHO Hello+world%21'

2CONCAT Hello', '+'CONCAT ~0, 'world%21'

ECHO ~1

3SEND_VAL Hello+world%21'DO_FCALL printf'

4SEND_VAL php%3A%2F%2Fstdout'SEND_VAL Hello+world%21'DO_FCALL file_put_contents'

5

SEND_VAL %25c%25c%25c…%25c%25c’SEND_VAL 72SEND_VAL …101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33DO_FCALL printf'

Page 39: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• The goal would be to create a polymorphic engine that generates different code in each infection randomly.

• Really difficult to get random numbers in computers, as they usually can be predictable.

POLYMORPHIC CODE

Page 40: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

rand() mt_rand()

RANDOM NUMBERS

Page 41: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• Computational methods are not considered true random number generators. In practice, they are sufficient for most tasks.

• Physical methods use physical phenomenon expected to be random. For example, atmospheric noise (random.org), radioactive decay, radio noise or even a coin flipping.

RANDOM NUMBERS

Page 42: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

RANDOM NUMBERS

1 2 3 4 5 6 7 8 9 10

Human brain

Page 43: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

RANDOM NUMBERS

1 2 3 4 5 6 7 8 9 10

Ideal PRNG

Page 44: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PROTECTING US

Page 45: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

PROTECTING US

• Before the infection: security measures, restrictive permissions, disable php-openssl if we don’t need it, allow_url_fopen, virus inoculation…

• Once the app has been infected, we want to know it as soon as possible, checking its integrity.

Page 46: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

Hash functions create a fixed-length digest from data of arbitrary length.

HASH FUNCTIONS

Easy to compute.

Infeasible to generate a message that has a given hash.

Infeasible to modify a message without changing the hash.

Infeasible to find two different messages with the same hash.

Page 47: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

Tiny changes in source generate (with high probability) big changes in the digest.

HASH FUNCTIONS

Page 48: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• md5() is not collision resistant. It is possible to create two files that share the same checksum.

• We can include the checksum of the whole project in the build process and check it regularly.

HASH FUNCTIONS

Page 49: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

use Symfony\Component\Finder\Finder; !$finder = new Finder(); $finder->in(__DIR__ . ‘/project') ->files() ->name('*.php'); !$hash = hash_init('sha512'); foreach ($finder as $file) { hash_update($hash, $file->getContents()); } !// hash of the whole project $hash = hash_final($hash);

HASH FUNCTIONS

Page 50: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

• The PHAR extension provides a way to put entire PHP applications into a single file.

• Equivalent to Java JAR files.

• PHAR files can contain a signature (checksum) of the included files.

PHAR SIGNATURES

Page 51: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

Stub

Manifest

File contents

Signature

Actual contents of the files

Describes the contents of the files: filename, size, timestamp, CRC32…

Phar Signature in MD5, SHA1, SHA256, SHA512 or OpenSSL (key pair)

__HALT_COMPILER();Usually contains loader functionality

PHAR SIGNATURES

Page 52: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70 |#!/usr/bin/env p|!68 70 0a 3c 3f 70 68 70 0a 0a 50 68 61 72 3a 3a |hp.<?php..Phar::|!6d 61 70 50 68 61 72 28 27 74 65 73 74 2e 70 68 |mapPhar('test.ph|!61 72 27 29 3b 0a 65 63 68 6f 20 27 68 65 6c 6c |ar');.echo 'hell|!6f 20 77 6f 72 6c 64 21 27 3b 0a 0a 5f 5f 48 41 |o world!';..__HA|!4c 54 5f 43 4f 4d 50 49 4c 45 52 28 29 3b 20 3f |LT_COMPILER(); ?|!3e 0d 0a 33 00 00 00 01 00 00 00 11 00 00 00 01 |>..3............|!00 00 00 00 00 00 00 00 00 05 00 00 00 31 2e 74 |.............1.t|!78 74 10 00 00 00 d2 1e 50 53 10 00 00 00 26 fb |xt......PS....&.|!a7 61 b6 01 00 00 00 00 00 00 53 6f 6d 65 20 72 |.a........Some r|!61 6e 64 6f 6d 20 74 65 78 74 23 b5 11 ce 2c 41 |andom text#...,A|!e0 d4 3a db 21 ee cc ec c2 8c f6 3f 93 e2 02 00 |..:.!……?....|!00 00 47 42 4d 42 |..GBMB|

Stub

Manifest

File contents

Signature

Signature flagsMagic GBMB

PHAR SIGNATURES

Page 53: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70 |#!/usr/bin/env p|!68 70 0a 3c 3f 70 68 70 0a 0a 50 68 61 72 3a 3a |hp.<?php..Phar::|!6d 61 70 50 68 61 72 28 27 74 65 73 74 2e 70 68 |mapPhar('test.ph|!61 72 27 29 3b 0a 65 63 68 6f 20 27 68 65 6c 6c |ar');.echo 'hell|!6f 20 74 68 65 72 65 21 27 3b 0a 0a 5f 5f 48 41 |o there!';..__HA|!4c 54 5f 43 4f 4d 50 49 4c 45 52 28 29 3b 20 3f |LT_COMPILER(); ?|!3e 0d 0a 33 00 00 00 01 00 00 00 11 00 00 00 01 |>..3............|!00 00 00 00 00 00 00 00 00 05 00 00 00 31 2e 74 |.............1.t|!78 74 10 00 00 00 d2 1e 50 53 10 00 00 00 26 fb |xt......PS....&.|!a7 61 b6 01 00 00 00 00 00 00 53 6f 6d 65 20 72 |.a........Some r|!61 6e 64 6f 6d 20 74 65 78 74 23 b5 11 ce 2c 41 |andom text#...,A|!e0 d4 3a db 21 ee cc ec c2 8c f6 3f 93 e2 02 00 |..:.!……?....|!00 00 47 42 4d 42 |..GBMB|

PharException: phar "test.phar" has a broken signature in /home/raul/test.phar on line 4

PHAR SIGNATURES

Page 54: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70 |#!/usr/bin/env p|!68 70 0a 3c 3f 70 68 70 0a 0a 50 68 61 72 3a 3a |hp.<?php..Phar::|!6d 61 70 50 68 61 72 28 27 74 65 73 74 2e 70 68 |mapPhar('test.ph|!61 72 27 29 3b 0a 65 63 68 6f 20 27 68 65 6c 6c |ar');.echo 'hell|!6f 20 74 68 65 72 65 21 27 3b 0a 0a 5f 5f 48 41 |o there!';..__HA|!4c 54 5f 43 4f 4d 50 49 4c 45 52 28 29 3b 20 3f |LT_COMPILER(); ?|!3e 0d 0a 33 00 00 00 01 00 00 00 11 00 00 00 00 |>..3............|!00 00 00 00 00 00 00 00 00 05 00 00 00 31 2e 74 |.............1.t|!78 74 10 00 00 00 d2 1e 50 53 10 00 00 00 26 fb |xt......PS....&.|!a7 61 b6 01 00 00 00 00 00 00 53 6f 6d 65 20 72 |.a........Some r|!61 6e 64 6f 6d 20 74 65 78 74 23 b5 11 ce 2c 41 |andom text#...,A|!e0 d4 3a db 21 ee cc ec c2 8c f6 3f 93 e2 02 00 |..:.!……?....|!00 00 47 42 4d 42 |..GBMB|

PharException: phar "test.phar" does not have a signature in /home/raul/test.phar on line 4

phar.require_hash = On

PHAR SIGNATURES

Page 55: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

LET’S SEE IT IN ACTION!

Page 56: $kernel->infect(): Creating a cryptovirus for Symfony2 apps

THANK YOU!

https://www.flickr.com/photos/sanofi-pasteur/7413644106 https://www.flickr.com/photos/robbie73/8280822928

https://github.com/raulfraile/cryptosymfony