How To Install Aide Intrusion Detection System on Ubuntu

Aide stands for Advanced Intrusion Detection Environment which is one of the most popular tools for monitoring changes to a Unix or Linux system. Here i will list out how i am going to set this baby up on some of my server to secure on system.

Updating and Installing Aide

sudo apt-get update -y

Once you have update your repo, simply install Aide using the following command

sudo apt-get install aide

And aide is installed in your machine!

Configuring and Test out Aide

Next we are going to configure this baby. Initial the database with the command below,

sudo aideinit

It will take a while and once you have initial the database, Verify that the new aide database has been created

cd /var/lib/aide
ls -lt

And you should see something like this

AIDE 0.16a2-19-g16ed855 initialized AIDE database at /var/lib/aide/aide.db.new
Start timestamp: 2016-05-12 10:17:20 -0400
Verbose level: 6

Number of entries:	66800

---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------

/var/lib/aide/aide.db.new
  RMD160   : BOdplDoXDH0ws73WkoYe11+WIhM=
  TIGER    : tJ8xmXCDo9N9e8cJZBuqQSW/yl/ArSnJ
  SHA256   : E+Pc3ae0PDDxfRV9PcZZ8Fq+NsJZBLbo
             SQQ+i6xQ2I0=
  SHA512   : WHHce2bdDPzP1NgMSr9afReWcIvGbW+p
             D09ShUO3kT6EJpFWhqTR0RI60LmYW/sR
             76QTqqOOnIK+Cknc8mKXRA==
  CRC32    : OqKLPA==
  HAVAL    : zT+SY0Ee5SuFaXb7Kjo3gU7NpnH+QIyA
             buxyjH8AedM=
  GOST     : 4cW9q/3KpRawsNsRc2HtdjGgF70fsaI5
             8eRaLnsDlmo=


End timestamp: 2016-05-12 10:24:58 -0400 (run time: 7m 38s)

Move the new file to the new database using the following command,

mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Now, let's test this baby out with the following command,

aide.wrapper --check

and you will get something like this

root@mongodb-pk:~# aide.wrapper --check
AIDE 0.16a2-19-g16ed855 found differences between database and filesystem!!
Start timestamp: 2016-05-12 10:29:51 -0400
Verbose level: 6

Summary:
  Total number of entries:	66801
  Added entries:		1
  Removed entries:		1
  Changed entries:		3

---------------------------------------------------
Added entries:
---------------------------------------------------

f++++++++++++++++: /var/lib/aide/aide.db

---------------------------------------------------
Removed entries:
---------------------------------------------------

f----------------: /var/lib/aide/aide.db.new

---------------------------------------------------
Changed entries:
---------------------------------------------------

d =.... mc.. .. .: /var/lib/mongodb/diagnostic.data
f >b... mc..C.. .: /var/lib/mongodb/diagnostic.data/metrics.2016-05-12T08-52-09Z-00000
f >.... mci.C.. .: /var/lib/mongodb/diagnostic.data/metrics.interim

---------------------------------------------------
Detailed information about changes:
---------------------------------------------------

Directory: /var/lib/mongodb/diagnostic.data
  Mtime    : 2016-05-12 10:24:39 -0400        | 2016-05-12 10:36:39 -0400
  Ctime    : 2016-05-12 10:24:39 -0400        | 2016-05-12 10:36:39 -0400

File: /var/lib/mongodb/diagnostic.data/metrics.2016-05-12T08-52-09Z-00000
  Size     : 361980                           | 372957
  Bcount   : 720                              | 744
  Mtime    : 2016-05-12 10:22:08 -0400        | 2016-05-12 10:32:08 -0400
  Ctime    : 2016-05-12 10:22:08 -0400        | 2016-05-12 10:32:08 -0400
  RMD160   : czpo/fk+iRIEKUBjlc2+wELg/Wo=     | wEQV9cj/KyiGQmfGSLbzo9B44Gs=
  TIGER    : 2wLpFPWq3lxfxXyHpAMkVXUjDtZ08W8z | x8IbKbindr6NVwNbaUt0J5jWq9Y1cWmv
  SHA256   : lVRtuDTLDD7DYajbBEYoMSPpdrtxdJNA | 3J4B2ToLfGmBbHOQas/hKGj8HXe4zihW
             rxL5xH8A0kA=                     | 0OLKtXC4fqo=
  SHA512   : axlztAMc56xIGz7JnsOq8dAgZfCLmT83 | 49Fex6rPE24SnoOaLc+T/hIiTLEEyOmk
             gFZS6MB2zmT5aPxK4FmOSnEC9W5mtUNJ | YGeLF1W/fxZuRYk3FuwgpFlKA2qrmi2f
             AIaoa5bK736BAXwMcsA+NA==         | xNij3UG21mAiX+Tx2pRw+A==
  CRC32    : drkWXw==                         | rtCgKQ==
  HAVAL    : SR2yfai80zpN2Xw+8sUFSM/kTQBGAHsl | xIk6ByhAZN5C2eU2bTJzZ0oZcJeqsIiz
             71FSIVFT4qA=                     | AMbC0DPcNhg=
  GOST     : bE/NiblzIQRPzFx8jVymvvkEA+NO6on0 | txFhbK566EUxlQk6c36TfqgvYBttntcm
             k3XlP3vO2LA=                     | qyMIxjG3zK8=

File: /var/lib/mongodb/diagnostic.data/metrics.interim
  Size     : 5279                             | 5397
  Mtime    : 2016-05-12 10:24:39 -0400        | 2016-05-12 10:36:39 -0400
  Ctime    : 2016-05-12 10:24:39 -0400        | 2016-05-12 10:36:39 -0400
  Inode    : 1180042                          | 1179903
  RMD160   : Uch+G7OlOobiM/VjjdNHYSdCZUY=     | OnSReGX+lqQuCQURBBxkfHC9U5o=
  TIGER    : bB0QmZYYNl2SKSfz4MlNrpwYKwCS3Evf | ktNDR+97gTAK7catLGoOhEFJu6IfQZwi
  SHA256   : h0s1leYNb7/RxTi86z+nHhe7DChFJtSo | KIlG5ePVgwG/+DopSTPHo6VqnGzdnQMj
             TUZXyOwKKYw=                     | m97NR3Gifhk=
  SHA512   : 8PrN5C6RJgYHIuM7DjL3vjx9/5fRbnsr | QLXQngP8ouoc8bvs580De+Vh7bGR0Lq8
             MDpk+PcTAxLV3AUbkWP9Xq0hTzro7mlM | +2tXCfVed02e1DVRgxeG3LbKxqhofP76
             nT96+O95DnPZRmuD5OAPZA==         | 6Mz99D/w7u9eabdbsYmmOw==
  CRC32    : sTX43A==                         | Ta6Udw==
  HAVAL    : ZDpLBirCqbUqz/jym+FFjv2IvY9T4k+g | qTpVXVypYnzMGQZF4SMw7Wjg/jKkptpw
             hhcWR0kK/ZE=                     | PEqS+lI8g84=
  GOST     : 7yJZnGdeAM8slovcFTD0Ftcec5KT8weQ | gVW46Bk3upRekyxDI5sPP6N1xk7b6gX5
             yPYlQqSMkf4=                     | CJTybT2VVKQ=


---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------

/var/lib/aide/aide.db
  RMD160   : BOdplDoXDH0ws73WkoYe11+WIhM=
  TIGER    : tJ8xmXCDo9N9e8cJZBuqQSW/yl/ArSnJ
  SHA256   : E+Pc3ae0PDDxfRV9PcZZ8Fq+NsJZBLbo
             SQQ+i6xQ2I0=
  SHA512   : WHHce2bdDPzP1NgMSr9afReWcIvGbW+p
             D09ShUO3kT6EJpFWhqTR0RI60LmYW/sR
             76QTqqOOnIK+Cknc8mKXRA==
  CRC32    : OqKLPA==
  HAVAL    : zT+SY0Ee5SuFaXb7Kjo3gU7NpnH+QIyA
             buxyjH8AedM=
  GOST     : 4cW9q/3KpRawsNsRc2HtdjGgF70fsaI5
             8eRaLnsDlmo=


End timestamp: 2016-05-12 10:37:13 -0400 (run time: 7m 22s)

see the file that we just added and updated? Yeah, that's the one that its reporting.

Crontab Aide

Now we dont want to do this every single day manually, so let's setup a crontab.

vi aide.sh

with the following code

#! /bin/sh
MYDATE=`date +%Y-%m-%d`
MYFILENAME="Aide-"$MYDATE.txt
/bin/echo "Aide check !! `date`" > /tmp/$MYFILENAME
/usr/bin/aide.wrapper --check > /tmp/myAide.txt
/bin/cat /tmp/myAide.txt|/bin/grep -v failed >> /tmp/$MYFILENAME
/bin/echo "**************************************" >> /tmp/$MYFILENAME
/usr/bin/tail -20 /tmp/myAide.txt >> /tmp/$MYFILENAME
/bin/echo "****************DONE******************" >> /tmp/$MYFILENAME
/usr/bin/mail -s"$MYFILENAME `date`" [email protected] < /tmp/$MYFILENAME

now make it executable

chmod +x aide.sh

open up crontab

crontab -e

add the following crontab into it

06 01 * * 0-6 /root/aide.sh

And we are good to go! Simple as that!

Enhance Security Hash Function For Web Development

Previously i wrote an article on Better Hashing Password in PHP and PHP Secure Login Tips And Tricks. Both these articles are closely link to hash function and i find that i really didn't answer hash function on these two articles clearly enough. Especially on the article Better Hashing Password in PHP where i find my reader get confused on some of the security term used and caused some misunderstanding on the article. Hence, i came up with an idea to write out an article to detail some hash function question and improvement any developer can make to further secure their website. You will get a better understanding on security hash function and apply it on your web development once this is over.

Stop Using MD5 or SHA-1 in the future

If you have read Better Hashing Password in PHP, US-CERT of the U. S. Department of Homeland Security said that MD5 should be considered cryptographically broken and unsuitable for further use in 2008. Wiki explained a good detail of MD5 vulnerability that will surely make you switch your hash function from md5 to other better hash function out there. SHA1 on the other hand is more secure than MD5. However, collision has also been found on SHA-1. This is no surprise as both SHA-1 and MD5 are descended from MD4. Nonetheless, SHA-1 is still strong enough currently but not in the future looking at how computer power advancement has been progressing. Furthermore, faster way of creating a collision has also been found with only 252 attempt required which is a significant reduction from 263. What does this means? This means that SHA-1 attacks affect collision resistance, not pre-image resistance. Short to say that after 252 operations, the researchers are able to generate two unique messages that hash to the same digest value which is approximately a few month times in a dedicated hardware to construct such collision. While obtaining a SHA-1 collision via brute force would still require 280 operations. By the way for people who have no clue what's SHA means, it stand for Secure Hash Algorithm which is required by law for use in certain U. S. Government applications, including use within other cryptographic algorithms and protocols, for the protection of sensitive unclassified information. Thus, SHA family algorithm should be pretty solid for anyone who wish to secure their web system unless weakness has been found such as SHA-1.

Why Collision Is Bad

Any hash function will face collision eventually due to pigeonhole principle whenever members of a very large set are mapped to a relatively short bit string. The impact of collisions of any kind are undesirable. This means that two different set of message may generate the same hash value and one hash value may be generated by more than one message. Simply to say that the hash function doesn't generate a one to one relationship hash value. What this means for security is that there is a message exist 'n' which is different from 'm' that can be used to access the same system. Therefore, the more collision resistance a hash function is the better it is for security. Let me provide you with an example on how bad collision can caused for a system. Assume  a system had their hashed password compromised. Instead of 'hello' as password, another value 'bye' which was generate the same hashed value (which is not true) that the hacker is able to use access the system. Now, instead of a 5 length word, a similar hash value can be found with a 3 length word. And this means shorter time to crack your hashed value and easily it is for our hacker but its not always necessary this case. Obviously this is just an example and security cautious people will definitely do much more than this to prevent birthday or brute force attacks.

Moving To SHA-2 Hash Function

Like i mention on Better Hashing Password in PHP it is time to start considering moving towards a more solid hash function that have not found any weakness yet. Most U.S. government applications will be required to move to the SHA-2 family such as SHA-224, SHA-256, SHA-384, and SHA-512 of hash functions by 2010 as stated by NIST(National Institutes of Standards and Technology) on their hash function policy. Hence, for web security conscious people, we should also start moving towards SHA-2 too. Currently, PHP 5.12 also offered such option, hash

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  hash(’sha1′,$phrase);
$sha256= hash(’sha256′,$phrase);
$sha384= hash(’sha384′,$phrase);
$sha512= hash(’sha512′,$phrase);

For users who used version lower than PHP5.12, you you can try to use mhash which is an open source class for PHP.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  base64_encode(bin2hex(mhash(MHASH_SHA1,$phrase)));
$sha256= base64_encode(bin2hex(mhash(MHASH_SHA256,$phrase)));
$sha384= base64_encode(bin2hex(mhash(MHASH_SHA384,$phrase)));
$sha512= base64_encode(bin2hex(mhash(MHASH_SHA512,$phrase)));

SHA-2 should be used if you are web security minded person. SHA-1 can still be used definitely but additional enhancement would have to be in placed to strengthen such hash function from various attacks on its weakness. On the other hand, you may want to avoid MD5 for very security data.

Is SHA-2 Totally Secure?

Like we mention previously, all hash function is unavoidable towards collision. It is the same as stating that any system can be compromised with the proper amount of time and resources. The objective of a hash function is not to provide a totally uncrackable solution but to delay the process of breaking it where the process might required few hundred year to achieve.

Currently, the best public attacks on SHA-2 break 24 of the 64 or 80 rounds where 64 and 80 rounds is the number of loop in SHA-256 and SHA-512 respectively. Hence, it is safe to say no collision has yet to be found on SHA2 family yet. Hence, SHA-2 family can be said to have high collision resistance at the moment.

Attacks On Hash Function

An attack can be process faster with the given resources.  Some ways is to divide up the cracking process to different computer or exploit CPU architecture to take advantage of multiple cores on one processor or multiple processors on a single machine. This makes cracking the password much easier. And the below attacks might just be one of the cracking process used by them.

Birthday Attack

Most attacks on hash function are targeting the hash function collision resistance part as it is easier to launch a collision attacks. At the same time, preimage attacks has yet to be found on established hash functions.  The typical kind of attack against hash function will usually be collision attacks which is also known as birthday attacks. We mention earlier that every hash function will face collision problem. Therefore, theoretically it is possible to find two message that produce the same hash value.

The birthday attack is a statistical probability problem. The method used to find a collision is to simply evaluate the function ƒ for different input values that may be chosen randomly or pseudorandomly until the same result is found more than once. Because of the birthday problem, this method can be rather efficient.

Let's see how efficient it is. Given 'n' inputs and 'k' possible outputs, there are n(n-1)/2 pairs of inputs. For each pair, there is a probability of 1/k of both inputs producing the same output key. So, if you take k/2 pairs, the probability will be 50% that a matching pair will be found. If n is greater than sqrt(k), there is a good chance of finding a collision.

Brute Force Attack

brute force attack is the most fundamental attack but is often used.  Brute force is often used against hash value as hash function generates a one way hash value. This also means that the hash value is irreversible which makes it such a secure function. The only bet is to try each and every words in order to get it right. However, such method is very time consuming as the search space may be very huge.

Rainbow Table Attack

Another common attack is to use a rainbow table to try to figure out the original message given a hash value. Unlike brute force that attempt to match every single  character, rainbow table attack uses tables which offer time-memory-trade-off  and chains to lookup for the particular message. The table content does not depend on the hash value to be inverted. It is created once and then repeatedly used for the lookups unmodified. Increasing the length of the chain decreases the size of the table. It also increases the time required to perform lookups, and this is the time-memory trade-off of the rainbow table. In a simple case of one-item chains, the lookup is very fast, but the table is very big. Once chains get longer, the lookup slows down, but the table size goes down. The table here refers to the rainbow table where all kind of password is being hashed and stored in it. This process usually takes a while as the table should be extremely large to have a possibility of finding hash and as stated in bold above, it is usually repeatedly used for lookups unmodified. Once you understand this, you can visit kestas for an explanation of how rainbow table attack works.

Defensive Strategies

There are known ways of attacks for hash function. Similarly, there will be defensive strategies web developers can apply to better protect our system.

Using SALT

Another common way of enhancing hash function is through the using of SALT. A salt is used to strengthen user password if ever the system table is to be compromise. SALT is just an additional string appended to the password before it is being hashed and store into the database table. The same exact SALT will be required during verification between the user entered password and stored password. However, some of us get confuse of the capability of a SALT in cryptography can greatly help in a web system.

Before i explain SALT criteria, let's see what SALT can do for us. If your system database was compromised but no SALT was used for your password hashing. What will you do? Basically you will send an email out to everyone and request them to change their password like what Reddit did (well, the only differences is they did not even hash their password). On the other hand, if SALT is being used in this case, you guys will just have to modify the SALT algorithm without causing so much kiosk. Furthermore, the passwords that was compromised will be pretty solid to be easily decrypted.

Let’s look at brute force attack. We assume the hacker know the length of your SALT (since its compromised) but you did not change the length (assume the length is 1000 character). The hacker began to hack your system using the passwords they receive. Let’s assume there are around 94 character you can fill for your SALT or password (Its around 94 characters, please refer to ASCII values). Hence, 1 single character will make a brute force run 92 times to get a shot of a single character password (means no salt). Now, we have 1000 character for our SALT. This means that our hacker will have to try 921000 to get a shot to decrypt one password on the list of hacked passwords. This means they will have to try 101500 which is many many combination for just one password! I don’t think one year is enough for them to crack one password using a single computer. But correct me if i’m wrong. Anyway we can see from this interesting table from Lockdown.co.uk - The Home Computer Security Centre research which was written on Friday 10th July 2009 04:01 that the longer and more character in a password, the longer it will need to crack in a simple brute force attack. Try imagine 1000 character with different combination will take after looking at the table.

Next, let’s look at rainbow table attack attempt to crack such password. Now, we understand that rainbow table precompute hash chain. The goal is to precompute a data structure that, given any output h of the hash function, can either locate the p in P such that H(p) = h, or determine that there is no such p in P. Since all our password are salted uniquely, the attacker will have to generate a rainbow table for each salt for each possible password – exponentially increasing the effort an attacker must make. Furthermore, looking at the size of the SALT, it is infeasible for such attack to occur because of the sizable investment in computing processing, rainbow tables beyond fourteen places in length are not yet common. So, choosing a password that is longer than fourteen characters or that contains non-alphanumeric symbols may force an attacker to resort to brute-force methods.

However, OUR TABLE WAS COMPROMISED! This doesn't mean our system is compromised as well. It really depend on the SALT function you create as mention on Better Hashing Password in PHP. A paranoid SALT implementation criteria might have:

  • More than 64 bits long of SALT where 64 bits is the least amount of SALT length required to be secure as specific in PKCS #5
  • Randomly populated ASCII value for each SALT character
  • Validate the SALT to ensure it contains symbols, uppercase, lowercase and numbers
  • BASE64_encode it before storing into database (decode it when used)
  • Use other dynamic field in the table that might change by users as part of the SALT such as email address, telephone numbers, last login
  • Validate that no such password hash exist on the table.

Basically the above criteria should be enough for very solid SALT implementation that will not compromised your system even if your database was compromised. Let me explain the reason why on the above criteria.

  • Longer salt length means more brute force values and bigger size rainbow table required
  • ensure that any kind of character is being considered as salt to generate different hash for each password.
  • this is just a validation to ensure every kind of salt is being purchased
  • decode this salt value into the database so that stupid hacker will use it directly.
  • this is the criteria that makes the system secure as we are not doing hash(password + salt) instead we utilize the data in the table or other table to hash it this way hash(password + salt + username + secret answer). Take note that the each variable used to create a hash value are all static data (it doesn't change). Hence, the hacker might not know how the sequence and data of hashing the password is generated unless the function of the SALT is also compromised which is possible (developers can be hackers). However, the above description wrote dynamic data. This means that the SALT function will always generate a new SALT or password to be updated to the table whenever the dynamic data changed. Since last login time will only change upon login, we will use this dynamic data and generate a hash using this sequence hash(password + salt + last login time). Hence, whenever a user logged in, a new password hashed is generated and update the password field (which is a hash).  During user validation we will use hash(password + salt + database last login time) and update current time and new password into the database upon logged in. Similar, SALT can be generated every time upon logged in as well. Hence, we will use a new salt for every single logged in request. Now, if a hacker compromise your database, unless it can crack before every user logged in, this is pretty solid i would said.
  • In case of collision, always validate that the hash value cannot be found within the table before inserting it.

Like i said, this is a total paranoid solution that some of you might like to have. But basic hash(password + salt + username + secret answer) will be quite enough to protect your system provided you follow the PKCS#5 way of constructing your salt. You may want to visit PHP Secure Login Tips And Tricks for login security.

Iterative Hashing Technique

One way of enhancing your hash function is through iterative hashing. This technique basically takes a particular hash function and rehashing it many times (around 1000-10,000) making it incredibly hard to crack which is also known as key stretching or key strengthening in cryptography. Assuming a hacker manage to crack a hash value within 8 hours, rehashing it many times might change this from 8 hours to 8000-80,000 hours per password. I think we can imagine how an attack will work on such technique where every decrypted hash resulted in more hash to be decrypt. Its like opening a birthday present and found yourself a new box to open again (make me cry). Now we all know that SHA family hash function are all considered as fast. However, SHA-2 family might run slower than SHA-1 hash function as the block size is bigger but no much differences is being made.

What most of us will worry about is the time required for that many iterative round hashing to occur each time a user login or account creation. This will depend on how secure your system is required. You don't expect a bank web portal to compromise security for speed don't you? (hacker: HELL YEAH! SPEED!! SPEED!!) Hence, you may want to tune this according to your need and be at least 1000 iterative as something between 2-100 iterative is equivalence to nothing as such hash might had already exist on rainbow table. On the other hand, according to Wiki, Slowest personal computers in use today (2009) can do about 65000 SHA-1 hashes in one second using compiled code. Thus a program that uses key strengthening can use 65000 rounds of hashes and delay the user for at most one second.  The standard as mention on PKCS #5 is around 1000 and above. And in case you never heard of PKCS, in cryptography, PKCS refers to a group of Public Key Cryptography Standards devised and published by RSA Security.

SALT can be appended to each iterative to make your iteration algorithm more secure but it really depends on how you are going to design this.

Is Double Hashing Better?

Double hashing here is different from iterative hashing. Double hashing uses two different hash function instead of one. This is really confusing as double hashing is also refer to iterative hashing by some people. Hence, making everything confusing. An example is


sha1(md5($pass))

your system is at least as weak as the weakest of the hash algorithms you are using (md5).  It is true that both iterative and double hashing will reduce the search space but the effective reduction is insignificant compare to the gain from the benefit of iterative hashing. On the other hand, double hashing is bad as it will weaken the system since the hacker will only required to break the weaker hash function. Therefore, try avoiding double hashing and go for iterative hashing instead. Furthermore,  hashing two times with the same algorithm is considered suboptimal.

References And Good Reading

Conclusion

Enhance Security Hash Function is a pretty interesting topic. Understanding the strength and weakness of your used hash function is necessary to better protect your web system. Hash function is the only method most of us, web developers and the internet are using to secure ourselves. Without fully understanding  hash function is like a man on a battle field  with a gun but have little to no understand of its capability and weakness. And that's bad. (not that gun where you bring along with you to the toilet)

PHP Secure Login Tips And Tricks

Every website on the internet faces a similar threat, hackers. Every single website can be a target of a hacker if security measures aren't implemented properly especially when it comes to login pages where our most sensitive data are being held. Hence, there is a need to better understand how well your login page has been implemented to be considered as really secure. In this article, you will get a list of PHP secure login tips and tricks that will definitely help you decide on your secure rating of your login page.

Length Of your username and password

Both your username and password should be at least 6-8 characters long. A longer combination of username or password will make brute force attack or any other password cracking algorithm longer to crack. This can really help your network administrator to detect an attack before the attack penetrates through your login page.

Encrypt your password

We all know that encryption is necessary in term of any password. But i would still like to stress such importance. We are very dependent on encryption algorithms such as MD5 or SHA-1. However, these two algorithms are no longer that secure as compared to the older days. On Wednesday, February 16, 2005 SHA-1 has been broken by three china researchers. Although it is more towards collision attack rather than pre-image one we can assure one thing is that SHA-1 can be broken. You can read more about it on Bruce Schneier article. On the other hand, you can find MANY MD5 cracker online nowadays through Google. eg. md5crack.com. But similarly they are all collision attacks.  Wiki explains MD5 vulnerability in a way you will be discouraged from using it. It is time to encrypt your users password using SHA-2 such as sha256, sha384, sha512 or better. If you are using PHP 5.12 or above, there is a new function, hash that supports SHA-2.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  hash(’sha1′,$phrase);
$sha256= hash(’sha256′,$phrase);
$sha384= hash(’sha384′,$phrase);
$sha512= hash(’sha512′,$phrase);

For people who are using PHP 5.12 and below, you can try to use mhash which is an open source class for PHP.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  base64_encode(bin2hex(mhash(MHASH_SHA1,$phrase)));
$sha256= base64_encode(bin2hex(mhash(MHASH_SHA256,$phrase)));
$sha384= base64_encode(bin2hex(mhash(MHASH_SHA384,$phrase)));
$sha512= base64_encode(bin2hex(mhash(MHASH_SHA512,$phrase)));

SHA-2 should be used to secure your future application. Although MD5 and SHA-1 can still be used for authentication purposes with a very secure password combination. eg. (eQ@xC#Eif2dsa!e2cX2?"}23{D@.

NOTE**: NEVER DOUBLE HASH!

Double hashing is *worse* security than a regular hash. What you’re actually doing is taking some input $passwd, converting it to a string of exactly 32 characters containing only the characters [0-9][A-F], and then hashing *that*. You have just *greatly* increased the odds of a hash collision (ie. the odds that I can guess a phrase that will hash to the same value as your password).

sha1(md5($pass)) makes even less sense, since you’re feeding in 128-bits of information to generate a 256-bit hash, so 50% of the resulting data is redundant. You have not increased security at all.

Credit goes to Ghogilee

****updated on 8 Oct 09

On the note of Ghogilee, i found a few errors which i would like to point out. Double hashing here is referring to two different hash function.  It does reduce the search space but doesn't *greatly* increased the odds of a hash collision.  On the other hand, SHA-1 should be a 160-bit hash not 256-bit and not only does this doesn't increased the security but also weaken the hash function as the hacker will only required to crack the weaker hash function in this case md5.

You may want to visit Better Hashing Password in PHP for more information. If you wish to understand the risk and stuff you can do with hash function, please visit Enhance Security Hash Function For Web Development. Here i document the most detail hash function i could for your information.

Enhance Hash With Salt

Once you have decide your secure password encryption algorithm, the last thing you might want is to have different user having the same encryption algorithm hash code. This can bring another problem of more than one account being compromised at the same time when there are multiple same hash and short password can easily be cracked with ease when your database and tables have been known. We can generate a salt in order to overcome this problem so that the string is longer and more random (providing that the salt + password are random enough).

define('SALT_LENGTH', 15);
function HashMe($phrase, &$salt = null)
{
$key = '!@#$%^&*()_+=-{}][;";/?<>.,';
    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).$key.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt . $key .  $phrase).$salt;
}

The above function contains two parameters. The first will take in a phrase and generate a SHA-2 salt if the second parameter is placed with an empty variable. However, if both parameters contain values, it will be used when you wish to compare between two hashes. We can use the above method this way,

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$hashed_password = HashMe($password, $salt);
$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ("'.$username.'", "'.<d>$hashed_password .'", "'.$salt.'") WHERE 1';
..

The above will insert the information into the table when user is being created. We will check the user with the following salt.

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$sqlquery = 'SELECT `salt`, `password` FROM  `usertable` WHERE `username` = "'.$username.'" limit 1';
..
#we get the data here and placed into variable $row
$salt = $row['salt'];
$hashed_password = HashMe($password, $salt);
if($hashed_password  == $row['password']){
#verified
}
else{
#ACCESS DENIAL
}
..

The objective of salt is to lengthen the password in the table and also create a totally random hash code for each password. Hence, even if your table is being compromised, it will really take a lot of time for them to crack those hashed password. (We are assuming login page already implemented protection against multiple false log in)

Do not use easy guess username for administrators

It is always wise to use a slightly more challenging username for any administrators on your system. Username like 'admin', 'root' or 'super' will surely be the one on the hacker list to determine any administrator username. Be smart! Use something more challenging such as 'iamtheking' as a username instead (if your login system is case insensitive).

Log user login attempt

It is actually wise to log every important event in a system. Definitely, login page is one of them. We can determine whether any attempt of attack on our system is being carry out with a proper logging system. The log file or table can be very useful to track back what had gone wrong during a specific time frame when an attack occurs to determine whether an attack was launched to determine whether the login page was compromised.

Handle Error

It is important to prevent any error from being displayed to malicious users. These information is very useful for them to determine how to break into your system. Hence, they will try any type of value in order to break your PHP functions. Therefore, an ampersat symbol (@) should be placed in front of any function to prevent an error from occuring. On the other hand, you can use the function mention on Solutions to SQL Injection Attack which uses die to generate a better SQL error message that can be both professional and at the same time log your errors. The function is shown below,

function sql_failure_handler($query, $error) {
	$msg = htmlspecialchars('Failed Query: {$query}<br>SQL Error: {$error}');
	error_log($msg, 3, '/home/site/logs/sql_error_log');
	if (defined(‘debug’)) {
		return $msg;
	}
	return 'An error occurs, please try again later.';
}

#query=test;DELETE FOM breakplease;
$query = 'SELECT * FROM user WHERE name ='. base64_decode($_GET['query']);
mysql_query('$query) or die(sql_failure_handler($query, mysql_error()));

Always filter user input

Remember on the articles Solutions to SQL Injection Attack and Solutions to Cross-Site Scripting (XSS) Attack which mention that filtering user input is very important as hackers will use any way to break your login system. The rule is to never TRUST your user input until every last verification gets through. You can use the following function in PHP for your filter assistance,

htmlentities()
strip_tags ()
utf8_decode ()
htmlspecialchars()
ctype_digit()
ctype_alnum()
stripslashes()
str_replace()

Be Innovative Not Informative

We must be innovative on the message we present to our users whenever an error or login fail occurs. Message such as 'invalid password' or 'invalid username' is bad practices that gives information to malicious user what they went wrong. Instead, provides something like 'Login Fail. Please try again' will be a much more appropriate approach.

USE LIMIT or WHERE 1

In SQL query, for any login attempt, always place a LIMIT 1 at the end of your SQL statement. If there is a chance where a successful SQL injection is performed, only one account is being compromised instead of all. On the other hand, using WHERE 1 can help prevent any additional SQL query from placing at the front of your where clause.

Check HTTP Referrer

The basic of every security check is to ensure that the HTTP referrer came from the form on your site. If the HTTP referrer is suspicious, reject the request immediately. Although, HTTP Referrer can be easily spoofed with JavaScript it is always good to have any form of protection on a login page. However, some firewalls or proxies strip this information out which will caused many of your users to be unable to login successfully. Hence, you might want to consider whether to implement such checking for your login system.

Nonce authentication

Another better way of authenticating than checking the HTTP Referrer is to use acryptographic nonce. A nonce is a number used once, and it is used for intention verification purposes. Think of it as a password for THAT particular form and only can be used once. It really depends on how you implement your Nonce between the client and server.

Use maxlength

It is definitely a great idea to only allow a maximum length of characters user can placed on an input box. This is like a restriction placing in front of malicious user to provoke their creativity in order to penetrate your system. However, you might not like this idea too as it minimize the number of combination for hackers to crack your login page. Personally i will place such restriction as my login page will never allow more than certain fail login.

$_POST ONLY

When dealing with any form data. The only answer is using $_POST. NO $_REQUEST or $_GET should be use as you are just making life easier for hacker and weaken your security. Although $_POST can still be used by hacker but it makes the job troublesome.

Sub String Not Trim

In a login page, it is best to secure ourselves. Hence, if a user made an error on their username or password, the system should not correct for them. If a user enters a username with leading or trailing space we are not going to trim it nicely for them before we check. On the other hand, we will sub string it out so that we are checking the maximum length that is being enforce on the text box.

MYSQL Accounts

It is important for any secure website to be cautious on the access given to MYSQL user account on the specific action. For login purposes, the only thing that the user allows to do is to retrieve data from MYSQL table. Hence, other actions such as delete, update, alter etc. should not be given to the login page. If a successful SQL Injection was launched on the site. Imagine the user updating your user account password to the one given. Our security measure will just kick us back to one. Hence, always be cautious on the access given to MYSQL user account.

Utilize IP

Always ensure that IP address is used together with session key after a user has logged into your portal. This can prevent Session attacks and at the same time ensure that the same person is viewing the content of your secure page. You can also use IP to ban certain users from trying to guess your login username or password upon certain tries. However, using IP may mean certain restrictions for certain companies or proxy users from accessing your website. Nonetheless, this can be solved by detecting their connection. You can use this script to detect whether they are behind proxy server

if (
      $_SERVER['HTTP_X_FORWARDED_FOR']
   || $_SERVER['HTTP_X_FORWARDED']
   || $_SERVER['HTTP_FORWARDED_FOR']
   || $_SERVER['HTTP_VIA']
   || in_array($_SERVER['REMOTE_PORT'], array(8080,80,6588,8000,3128,553,554))
   || @fsockopen($_SERVER['REMOTE_ADDR'], 80, $errno, $errstr, 30))
{
    exit('Proxy detected');
}

The above code should allows you to detect even anonymous proxy server.

*****Update 7 Oct 2009

I forgot to mention here that the above script will only be necessary if an IP address cannot be detected (Thanks Julius).

Utilize Cookies

I forgot to mention this important thing to you guys. There is also a need to tie cookie together with session and/or ip to prevent session hijack or cross-site request forgery (CSRF). The hacker might be able to hijack your session through different ways but cookies will still remind on your user client browser.

Cookies can also used for auto logout module by setting the expiry date of the cookie after 15 minutes and if the cookie doesn't exist, the user has been idle for 15 minutes. On the other hand, we can refresh this cookie every user activity. This is one of the many ways to implement auto logout functionality but this is not secure as the cookie can be stolen by hacker and prolong the duration of the cookie expiration time.

Lastly, we talk about locking user upon certain attempts but IP was difficult to be used. This can be solve by utilize cookie to set the number of tries performed by the user/browser. Using cookie is definitely insecure way of keeping track of user attempts but it also creates additional barriers for hackers to overcome. This should be used together with account lock functionality to prevent such weakness in your defense (this means cookie count and account attempts count should not be link together).

Auto Logged Out Mechanism

I forgot this one but one of the readers did not. Implementing an auto logged out mechanism onto your login system can really help prevent CSRF attacks. Since we can't control whether our user leave their account logged in while browsing or surfing the net, we can definitely cover their butt but having this mechanism up to prevent any CSRF or Session attacks. Since both attacks require the user to be logged in.

*****Update End

Lock upon certain fail attempt

This is something that most secure web pages should looked upon. A very good way of locking a user will be as follow,

  1. n times fail attempt locked m minutes
  2. n fail attempt due to 1. locked further m+30 minutes
  3. n fail attempt due to 2. locked for the whole day

An example will be as follows:

  • 3 times fail attempt locked 10 minutes
  • 3 fail attempt due to 3 times fail attempt locked 10 minutes subsequence locked 10+30 minutes
  • 3 fail attempt due to the above will result in whole day lock

You can lock a user based on IP or accounts. It will be better to lock them based on accounts IF proxy IP is unable to detect due to the fact that it is an anonymous proxy. IP should be used otherwise. This will prevent the user from guessing the correct username. On the other hand, if a username was guessed correct the same process can be applied and disabled the account by sending an email to the original author to reactive it. But the same message should be used. (not informative information!) If you are worry of blocking an entire proxy server or company employees, you can just go by account since breaking an account will required certain tries anyway.

SSL Encryption

No matter what you do on the above, without a secure line from the client to your server everything will be meaningless when it comes to packet sniffer which is also known as man in the middle attack. Especially for attacks such as Session Hijack. Password can be send directly into a hacker computer without the need to use brute force. The above mentioned methods definitely can stop newbies but not those that know their stuff. Without such encryption, getting your password won't be that difficult. Here's a video showing how easily it can be done without SSL encryption.

Summary

Any kind of system can still be compromised but the time and effort to compromised such system is another thing to be considered. The above mention methods are ways to make life difficult for hackers so that they will give up on penetrating your system. Hence, any little bit of security measure we can implement on our system is considered as a line of defense. There is never a bad thing by being paranoid in securing your web system. A website is like a man on an open field ready to be shoot at anytime! Do your website a favor. Wear a helmet. (not condom)

Better Hashing Password in PHP

Every developer should know that storing any type of password in plain text is the worst possible decision anyone can make in a secure environment. Between security and confidentiality which one will you choose? Nowadays hacking are perform through social engineering or an inside job, by an employee or trusted person. How exactly confident are you towards securing your stuff and confidentiality of your user? Most of us will know that the Reddit suffer from such problem when all their username and password were compromised as their password wasn't hashed and stored as plain text. And twitter was attacked through social engineering recently. We won't want this to happen to us right? Therefore, in this article you will get to know some ways to better hash your password in PHP and some ways to improve your security.

What is Hashing?

Hashing is a term used in encryption to perform a deterministic procedure that takes an arbitrary block of data and returns a fixed-size bit string. Any accidental or intentional attempt to change the data will change the hash value. Moreover, different message will have different hash value. There should not be an exact hash value with different message. And it is infeasible to find a message that has a given hash. Hence, many information security application uses hashing to protect or authenticate the confidentiality of the content of the application such as digital signatures, message authentication codes (MACs), and other forms of authentication.

Authenticate User

We use cryptographic hash function to hash our password. And all of us should not be aware of what is being placed as password in the table. So how do we authenticate these users password since hash value is a one way encryption? This can easily be achieve through comparing the hash value against the one user has keyed in and the one stored in our database!

Rainbow table Attack

A rainbow table attack is a form of lookup table that aim to decode the hash value in order to make hashing feasible to find a message that has a given hash. Rainbow table attack is usually used against cryptographic hash function after they have retrieved a hash value. However, we can better protect ourselves by adding SALT onto our plain text to make it more infeasible for rainbow table to retrieve pain text with a given hash value.

SHA-1 and MD5

We all know that hashing is necessary in term of any password. But i would still like to stress such importance. We are very dependency on encryption algorithm such as MD5 or SHA-1. However, these two algorithm is no longer that secure as compared to the older days. On Wednesday, February 16, 2005 SHA-1 has been broken by three china research. Although its more towards collision attack rather than pre-image one we can assure one thing is that SHA-1 can be broken and its weaker than we thought. You can read more about it on Bruce Schneier article. On the other hand, you can find MANY MD5 cracker online nowadays through Google. eg. md5crack.com. But similarly they are all collision attacks or rainbow table. Wiki explains MD5 vulnerability in a way you will discourage using it. Its time to encrypt your users password using SHA-2 such as sha256, sha384, sha512 or better.

Hashing your password

If you are using PHP 5.12 or above, there is a new function, hash that supports SHA-2.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  hash(’sha1′,$phrase);
$sha256= hash(’sha256′,$phrase);
$sha384= hash(’sha384′,$phrase);
$sha512= hash(’sha512′,$phrase);

For people who are using PHP 5.12 and below, you can try to use mhash which is an open source class for PHP.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  base64_encode(bin2hex(mhash(MHASH_SHA1,$phrase)));
$sha256= base64_encode(bin2hex(mhash(MHASH_SHA256,$phrase)));
$sha384= base64_encode(bin2hex(mhash(MHASH_SHA384,$phrase)));
$sha512= base64_encode(bin2hex(mhash(MHASH_SHA512,$phrase)));

SHA-2 should be used to secure your future application. However MD5 and SHA-1 can still be use for authentication purpose with a very secure password combination. eg. (eQ@xC#Eif2dsa!e2cX2?"}23{D@.

NOTE**: NEVER DOUBLE HASH!

Double hashing is *worse* security than a regular hash. What you’re actually doing is taking some input $passwd, converting it to a string of exactly 32 characters containing only the characters [0-9][A-F], and then hashing *that*. You have just *greatly* increased the odds of a hash collision (ie. the odds that I can guess a phrase that will hash to the same value as your password).

sha1(md5($pass)) makes even less sense, since you’re feeding in 128-bits of information to generate a 256-bit hash, so 50% of the resulting data is redundant. You have not increased security at all.

Credit goes to Ghogilee

****updated on 8 Oct 09

On the note of Ghogilee, i found a few errors which i would like to point out. Double hashing here is referring to two different hash function.  It does reduce the search space but doesn't *greatly* increased the odds of a hash collision.  On the other hand, SHA-1 should be a 160-bit hash not 256-bit and not only does this doesn't increased the security but also weaken the hash function as the hacker will only required to crack the weaker hash function in this case md5.

If you wish to understand the risk and stuff you can do with hash function, please visit Enhance Security Hash Function For Web Development. Here i document the most detail hash function i could for your information.

Enhance Hashing With Salt

Once you have decide your secure password encryption algorithm, the last thing you might want is to have different user having the same cryptographic hash code in order to defend against rainbow attack. This can bring another problem of more than one account being compromised at the same time when there are multiple same hash and short password can easily be cracked with ease when your database and tables have been known. We can generate a salt in order to overcome this problem so that the string is longer and more random (providing that the salt + password are random enough).

define('SALT_LENGTH', 15);
function HashMe($phrase, &$salt = null)
{
$key = '!@#$%^&*()_+=-{}][;";/?<>.,';
    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).$key.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt . $key .  $phrase);
}

The above function contains two parameter. The first will take in a phrase and generate a SHA-2 salt only if the second parameter is placed with an empty variable. However, if both parameter contains values, it will be used when you wish to compare between two hashes. We can use the above method this way,

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$hashed_password = HashMe($password, $salt);
$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ("'.$username.'", "'.$hashed_password .'", "'.$salt.'") WHERE 1';
..

The above will insert the information into the table when user is being created. We will check the user with the following salt.

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$sqlquery = 'SELECT `salt`, `password` FROM  `usertable` WHERE `username` = "'.$username.'" limit 1';
..
#we get the data here and placed into variable $row
$salt = $row['salt'];
$hashed_password = HashMe($password, $salt);
if($hashed_password  == $row['password']){
#verified
}
else{
#ACCESS DENIAL
}
..

The objective of salt is to lengthen the password in the table and also creates totally random hash code for each password. Furthermore, a key is being placed in as hash value to protect the password as our SALT is placed in the table and if our table is compromised, the SALT will also be take into consideration in a rainbow table. Therefore, an additional key is required that is not placed within the table. This way, even if your table is being compromised, it will really takes a lot of time for them to crack those hashed password. As i mention earlier, database can be easily compromised due to employee or social engineering.

Summary

Many of us should start moving forward to new hash function rather than sticking on to MD5 and SHA-1. Although it is still secure for these two algorithm to be used given a strong password. Nonetheless, in the near future these two might not be that secure anymore. Furthermore, both algorithm had already been dropped by US and focus on SHA-2 instead. On the other hand, SALT can really help in many ways against social engineering and inside job attack. Its not all about Session attack, SQL Injection, XSS or XRSF nowadays.

Web File And Folder Permission – Security

I believe majority of us will have their website host on a shared environment as it is cheaper and more cost effective. Even if you have a dedicated server plan, the network administrator will not be 'automatic' enough to educate you about file and folder permission on your web environment. Your best bet is to approach them and discuss this topic hoping for a more secure environment through some dedication from your side (since all file and folder permission are managed by you instead of network administrator). But often we get standard answers from these network administrator who might not be very knowledgeable on this topic and you might ended up getting 'standard' answer from a predefined QnA text on their side. I believe everyone have certain knowledge on file and folder permission but in details what are the security risk we are facing if we ignore them? In this article, we will discuss them and hopefully get some idea and understanding on the security impact of file and folder permission in our web environment.

File and folder permission

Although many already know this, it is still a good practice to explain to those that are still new to file and folder permission. Personally, i think the best way to illustrate a file and folder permission is through a diagram. So i wrote out a sort of diagram like representative below,

  7       7     7
user   group  anyone
r+w+x  r+x    r+x
4+2+1  4+0+1  4+0+1  = 755

The permission mode is computed by adding up the following values for the user, the file group, and anyone.

  • Read 4 - Allowed to read files
  • Write 2 - Allowed to write/modify files
  • execute 1 - Read/write/delete/modify/directory

This will pretty much explain everything the diagram shows. So if we have chmod 777

  7       7     7
user   group  anyone
r+w+x  r+x+x  r+x+x
4+2+1  4+2+1  4+2+1  = 777

It is quite easy to understand what does the number means but how about each type of users?

  • User: it refers to the permission given to the owner of the file/folder.
  • Groups: it refers to the permission given to the group that was allocated to the file/folder
  • Anyone: basically refers to the permission given to outsider like normal visitors of a site

This should sum up the permission access you should give to a particular file or folder in a web environment.

What File and folder permission protect?

It is necessary to understand that file and folder permission protects only your file and folder (obvious). This means that other than files and folders, other stuff is unprotected such as databases.

Permission 777

Most likely majority of your file and folder will be set to permission 777 unless it is told otherwise. It is indeed dangerous to have everything set to permission 777 and might become a security risk. However, it is largely depends on whether your web server is being configure correctly. The main problem is that many server are not being configured correctly which is why users have to protect themselves through file and folder permission. (although permission also can act as another layer of protection for your file and folder). Is it safe for some directory to have permission 777? Yes, if you have a proper configure server. But you should be cautious and only give each folder or file with sufficient permission.

Why we need to set different permission

We will have to be cautious on the different level of permission permit for each type of user if we do not trust our network administrator on the configuration done to the server. The reason is that a hacker might hack into your system through a vulnerable web service on the server. However, the type of user the hacker get hold might not be the owner and having different permission level might just save yourself.

Type of damage

There are many types of damage a hacker might caused to your web environment. Assuming the same scenario happen which the hacker managed to get hold certain access which allows him to execute code as the user of the service. If a user neglect permission level (777 for all file and folder) and its server configuration is done poorly, an attacker can caused the sever damage to your system. Below listed some damage that could happen.

  • add/delete/modify any file or folder
  • implant virus or Trojan that will infect your visitors
  • Steal important information
  • Legal action might be make against you for poor security
  • implant bot
  • Etc.

Confusion on inherit of permission

Files do not inherit the permissions of the containing directory. This means that even though the uploads directory is executable, the files uploaded into it are not. (You should be explicitly setting the permissions for uploaded files in your upload script.) If the files are supposed to be read-only, don't hesitate to set them as 444.

Remove Execute permission

PHP files only have to have the execute bit set if you are running PHP in CGI mode. If you have PHP as an Apache module (mod_php), then it doesn't matter whether the files are executable or not.