I sat down with a friend today and spent a good 5 hours attempting to breach the security of an unnamed website. The website in question is a rather popular website with an Alexa ranking of just over 3,000. I've always been of the opinion that esoteric knowledge is only esoteric because the individuals wish to make it that way. Governmental procedures, for instance, are very esoteric. Unless you're actually there, the procedures are well over many individuals' head. If you can decipher the language used most people can understand it.
This is where I'd like to sit down with everyone at TalkPHP and explain in simple terms how I did it, the reasons why and what you can do to prevent this from happening to you.
Note: Although we successfully hacked the target site, no core information was gathered and no harmful information was injected. The administrators of the site were notified and advised on how to patch the vulnerability.
This breach of security involved the common security method, SQL injection. Now, I've used the unnamed site on numerous occasions for various reasons that I'm not going to mention. All perfectly innocuous. However, from using the website off and on I noticed many security issues that were arising from normal use. Today was the day I decided to put theory into practice.
I already had an account and so I attempted to login to my account using the following:
Username: Wildhoney Password: ' OR 1=1
What that essentially says is take the user name, Wildhoney, and then attempt to issue my own SQL. If you think that the normal query would be like so:
myUsername = 'Wildhoney'
myPassword = 'myPassword'
Then terminating the SQL just after the = ' would end the normal SQL and allow me to enter raw SQL commands. Thanks to our SQL injection the query would look like so:
myUsername = 'Wildhoney'
myPassword = '' OR 1=1
As you can clearly see from there, the SQL has been significantly modified to to make the end part of the SQL say the following in pseudo terms: AND the field myPassword equals NULLOR 1 equals 1. As 1 will always equal 1 we can successfully login.
However, on this website there is more code at the end of the SQL making our MySQL statement now make absolutely no sense. The solution for this is MySQL comments! A comment will comment out any code we do not want. In this case, the code after our OR 1=1. First up was the -- comment block. However, -- only comments single lines and after that didn't work we deduced the site must have been using multiple SQL lines. Step in /*. Once that had been issued MySQL ignored everything after our OR 1=1 and the login was successful.
Note: Although we logged into our own user name, absolutely any user name on the site could have been accessed.
I presume that many individuals are asking "why?". This wasn't a case of boosting our ego or bragging rights. Rather, education. Although we did a lot more after the login attempt, nothing harmless in the least, the login attempt is perhaps 1 of the most vulnerable part to any website and I felt was worth mentioning to everyone on TalkPHP to stop them making the same mistakes in their code.
For the login attempt, the code was not complex nor was it tricky to construct. We successfully logged into our account without specifying the correct password after about the 5th attempt. A little research was required before logging in but after that, the world is yours (Or, ours).
The way to protect yourself against something like that is just so simple. You should escape all single quotes, as well as check the data using a type specifier. See our article on sprintf. You may also wish to check for the encoding type - such as UTF-7 and UTF-8. Character encoding can cause so many issues with MySQL queries. These will certainly be covered in some depth on TalkPHP in the near future.
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.