Cargo Cult Security https://github.com/disaacson/cargo-cu lt-security by Derrick Isaacson
May 11, 2015
Cargo Cult Security
https://github.com/disaacson/cargo-cult-security
by Derrick Isaacson
http://en.wikipedia.org/wiki/Cargo_cult
Richard Feynman
Cargo Cult Programming
Ritualistic inclusion of code or patterns that are unnecessary for the task at hand.
• Design patterns• Factory• Wrapper
• Dependency injection• Cryptography• Encryption• Hashing
The Big Picture
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
Anti-pattern: Authentication
$plainTextId = '100000';
echo '<h4>"Secure" URL for image ' . $plainTextId . '.</h4>';
$cryptTextId = bin2hex(mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $plainTextId, MCRYPT_MODE_OFB, $initializationVector));
$secretImageUrl = "…?secure_id=". $cryptTextId;
echo '<a href="'. $secretImageUrl .'">'.$secretImageUrl.'</a>';
private_image.php?secure_id=573146feb41e
$cryptTextId = $_GET["secure_id"];
$plainTextId = rtrim(mcrypt_decrypt(MCRYPT_BLOWFISH, $key,hex2bin($cryptTextId), MCRYPT_MODE_OFB,
$initializationVector));
$imageData = file_get_contents("img/". $plainTextId);echo '<img src="data:image/png;base64,‘
. base64_encode($imageData).'">‘;
573146feb41e
100000
Team Photo
private_image.php?secure_id=573146feb41e
$cryptTextId = $_GET["secure_id"];
$plainTextId = rtrim(mcrypt_decrypt(MCRYPT_BLOWFISH, $key,hex2bin($cryptTextId), MCRYPT_MODE_OFB,
$initializationVector));
$imageData = file_get_contents("img/" . $plainTextId);echo '<img src="data:image/png;base64,‘
. base64_encode($imageData).'">‘;
573146feb41f
100001
attack plan
private_image.php?secure_id=573146feb41f
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
Anti-pattern: Integrity
$aes = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');…
return mcrypt_generic($aes, $data);
$cipher [45] = chr(ord($cipher [45]) ^ ord(".") ^ ord ("0"));
$aes = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');…
return mdecrypt_generic($aes, $data);
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
HMAC$plainTextId = '100000';$hmac = hash_hmac("sha256", $key, $plainTextId);$secretImageUrl = "…?id=". $plainTextId . "&hmac=" . $hmac;
echo '<a href="'. $secretImageUrl .'">' . $secretImageUrl . '</a>';
$plainTextId = $_GET["id"];$signature = $_GET["hmac"];$hmac = hash_hmac("sha256", $key, $plainTextId);if ($hmac == $signature) { $imageData = file_get_contents("img/" . $plainTextId . ".jpg"); echo '<img src="data:image/png;base64,'. base64_encode($imageData)
.'">'; }else { echo '<h4 class="error">Permission Denied!</h4>';}
Permission Denied!
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
Encryption Parameters
Creates cipher textCipher (AES, Blowfish, …) Secret keyData to encryptCBC, ECB, OFB, …Initialization Vector
mcrypt_encrypt( MCRYPT_BLOWFISH, $key, $plainText, MCRYPT_MODE_CBC, $iv);
Anti-pattern: Encryption Modes
$plainImageData = file_get_contents($file);
$cryptText = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $plainImageData, MCRYPT_MODE_ECB, $initializationVector);
file_put_contents($file . ".encrypted.data", $cryptText);
Cipher-block Chaining Mode
$plainImageData = file_get_contents($file);
$cryptText = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $plainImageData, MCRYPT_MODE_CBC, $initializationVector);
file_put_contents($file . ".encrypted.data", $cryptText);
Encryption Parameters
Creates cipher textCipher (AES, Blowfish, …) Secret keyData to encryptCBC, ECB, OFB, …Initialization Vector
mcrypt_encrypt( MCRYPT_BLOWFISH, $key, $plainText, MCRYPT_MODE_CBC, $iv);
Anti-pattern: Initialization Vector
$plainText = “Hold";
$cryptText = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $plainText, MCRYPT_MODE_CBC, md5($key));
• Monday: “a8b8f95c46”• Tuesday: “a8b8f95c46”• Wednesday: “a8b8f95c46”• Thursday: “a8b8f95c46”• Friday: “10f32c937a1284db”
Modes and IVs
• Cipher-block chaining prevents patterns within messages• Correct IV prevents patterns across
messages
Generating Keys & Initialization Vectors
$key = “koicy37m8ao2nl07";$iv = rand();$cypherText = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plainText, MCRYPT_MODE_CBC, $iv);
• How many bits of key entropy can be contained in 16 alphanumeric characters?• 96 bits!• ~0.00000002% of possible search space
• What initialization vector is really used here?• “\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0”!• PHP Warning: mcrypt_decrypt(): The IV parameter must be as long
as the blocksize in /home/derrick/…/CBC.php on line 27• Use
• $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,
MCRYPT_MODE_CBC);• mcrypt_create_iv($size);
Anti-pattern: Random Values<form action=""> <label>Donation amount</label> <input type="text" value="10.00"> <?php $csrfToken = rand(); setCookie("csrfToken", $csrfToken); echo "<input type=\"hidden\" value=\"$csrfToken\">“; ?> <input type="submit" value="Submit"></form>
Finding Linear Congruential Seed
Random random = new Random();long v1 = random.nextInt();long v2 = random.nextInt();for (int i = 0; i < 65536; i++) { long seed = v1 * 65536 + i; if (((seed * multiplier + addend) & mask) >>> 16) == v2) { System.out.println("Seed found: " + seed); break; }}
Anti-pattern: Psuedo-random Session IDs
<?php $uid = "12345678"; $sessionId = md5($uid . rand() . microtime()); setCookie(“session_id", $sessionId);?>
Really only ~20 bits of entropy.A modern GPU can calculate that in a second!9,12
HMACs and Secure Random
<form action=""> <label>Donation amount</label> <input type="text" value="10.00"> <?php $csrfToken = openssl_random_pseudo_bytes(32); setCookie("csrfToken", bin2hex($csrfToken)); echo "<input type=\"hidden\" value=\"$csrfToken\">“; ?> <input type="submit" value="Submit"></form>
Do not use sessions! Use HMACs!Seriously.
No Cargo Cult Security!
1. Identify true security goal.2. Find correct crypto primitive.3. Spend some time to learn about it.4. Write as little of your own crypto code
as possible.
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=6325
Crypto Primitives & Goals
Hash MACHMAC
Symmetric Key
Crypto
Asymmetric Key
Crypto
Digital Signature
Digital Certificate
s
Data Integrity
Data Authentication
Non-repudiation
Confidentiality
Trust
Questions?
https://github.com/disaacson/cargo-cult-security
References
1. http://en.wikipedia.org/wiki/Cargo_cult
2. http://neurotheory.columbia.edu/~ken/cargo_cult.html
3. http://en.wikipedia.org/wiki/Post_hoc_ergo_propter_hoc
4. http://en.wikipedia.org/wiki/Cargo_cult_programming
5. https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=6325
6. http://www.scs.stanford.edu/10au-cs144/notes/
7. http://resources.infosecinstitute.com/cbc-byte-flipping-attack-101-approach/
8. http://security.stackexchange.com/questions/18033/how-insecure-are-phps-rand-functions
9. http://crypto.di.uoa.gr/CRYPTO.SEC/Randomness_Attacks_files/paper.pdf
10. http://security.stackexchange.com/questions/17988/how-insecure-are-non-cryptographic-random-number-generators
11. http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html
12. http://thepasswordproject.com/oclhashcat_benchmarking
13. http://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php
14. https://github.com/disaacson/cargo-cult-security