SlideShare a Scribd company logo
Web Security
By David Haskins
Hashing and Encryption
• Types of hashes:
– md5 (generally considered compromised)
– SHA-1, SHA-2, SHA-3
– LANMAN (definitely compromised)
Hashing and Encryption
• Hash of "hello Memphis PHP meetup group!":
– a52cc137d1f59dc9265c59751cd3e624
• Hash of "1":
– c4ca4238a0b923820dcc509a6f75849b
• Hash of "10":
– d3d9446802a44259755d38e6d163e820
Hashing and Encryption
Properties of hashes:
can be used to identify changes to data.
are considered one-way:
md5("my_string_here"); //exists
unmd5("535f8bd2e548ffed92027c53d5a24b56"); //doesn't exist
Hashing and Encryption
Encryption is reversible. Encryption requires a key to
decrypt.
Symmetric versus asymmetric key cryptography.
Symmetric would work like:
$key = 'secret';
$msg = encrypt("hidden message", $key);
echo decrypt($msg, $key);
Hashing and Encryption
The problem:
How do you get the key to someone over
the internet without some 12-year old hacker
reading it?
Hashing and Encryption
Asymmetric would work like:
$encrypt_key = 'key_123';
$decrypt_key = 'key_456';
$msg = encrypt(“hidden message”, $encrypt_key);
echo decrypt($msg, $decrypt_key);
Hashing and Encryption
Asymmetric would be like:
The point to remember, is that this will produce gibberish:
echo decrypt($msg, $encrypt_key);
Hashing and Encryption
In public key cryptography, there exist two keys:
- a public key
- a private key
One is used for encryption, the other is used for
decryption.
The whole reason this stuff works is because I can
encrypt a message with a public key, but it can only
be decrypted with a private key.
Hashing and Encryption
Small problem:
Asymmetric cryptography is slow.
Hashing and Encryption
Small problem:
Asymmetric cryptography is slow.
Solution:
Use asymmetric cryptography to share a
symmetric key. Then use symmetric
cryptography.
HTTPS
User
Amazon server
HTTPS
User
Amazon server
Send connection request on port 443
HTTPS
User
Amazon server
Send connection request on port 443
Send public key
HTTPS
User
Amazon server
Send connection request on port 443
Send public key
The browser generates a symmetric key,
encrypts it with Amazon's public key and
sends it to Amazon.
HTTPS
User
Amazon server
Send connection request on port 443
Send public key
The browser generates a symmetric
key, encrypts it with Amazon's public key
and sends it to Amazon.
Amazon decrypts symmetric key with
Amazon's private key and sends
response encrypted with symmetric key.
Web security
Hashes and Salting
Remember hashes?
They work like one-way encryption.
$string = '1';
echo md5($string);
//outputs 4ca4238a0b923820dcc509a6f75849b
Hashes and Salting
We can use this for validating passwords.
Hashes and Salting
The plain-text problem:
$password = $_POST['password'];
$user = $_POST['user'];
$query = "select id from user where password = '$password' and
userName = '$user'";
ID UserName Password
1 cypherTXT l3m0ns
2 fred password123
3 david_TN m3mph!$
4 sallyW omgPonies!
5 agent_007 1337h4x0r
Hashes and Salting
Store the hash of the password instead of the plain-text:
$password = md5($_POST['password']);
$user = $_POST['user'];
$query = "select id from user where password = '$password' and
userName = '$user'";
ID UserName Password
1 cypherTXT cf5712b00855500691cff0e4b0566c68
2 fred 482c811da5d5b4bc6d497ffa98491e38
3 david_TN f145a55e591e1c6ed235ce456a5166f7
4 sallyW e2c29e21e004f9e71ef9db780884ede1
5 agent_007 81d3ebd158986fbdd6bd47177312c026
Hashes and Salting
Rainbow tables
plain text hash
a 0cc175b9c0f1b6a831c399e269772661
b 92eb5ffee6ae2fec3ad71c777531578f
c 4a8a08f09d37b73795649038408b5f33
… …
aa 4124bc0a9335c27f086f24ba207a4912
ab 187ef4436122d1cc2f40dc2b92f0eba0
ac e2075474294983e013ee4dd2201c7a73
… …
zzzzzzzzzzzzzzzzzz 0d057201bcd27c92eaa9efc6a9ce08f0
Hashes and Salting
Rainbow tables
plain text hash
a 0cc175b9c0f1b6a831c399e269772661
b 92eb5ffee6ae2fec3ad71c777531578f
c 4a8a08f09d37b73795649038408b5f33
… …
aa 4124bc0a9335c27f086f24ba207a4912
ab 187ef4436122d1cc2f40dc2b92f0eba0
ac e2075474294983e013ee4dd2201c7a73
… …
zzzzzzzzzzzzzzzzzz 0d057201bcd27c92eaa9efc6a9ce08f0
Hashes and Salting
Place a "salt" in the code.
$salt = 's3kr3t';
$password = md5($_POST['password'] . $salt);
If the user uses "password123", his password becomes
"password123s3kr3t", which is much more complex.
$query = "select id from user where password = '$password' and
user = '$user'";
Hashes and Salting
Store the hash of the password and a unique salt:
$password = md5($_POST['password'] . $salt);
$user = $_POST['user'];
$query = "select id from user where password = '$password' and
userName = '$user'";
ID UserName Password Salt
1 cypherTXT cf5712b00855500691cff0e4b0566c68 bawex
2 fred 482c811da5d5b4bc6d497ffa98491e38 msefz
3 david_TN f145a55e591e1c6ed235ce456a5166f7 juftv
4 sallyW e2c29e21e004f9e71ef9db780884ede1 irqhj
5 agent_007 81d3ebd158986fbdd6bd47177312c026 coowo
SQL injection
SQL injection
$password = $_POST*‘password’+;
$id = $_SESSION*‘id’+;
$query = “update user set password =
‘$password’ where id = $id”;
SQL injection
// assume $password = ‘secret_password’;
// assume $id = 7;
$query = “update user set password = ‘$password’
where id = $id”;
Sent to the database:
update user set
password = ‘secret_password’
where id = 7
SQL injection
// assume $password = ‘secret_password’--’;
// assume $id = 7;
$query = “update user set password = ‘$password’
where id = $id”;
Sent to the database:
update user set
password = ‘secret_password’
--’where id = 7
SQL injection
//wrong solution:
$password = str_replace(“’”,”’”,$password);
$query = “update user set password =
‘$password’ where id = $id”;
Depending on web server encoding and
database encoding, you may still be vulnerable
SQL injection
//correct solution:
Use prepared statements
$query = “update user set password = ?
where id = ?”;
$stmt = $dbh->prepare($query);
$stmt->bindParam(1,$password);
$stmt->bindParam(2,$id);
Web security
Command injection
function safe_query($query){
$database = “ABC_DB";
$username = ‘IDEF42;
$password = ‘JKLM873’;
$destination = "localhost";
//connect
mysql_connect($destination, $username, $password) or die("Unable to connect to database: ". mysql_error());
//choose database
mysql_select_db($database) or die ("Unable to select database [$database]: " . mysql_error());
//submit query
$result = mysql_query($query) or die("Unable to modify database [$database]: " . mysql_error());
return $result;
}
Command injection
function safe_query($query){
shellexec(“echo $query >> record_queries.txt ”);
$database = “ABC_DB";
$username = ‘IDEF42;
$password = ‘JKLM873’;
$destination = "localhost";
//connect
mysql_connect($destination, $username, $password) or die("Unable to connect to database: ". mysql_error());
//choose database
mysql_select_db($database) or die ("Unable to select database [$database]: " . mysql_error());
//submit query
$result = mysql_query($query) or die("Unable to modify database [$database]: " . mysql_error());
return $result;
}
Command injection
Assume $query:
select * from article where id = 7; cp /backup/*.tgz .;
function safe_query($query){
shellexec(“echo $query >> record_queries.txt ”);
…blah, blah, blah…
return $result;
}
Command injection
Assume $query:
select * from article where id = 7; cp /backup/*.tgz .;
function safe_query($query){
shellexec(“echo $query >> record_queries.txt ”);
…blah, blah, blah…
return $result;
}
Command injection
Another interesting option:
Assume $query:
select * from article where id = 7; rm –rf /;
function safe_query($query){
shellexec(“echo $query >> record_queries.txt ”);
…blah, blah, blah…
return $result;
}
Command injection
Solution to preventing command injection:
Command injection
Solution to preventing command injection:
DON’T ALLOW SHELL ACCESS IN YOUR CODE
DON’T ALLOW SHELL ACCESS IN YOUR CODE
DON’T ALLOW SHELL ACCESS IN YOUR CODE
DON’T ALLOW SHELL ACCESS IN YOUR CODE
DON’T ALLOW SHELL ACCESS IN YOUR CODE
DON’T ALLOW SHELL ACCESS IN YOUR CODE
Command injection
If you’re going to do it anyway, use escapeshellcmd().
$code_that_will_get_me_fired = escapeshellcmd($query);
shellexec(“echo $code_that_will_get_me_fired >>
record_queries.txt ”);
File upload attack
Users can upload images (.jpg, .gif, .bmp, etc).
File upload attack
Make sure users can’t upload .php, .pl, .asp, etc.
files.
Use a whitelist, rather than a blacklist to enforce
this control.
The uploaded directory shouldn’t have any
execute permissions.

More Related Content

Web security

  • 2. Hashing and Encryption • Types of hashes: – md5 (generally considered compromised) – SHA-1, SHA-2, SHA-3 – LANMAN (definitely compromised)
  • 3. Hashing and Encryption • Hash of "hello Memphis PHP meetup group!": – a52cc137d1f59dc9265c59751cd3e624 • Hash of "1": – c4ca4238a0b923820dcc509a6f75849b • Hash of "10": – d3d9446802a44259755d38e6d163e820
  • 4. Hashing and Encryption Properties of hashes: can be used to identify changes to data. are considered one-way: md5("my_string_here"); //exists unmd5("535f8bd2e548ffed92027c53d5a24b56"); //doesn't exist
  • 5. Hashing and Encryption Encryption is reversible. Encryption requires a key to decrypt. Symmetric versus asymmetric key cryptography. Symmetric would work like: $key = 'secret'; $msg = encrypt("hidden message", $key); echo decrypt($msg, $key);
  • 6. Hashing and Encryption The problem: How do you get the key to someone over the internet without some 12-year old hacker reading it?
  • 7. Hashing and Encryption Asymmetric would work like: $encrypt_key = 'key_123'; $decrypt_key = 'key_456'; $msg = encrypt(“hidden message”, $encrypt_key); echo decrypt($msg, $decrypt_key);
  • 8. Hashing and Encryption Asymmetric would be like: The point to remember, is that this will produce gibberish: echo decrypt($msg, $encrypt_key);
  • 9. Hashing and Encryption In public key cryptography, there exist two keys: - a public key - a private key One is used for encryption, the other is used for decryption. The whole reason this stuff works is because I can encrypt a message with a public key, but it can only be decrypted with a private key.
  • 10. Hashing and Encryption Small problem: Asymmetric cryptography is slow.
  • 11. Hashing and Encryption Small problem: Asymmetric cryptography is slow. Solution: Use asymmetric cryptography to share a symmetric key. Then use symmetric cryptography.
  • 14. HTTPS User Amazon server Send connection request on port 443 Send public key
  • 15. HTTPS User Amazon server Send connection request on port 443 Send public key The browser generates a symmetric key, encrypts it with Amazon's public key and sends it to Amazon.
  • 16. HTTPS User Amazon server Send connection request on port 443 Send public key The browser generates a symmetric key, encrypts it with Amazon's public key and sends it to Amazon. Amazon decrypts symmetric key with Amazon's private key and sends response encrypted with symmetric key.
  • 18. Hashes and Salting Remember hashes? They work like one-way encryption. $string = '1'; echo md5($string); //outputs 4ca4238a0b923820dcc509a6f75849b
  • 19. Hashes and Salting We can use this for validating passwords.
  • 20. Hashes and Salting The plain-text problem: $password = $_POST['password']; $user = $_POST['user']; $query = "select id from user where password = '$password' and userName = '$user'"; ID UserName Password 1 cypherTXT l3m0ns 2 fred password123 3 david_TN m3mph!$ 4 sallyW omgPonies! 5 agent_007 1337h4x0r
  • 21. Hashes and Salting Store the hash of the password instead of the plain-text: $password = md5($_POST['password']); $user = $_POST['user']; $query = "select id from user where password = '$password' and userName = '$user'"; ID UserName Password 1 cypherTXT cf5712b00855500691cff0e4b0566c68 2 fred 482c811da5d5b4bc6d497ffa98491e38 3 david_TN f145a55e591e1c6ed235ce456a5166f7 4 sallyW e2c29e21e004f9e71ef9db780884ede1 5 agent_007 81d3ebd158986fbdd6bd47177312c026
  • 22. Hashes and Salting Rainbow tables plain text hash a 0cc175b9c0f1b6a831c399e269772661 b 92eb5ffee6ae2fec3ad71c777531578f c 4a8a08f09d37b73795649038408b5f33 … … aa 4124bc0a9335c27f086f24ba207a4912 ab 187ef4436122d1cc2f40dc2b92f0eba0 ac e2075474294983e013ee4dd2201c7a73 … … zzzzzzzzzzzzzzzzzz 0d057201bcd27c92eaa9efc6a9ce08f0
  • 23. Hashes and Salting Rainbow tables plain text hash a 0cc175b9c0f1b6a831c399e269772661 b 92eb5ffee6ae2fec3ad71c777531578f c 4a8a08f09d37b73795649038408b5f33 … … aa 4124bc0a9335c27f086f24ba207a4912 ab 187ef4436122d1cc2f40dc2b92f0eba0 ac e2075474294983e013ee4dd2201c7a73 … … zzzzzzzzzzzzzzzzzz 0d057201bcd27c92eaa9efc6a9ce08f0
  • 24. Hashes and Salting Place a "salt" in the code. $salt = 's3kr3t'; $password = md5($_POST['password'] . $salt); If the user uses "password123", his password becomes "password123s3kr3t", which is much more complex. $query = "select id from user where password = '$password' and user = '$user'";
  • 25. Hashes and Salting Store the hash of the password and a unique salt: $password = md5($_POST['password'] . $salt); $user = $_POST['user']; $query = "select id from user where password = '$password' and userName = '$user'"; ID UserName Password Salt 1 cypherTXT cf5712b00855500691cff0e4b0566c68 bawex 2 fred 482c811da5d5b4bc6d497ffa98491e38 msefz 3 david_TN f145a55e591e1c6ed235ce456a5166f7 juftv 4 sallyW e2c29e21e004f9e71ef9db780884ede1 irqhj 5 agent_007 81d3ebd158986fbdd6bd47177312c026 coowo
  • 27. SQL injection $password = $_POST*‘password’+; $id = $_SESSION*‘id’+; $query = “update user set password = ‘$password’ where id = $id”;
  • 28. SQL injection // assume $password = ‘secret_password’; // assume $id = 7; $query = “update user set password = ‘$password’ where id = $id”; Sent to the database: update user set password = ‘secret_password’ where id = 7
  • 29. SQL injection // assume $password = ‘secret_password’--’; // assume $id = 7; $query = “update user set password = ‘$password’ where id = $id”; Sent to the database: update user set password = ‘secret_password’ --’where id = 7
  • 30. SQL injection //wrong solution: $password = str_replace(“’”,”’”,$password); $query = “update user set password = ‘$password’ where id = $id”; Depending on web server encoding and database encoding, you may still be vulnerable
  • 31. SQL injection //correct solution: Use prepared statements $query = “update user set password = ? where id = ?”; $stmt = $dbh->prepare($query); $stmt->bindParam(1,$password); $stmt->bindParam(2,$id);
  • 33. Command injection function safe_query($query){ $database = “ABC_DB"; $username = ‘IDEF42; $password = ‘JKLM873’; $destination = "localhost"; //connect mysql_connect($destination, $username, $password) or die("Unable to connect to database: ". mysql_error()); //choose database mysql_select_db($database) or die ("Unable to select database [$database]: " . mysql_error()); //submit query $result = mysql_query($query) or die("Unable to modify database [$database]: " . mysql_error()); return $result; }
  • 34. Command injection function safe_query($query){ shellexec(“echo $query >> record_queries.txt ”); $database = “ABC_DB"; $username = ‘IDEF42; $password = ‘JKLM873’; $destination = "localhost"; //connect mysql_connect($destination, $username, $password) or die("Unable to connect to database: ". mysql_error()); //choose database mysql_select_db($database) or die ("Unable to select database [$database]: " . mysql_error()); //submit query $result = mysql_query($query) or die("Unable to modify database [$database]: " . mysql_error()); return $result; }
  • 35. Command injection Assume $query: select * from article where id = 7; cp /backup/*.tgz .; function safe_query($query){ shellexec(“echo $query >> record_queries.txt ”); …blah, blah, blah… return $result; }
  • 36. Command injection Assume $query: select * from article where id = 7; cp /backup/*.tgz .; function safe_query($query){ shellexec(“echo $query >> record_queries.txt ”); …blah, blah, blah… return $result; }
  • 37. Command injection Another interesting option: Assume $query: select * from article where id = 7; rm –rf /; function safe_query($query){ shellexec(“echo $query >> record_queries.txt ”); …blah, blah, blah… return $result; }
  • 38. Command injection Solution to preventing command injection:
  • 39. Command injection Solution to preventing command injection: DON’T ALLOW SHELL ACCESS IN YOUR CODE DON’T ALLOW SHELL ACCESS IN YOUR CODE DON’T ALLOW SHELL ACCESS IN YOUR CODE DON’T ALLOW SHELL ACCESS IN YOUR CODE DON’T ALLOW SHELL ACCESS IN YOUR CODE DON’T ALLOW SHELL ACCESS IN YOUR CODE
  • 40. Command injection If you’re going to do it anyway, use escapeshellcmd(). $code_that_will_get_me_fired = escapeshellcmd($query); shellexec(“echo $code_that_will_get_me_fired >> record_queries.txt ”);
  • 41. File upload attack Users can upload images (.jpg, .gif, .bmp, etc).
  • 42. File upload attack Make sure users can’t upload .php, .pl, .asp, etc. files. Use a whitelist, rather than a blacklist to enforce this control. The uploaded directory shouldn’t have any execute permissions.