•Re: Password hacker killer
by merlyn (Sage) on Sep 07, 2003 at 14:00 UTC
|
Because HTTP is stateless, there's no definite way to know that two hits are coming from exactly the same person (or even the same browser).
You could watch for many failed attempts from the same IP address, but that will get false positives on proxies, and false negatives from AOL or dialup customers. Definitely don't bother with cookies or referer: any bad guy worth their salt is going to strip those. In fact, it's trivial to construct a LWP-based bot that blows both of those off.
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply. | [reply] |
|
Because HTTP is stateless, there's no definite way to know that two hits are coming from exactly the same person (or even the same browser).
As you seem to know quite well, there are standard ways to add session functionalities to http. The client can of course perform a clean request at each time, by cleaning cookies and filtering out session parameters, but the same is true of stateful protocols. It is equally difficult to stop an attacker from performing repeated ftp/ssh/telnet login attempts., so I'd say that the statelessness of http is not the issue here.
Cheers
Antonio
The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
| [reply] |
|
HTTP is a stateless protocol, but it allows state via cookies and CGI parameters if both sides cooperate. The server already wants to cooperate, so you just have to provide an incentive to the client.
One way to do this would be to have a cookie that a person using the interface normally would receive, which tracks how many times they've tried to log in and makes them wait progressively longer or whatever else you want to do. The cookie would have to be secured in some way that would make it impossible for the client to just make one up, or to re-use an existing one. You could randomly generate cookie IDs and store them in a database, deleting them when they're used, or use cryptography to make this work (though no crytographic scheme comes immediately to mind).
Once you have a way of generating secure cookies, you can simply check if their cookie is valid, and if they don't present a valid cookie, you penalize them in a way that makes it very difficult to brute-force a password. sleep(30) would be a good penalty.
Something like this is what I'm thinking of (this is perl-like pseudocode):
if (!$login) {
&print_login_page; exit(0);
}
my($numtries)=check_cookie($cookie);
if ($numtries) {
$waittime = 5*($numtries-1);
} else {
$waittime = 30;
}
sleep($waittime);
if (check_pass($login,$password)) {
welcome(); exit(0);
} else {
set_cookie(numtries => $numtries+1);
bad_password(); exit(0);
}
You would enfoce the cookie's security in check_cookie and set_cookie.
| [reply] [d/l] [select] |
|
For several reasons, this is not a good solution to the problem:
First off, you penalize any valid users that want to log in for the first time.
Secondly, any attacker can just start up a bunch of requests at the same time (let's say 10 requests) and still get way more attempts per second. Try to stop that and you'll create a situation where your security system will probably become more convoluted and difficult to test (thus probably still not working correctly).
Anyways I'd go for matsmats++ solution, or go for full client SSL certificates if you can affort the trouble and money.
--
#!/usr/bin/perl -w
use strict;$;=
";Jtunsitr pa;ngo;t1h\$e;r. )p.e(r;ls ;h;a;c.k^e;rs
";$_=$;;do{$..=chop}while(chop);$_=$;;eval$.;
| [reply] [d/l] |
Re: Password hacker killer
by matsmats (Monk) on Sep 07, 2003 at 14:27 UTC
|
If your password is connected to a username, and said data is registered in a database - count the login attempts there. My favourite implementation of this is to double the response time from the server for every failed login-attempt on a username, slowing a brute force password guessing attack to a halt, but not necessarily bothering a regular user with throwing him out or something annoying like that.
Basically, as merlyn points out, you can't trust what is sent to you, so you have to connect the count of login tries to something you know is true. A username connected to the password would be most natural, I think.
Depending on the scale of what you're doing this for, an IP-adress check could be enough. The false negatives from AOL/dialups are not likely, I think (depending on the strength of your passwords) - and false positives from proxies could be taken care of by raising the number of allowed attempt to cover what goes as a expected count from said proxies. Not perfect, though.
| [reply] |
Re: Password hacker killer
by abell (Chaplain) on Sep 07, 2003 at 14:23 UTC
|
You can set a limit on the failed attempts coming from the same IP for a given user name.
Say that after three failed attempts in the same 10 minutes, login attempts for the given username from the same IP are rejected for one hour. This way a legitimate user would only be hurt if he made a mistake on his own password several times in a row, and an attacker wouldn't be able to DOS a user unless he were also able to spoof the user's IP address.
Cheers
Antonio
The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
| [reply] |
|
It's for this task that I wrote Tie::Scalar::Decay, which implements scalars whose values change over time. For each failed attempt, I would increment a scalar. Every N amount of time the value would decrease by F. But if the value went above a particular value, I would assume an attack was underway and take action. Those options can be tweaked so that a real user who's forgotten his password won't be locked out, but an automated password-guessing bot will be locked out.
Depending on your implementation, you may be able to use this module, but if you can't, then the basic idea of it is simple and should be easy to implement some other way. If you do have to reimplement it, I'd be glad to help or to accept suggestions or patches.
| [reply] |
Re: Password hacker killer
by Zaxo (Archbishop) on Sep 07, 2003 at 14:43 UTC
|
It's not suitable for all applications, but you can send failed logins to some innocuous page. Apache's ErrorDocument setting in .htaccess can be used for that. You can point that to a perl script which logs whatever you want to see and produces a joke, a stunt, or just something harmless which must be parsed to discover that a guess has failed.
That way you don't need a doomed effort to maintain state, as merlyn explained, in a stateless protocol. All you've done is make guesses more time-consuming and difficult. That's how passwords are supposed to work.
After Compline, Zaxo
| [reply] |
|
If you make it difficult to discover a guess has failed, but easy to discover it has succeeded, you haven't really gained anything. You'd have to make it hard to tell whether you were logged in succesfully, and I can't help but think that's bad user-interface design...
| [reply] |
Re: Password hacker killer
by liz (Monsignor) on Sep 07, 2003 at 14:31 UTC
|
I would definitely count the number of unsuccessful tries for a particular user. Then put in a sleep of one second for each unsuccessful try. So the first unsuccessful trye wil take 1 second, the second 2 etc. etc. This will at least slow the attack down, but may have turned it into a unwanted DoS attack if more attempts are made before the previous has returned its result..
So you would need to be a little smarter, by somehow flagging that a sleep after an unsuccessful attempt is occurring. And simply break the connection on any attempts being made while in a "sleep" period (as this indicates a parallel, and most likely programmed attack). If you find two or more parallel requests, I think you can safely assume you have an attack on your hands and appropriate actions (notifying admins, blocking IP number, etc) may be needed.
Of course, once the user properly supplies the password, reset the failed tries counter.
No code, just a principle course of action. Hope it helps.
Liz | [reply] |
Re: Password hacker killer
by davido (Cardinal) on Sep 07, 2003 at 20:06 UTC
|
How about this? (Just a thought that came to me. There may be problems with it, but then again, maybe it has some merit):
After three failed login attempts, send the user an email at his registered email address:
John Doe:
You have, or someone pretending to be you has attempted
to log into xxx.com unsuccessfully 3 or more times.
To provide you with the utmost in security, xxx.com has
put your account on a temporary hold. You may remove
this hold by logging in as follows.
The next time you log in (and that time only), use your
existing user name, plus the text, "+ZRYU3" (without
the quotes), appended to your username. Your password
should be entered in the usual fashion.
If the unsuccessful login was the result of forgetting
your password, click THIS LINK to have your registered
password hint emailed to you at this email address.
We are sorry for the inconvenience. If you have any
questions or need further assistance you may email
support at login-support@xxx.com.
Sincerely,
.....
I think the preceeding text pretty much explains the pholosophy. If three attempts fail, suspend until the user logs in with 'username+REY3Q', the suffix being a random set of ASCII characters known to be available on just about any keyboard; perhaps \w or \w\d.
Implementation wouldn't be terribly complex, and the only difficulty would be if users don't keep their email address up to date, or if they're too new to technology to understand the instructions.
If you're still concerned with a bot knowing about the suspension and trying to thwart it by guessing at the username alteration as well as the password, implement one of the $delay*=2; solutions for every guess at username. The delay still enables DOS attacks, but the attacker has to go an extra layer into the onion to accomplish the attack. And also, by adding an extra six unknown digits to the username, in addition to the already unknown password, you've made unauthorized access difficult enough that the attacker is likely to seek more fertile ground.
UPDATE: BrentDax suggested emailing a "...click on THIS LINK..." to the real user's email address. I think that's a fantastic modification to my original proposal, but believe that for those whos email clients don't support clickable links, and those whos email clients break links by mangling them in the process of wrapping text, it doesn't hurt to provide the "log in next time only username+random_stuff" as an alternate. There are people who simply can't click on a link in email and expect it to work right. The approach of enabling either option seems to be a good solution for those people.
Dave
"If I had my life to do over again, I'd be a plumber." -- Albert Einstein | [reply] [d/l] |
|
If you're going to do something like that, the key paragraph might as well be:
To remove the suspension, click on THIS LINK. You will then
be able to log in normally. If you have forgotten your
password, the link above will offer to e-mail your password
hint to you, or send you a new computer-generated password.
The "THIS LINK" would contain a randomly-generated code of some sort. This keeps people from having to deal with weird "add this to your username" type things.
=cut
--Brent Dax
There is no sig. | [reply] [d/l] |
Re: Password hacker killer
by calin (Deacon) on Sep 07, 2003 at 17:10 UTC
|
You can challenge the user with a so called Reverse Turing Test. It's basically a low quality and partially scrambled rendering of a random text or number (to prevent OCRing) that the user must interpret and submit back before being allowed to continue with the log-in procedure. See this paper for more info. | [reply] |
|
| [reply] |
|
Please enter the answer to the following question:
(number of days in a year) + (the hours in a day) + (the number of wis
+e men)
People friendly, computer not. At least it would stimulate growth in NLP and common sense bots :)
___________
Eric Hodges | [reply] [d/l] |
|
|
|
|
WOW! Thanks for the heads up, that could have bitten me in the butt hard... I had considered that for a system I am working on, guess that one goes off the drawing board now :)
Just goes to show, no matter how much you think out a solution, there is always something lurking around the corner that you just don't expect.
| [reply] |
Re: Password hacker killer
by allolex (Curate) on Sep 07, 2003 at 14:24 UTC
|
Use user-level authentication and limit the number of retries per user to something like four and then put a wait period between unsuccessful login series. So if someone makes four unsuccessful login attempts in a row, block the user account so that that user cannot log in for the next hour, no matter the password, or until you reset the account.
Also make sure your passwords are good in the first place. No dictionary words, no names (there are dictionaries for those, too). You could maybe use something like Data::Password, although I cannot personally vouch for it.
Good luck keeping them out.
--
Allolex
| [reply] |
|
This method leads the way for an effective DOS - if I want to prevent you from logging in, I just write a script that repeatedly tries to log in as you, with a wrong password. You won't be able to ever get at your account again.
You need to block at least only a certain IP address, then only AOL users can block AOL users ...
perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The
$d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider
($c = $d->accept())->get_request(); $c->send_response( new #in the
HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
| [reply] [d/l] |
|
| [reply] |
|
Re: Password hacker killer
by waswas-fng (Curate) on Sep 08, 2003 at 18:45 UTC
|
Some of the more complicated password/hacking blocking tools will do the following..
Keep a running database of:
- IP -> Username good auth
- IP -> Username bad auth
- Username -> Current session list
With these three time stamped pieces of information you can do the following:
- Test for repeated usernames with bad auths from one IP, and tag the IP as
a cracker for X minutes (you have to have a rolling target for this so you
can set the weight limit high enough to get few false blocks -- meaning 5 bad
user/pass combos with unique users in 30 seconds triggers a block while 5 bad
auths over 5 minutes does not.)
- Many same user bad auths with the same IP (or different as most password
cracking software will use huge proxy lists to hide the source of the attack)
can trigger a administrative lockout of the account --
You should give the user the ability to easily unlockout their account once
every
X minutes
via
another
form or
via customer support.
- Test for multiple good auths from different IP addresses with unique session
ids. This should take into account that the end user may have a few different
computers live on the site at once -- but there is no reason to see 15 active
sessions from 15 different IP addresses.
Just make these test flexible enough to allow for normal allowed use of the
site while catching blatant cracking attempts.
-Waswas
EDITED: Spelling mistakes fixed gogo dyslexia. | [reply] |
|
| [reply] |
|
| [reply] |
|
Test for multiple good auths from different IP addresses with unique session ids.
I think you missread this, this means unique username <waswas-fng> from random IP addresses each with their own session going. <br
User:IP:Session
waswas-fng:10.128.172.10:000001
waswas-fng:10.128.172.10:000002
waswas-fng:10.128.172.10:000003
waswas-fng:10.128.172.10:000004
waswas-fng:10.128.172.10:000005
waswas-fng:10.128.172.12:000005
waswas-fng:192.168.66.11:000004
Would be "OK"
Where:
User:IP:Session
waswas-fng:12.128.172.10:000001
waswas-fng:231.128.172.1:000002
waswas-fng:12.128.172.10:000003
waswas-fng:231.128.172.1:000004
waswas-fng:192.168.52.1:000005
Would show many users using the same account with unique sessions on different networks (shared password or hacked access).
-Waswas | [reply] [d/l] |
Re: Password hacker killer
by GermanHerman (Sexton) on Sep 09, 2003 at 00:55 UTC
|
From my experience building and block web robots and script kiddies the following have been the most effective:
An extremly complex cookie mechanism in a dynaic external javascript file
Cookies sent in with random images on the page
IP address tracking
Tracking what order your parameters come in on which broswers
Wheither or not they sent it as a post or a get.
Whether or not requests are coming in at regular intervals (if they are coming in at intervals less then 5 seconds then it is probably a robot of some kind.)
If the client has requested to logon under a vastly different user name.
If you are trying to keep people web web robots rfom downloading your entire site you can give people bandwidth
quotas (I think apache does this though I'm not sure)
Instead of sending the "he is logged on this is his id" cookie with the logged in page send it from a style sheet on that page.
All of these methods can be worked around (the ip tracking one being the hardest) but implementing a set of them could make someone thing twice about how hard they want your content.
-Douglas | [reply] |