How hackers hack your web login page and how to stop it.
Ground rules.
It's not legal to subvert other people's on-line accounts. The reason I am writing this is to inform you of one way how malicious crackers could get into your account. If you are a web designer or have employed someone to design your web site, then read this, do the quick test for vulnerability, then fix the hole. Do not attempt to crack other people's sites. My goal here is to educate the good people. The naughty ones already know this stuff. (Yes - you know who you are...)
The test...
The test is simple.
At your login/password entry, just put in a single quote mark and submit. If the web page returns an error because of broken source-code, then your site is probably vulnerable.
Note: More than 16 million Web severs use PHP.
Now I will explain why this could happen.
Why might this test work?
Quite often, the user name and password field are HTML forms, and behind that, either in the rendered web page or hidden on the server that you connected to, there will be some code. It might be PHP or JAVASCRIPT or similar.
Some languages use single quote marks as delimiters for parameters. A delimiter is like a punctuation mark for code. It separates terms and tokens and words etc. Many delimiters are unary which means that only one is required. Here is an example using a comma as a delimiter:
1,2,3,4,5,6
But quote-marks come in pairs. The first from the left turns a mode ON, and the next one turns it OFF.
Example using single quote marks;
123 456 'fred is tall' 789 'bill' 'ted 99'
If you count the ticks, there are always an even number. The tick marks "toggle" a mode. In the example above, the unary delimiter is a space. The space separates numbers and it's fine to do that because a space is not a number. But you can have spaces in strings like "fred is tall" and "ted 99". The quotes toggle between 'number mode' and 'string mode'
Your log-in code that checks the user name consists of code and parameters. This code could use quotes to toggle between code-execution mode and parameter mode like this:
if ( '$fredpassword' == '$password' ) then allow_access
The stuff that is not quoted is code and the stuff inside the quotes is data.
Here is the code only, each chunk on its own line for clarity:
if ( == ) then allow_access
and here are the parameters:
'$fredpassword' '$password'
The stuff between parentheses is called an expression. This is a mathematical statement. In this case, it's a test for equality. All it is doing is testing whether the password typed in is the same as fred's password.
The web-login form allows the user to enter ANY characters into $password. This is not the best idea because we can enter a character that is used to toggle code-mode. This scrambles the logic (syntax) and the interpreter throws an unexpected error which is usually spat onto the web page.
Here is an example of what the code might be interpreted as if you use a single quote as a password... (Let's assume fred's password is 'badcodeday'
if ( 'badcodeday' == ''' ) then allow_access
Note that there are now an ODD number of quote marks.
Now if we "parse" this into code and parameters, look what happens:
code: if ( ==
That's all the code there is now. So let's look at the parameters:
badcodeday ) then allow_access
This is clearly nonsense and it is why the interpreter throws an error.
So what if it throws an error?
Since we can type ANY characters in as a proposed password, we can also type code fragments. By being crafty, we can add code that maintains valid syntax and makes the expression evaluate to TRUE. If we can do that, then the modified code lets us in without knowing the password.
Some boolean logic:
A statement is something that can be evaluated to TRUE or FALSE. eg:
- All birds have have four wings. (FALSE)
- 0=0 (TRUE)
Now, even though 1. is false, we can combine these and maintain an OVERALL statement of TRUE.
(All birds have four wings) OR (0=0)
This is now a true statement because 0=0. When the interpreter evaluates a statement like this, it is following the Boolean logic truth table for an OR expression. It looks like this:
A B Q 0 0 0 0 1 1 1 0 1 1 1 1
'Q' is the TRUE/FALSE result where 1 represents TRUE. A and B are the results of two evaluated sub-statements. Every case is covered, and you can see that Q becomes 1 when either (or both) A OR B are 1. i.e. you only need to find ONE true statement in a string of OR joined statements to immediately decide the truth of the whole statement.
Knowing this, all we need to do is craft a new syntax and expression by manipulating what is in the password parameter.
![]() | Amazon Price: $75.00 List Price: $124.00 |
![]() | The Basics of Information Security: Understanding the Fundamentals of InfoSec in Theory and Practice Amazon Price: $18.55 List Price: $29.95 |
![]() | Amazon Price: $86.11 List Price: $120.00 |
![]() | Amazon Price: $48.99 |
![]() | Amazon Price: $18.00 List Price: $44.99 |
The hack
Here is the intended code
if ( '$fredpassword' == '$password' ) then allow_access
Let's ignore the content of fredpassword as we don't know it anyway, and craft a new statement that makes it irrelevant.
Type into the password field the following:
' OR '1
This makes the code look like this:
if ( '$fredpassword' == '' OR '1' ) then allow_access
This says, "If $fredpassword equals ''
(Which read, If fredspassword is nothing... This is FALSE but we don't care.)
OR
if 1
then allow access.
Well of course the expression '1' evaluates to true! That's what 1 means.
We could also use a sub expression like this
if ( '$fredpassword' == '' OR '0==0' ) then allow_access
It's basically the same idea. zero equals zero which is a true statement.
Or we could try:
if ( '$fredpassword' == '' OR '1>0' ) then allow_access
At least now we don't need to guess that equality is tested using the double = symbol. Most languages try to distinguish between a test for equality as == and an assignment = as in
b=4
where the value 4 is 'assigned' to the variable b. In contrast,
b==4
is a test to see whether b has the same value as 4.
Suhosin
Suhosin is an advanced protection system for PHP installations. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core.
Ok brainiac, how do I fix it?
There are a few ways.
You can install the Suhosin patch for PHP. This will harden against buffer overflows and sloppy programming.
One (outdated) way that might work is to make every character "literal". In unix, linux, perl, PHP, Python any many other languages, to embed a quote mark in a string, or any other special delimiter, you can make it literal by prepending a back slash.
Non-special characters that are "escaped" in this way are still interpreted normally.
Therefore, these two strings are equivalent:
fred == \f\r\e\d
And you would embed a quote mark inside a string like this:
'This \' is a quote mark'
When the parser sees the back slash it does not switch mode no matter what the next character is. The next character is taken as a literal.
Therefore, if you use a function to insert these back-slashes into the entered password field, the interpreter will not get broken by the single quote mark, and the hack is not applicable.
There is something called 'magic quotes' and is supplied by a function called stripslashes(). However, this "solution" is deprecated because of performance problems and incompatibility. It escapes EVERY character. In reality, you only need to escape the quotes.
Instead, you should call
mysql_real_escape_string()
The following characters are affected:
\x00 \n \r \ ' " \x1a
Alternatively and preferably as well, you can apply input-validation on every character typed into the web page.
As a character is entered, it is accepted or rejected depending on your rules. An input field for a date for example could use a mask like this:
dd/mm/yyyy , dd:{checkday()} , mm:{checkmonth} , yyyy:{checkyear}
This is a set of rules for data entry. dd is DAY of month, but since this varies month by month, we check it with a function called checkday and checkmonth. Only digits can be typed. i.e hitting the key H does nothing, neither does & or * or '
In this way, the input is guaranteed to be in good form BEFORE it gets used. You can use this technique on all input fields to define the input data to within expected and previously tested ranges. It's a safe way to program in general.
Useful links
Comments
Okay, I understood about half of that and was feeling fantastically intelligent, then realized my understanding was limited to only phrases but not to the whole, thus understanding nothing. But if I combine my nothing to my half will I be able to hack?
I will try the "" suggestion, assuming I understand what I'm doing.
Hi diogens & Jeff.
For those who have done any programming -- even a little, this should make sense. Many at this level are not aware of how a hacker/cracker thinks. But once you get into the groove, you can make more secure code.
For non-programmers: If you have a web site, then you can try your own site and enter a single quote mark for user name, password or both. Try all kinds of odd characters and see if any combination breaks the web page code. If so, you don't need to understand what's going on exactly -- just notify your webmaster and get it fixed.
Really interesting! Most of it is way over my head - I do sort of understand but ugh that is why I have someone like you come over and bullet proof my computers. I always wanted to be a hacker Manna, now I see why that will never happen:( lol! My friend would love to read this though - often he tries to explain this stuff to me, and I get lost in translation:)
I am going to make sure I figure out, with my computer guys help of course, how to protect my accounts! Thanks so much. I just had a friend who had her email account hacked - it is still an ongoing nightmare.
Can the hackers break into HubPages or FaceBook in this same way? Or do they use some other method. How do we protect our HP and FB accounts?
I'm going to get right on my domain account since it has been used extensively as a robot for spam.
I scrub all input and also limit its length to no more than what is appropriate for the task. Perl's "taint" mode can be helpful too (I do everything I can in Perl rather than PHP because PHP has had such a horrid security history).
Yeah, that's what I was talking about Pcunix:) !
Austinstar: Potentially. You are at the mercy of the security team at hubpages. This link: http://www.xssed.com/pagerank give you an incomplete list of high profile sites vulerable to XSS (Cross Site Scripting -- which is a special case of the code-injection example that I gave.) Note that google and yahoo have even been vulnerable but fixed the problem. I don't see hubpages on that list. It's a worry how many have apparently not fixed the vulnerability.
Pcunix: Right on!
RealHousewife: It's good too see consensus.
Having awareness is more important than a deep understanding. At least if you are aware you can alert your programmers. About 80% of web-hacks involve some form of XSS.
Very cool! I was only kidding @Pcunix:). I was pretending to be smart! Lol
I still think it's interesting and if I hadn't read this I sure wouldn't have known to ask the guy who takes care of my network issues to check, so thanks! I'm already wondering how quick he can get over here:)
There are tools to help. Like the scanning tool supplied here: https://download.hpsmartupdate.com/webinspect/
Thank you so much! I'm going to check that out.
I'm also chuckling about testing the computer guy with this! I wonder if he can keep up? Haha!
Great info, and what can you do to find out why a new account you just created with the used ID and password you just had confirmed ... refuses to let you in? :)
Thanks f_hruz
By far the most likely is you got the password or user id wrong. Leaving CAPS-LOCK on is common. You will need to request a password-reset.
Here is another testing tool.
Hi f_hruz,
You wrote
"Thanks for taking a crack at my question!
Since there was nothing wrong with either the user name nore the password ... and it worked ok a little while later without a reset, it may just have been a bit slow to create the entries in the flat file db to let me in - it's not using MySQL"
That's interesting.
Thanks for the tips.
I added a reference to the PHP hardening patch/extension called Suhosin.
Yikes. And I THOUGHT I was computer literate.
Wow fascinating...and useful. Manna, reading one your hubs is like trying to work out an extremely difficult puzzle.I'm sure it's good for my brain...:)
Thanks so much. I am Bookmarking this to study closely.
Thanks for the information. I have been hacked and don't want it to happen again.
I always knew about this in general terms, but now I understand the detail. You have a very clear and easily understood way of explaining your concepts.
Thank you for reading this SJKSJK (cool user name btw!)
Cheers Gary.
Really impressive write up. Keep up the great work!
rorshak sobchak





diogenes 13 months ago
Any article written in English that completely baffles me leaves me in awe. I hope other hubbers are more computer literate and understand this advice...Bob