On Thu, Apr 5, 2012 at 6:51 AM, Otto Moerbeek <[email protected]> wrote:
> That sounds like timing bases attacks to guess a username still will work.
>
> -Otto
First thing I thought when reading your reply: absolute nonsense. With
that mindset I really wanted to disprove your suggestion. For this I
have set-up two different scenarios:
1.) Local 'attack' without use of getpwnam (plain-vanilla login_yubikey)
2.) Local 'attack' with use of getpwnam (altered version, read: with
applied diff)
Each scenario was run two times: one time targeting existing users and
one time targeting not existing users. I measured the time it took to
get a reply (accept / reject) after sending a password. Each test-run
was done a couple ten thousand times. I compared data from the two
test-runs within each scenario using a simple t-test. For scenario 1,
I found that the probability that one can guess that a user exist or
not is less than 0,00000014%. For scenario 2 the probability is less
than 0.0021%. Albeit the probability is small, it increased four
orders in magnitude.
In my own opinion I have failed to disprove your suggestion. I now can
imagine that somebody who has knowledge on the subject can derive
useful information as a result from the alteration to login_yubikey.
So, in a nutshell: I guess you are right!
>From the different diffs I've send in I learned that code needs to be
readable, regexp is a no-no and that the use of getpwnam is probably
not a good idea. I changed my first diff to reflect the above
learning's.
As I am out of alternative ideas: Opinions? / Alternatives? / Comments?
Index: login_yubikey.c
===================================================================
RCS file: /cvs/src/libexec/login_yubikey/login_yubikey.c,v
retrieving revision 1.4
diff -u -p -r1.4 login_yubikey.c
--- login_yubikey.c 1 Feb 2012 16:07:28 -0000 1.4
+++ login_yubikey.c 5 Apr 2012 10:53:57 -0000
@@ -165,10 +165,18 @@ main(int argc, char *argv[])
static int
clean_string(const char *s)
{
+ int nlim, n = 1;
+
+ nlim = strlen(s);
while (*s) {
- if (!isalnum(*s) && *s != '-' && *s != '_')
+ if (n == 1 && !isalnum(*s) && *s != '_')
+ return (0);
+ else if (n == nlim && !isalnum(*s) && *s != '_' && *s != '-')
+ return (0);
+ else if (!isalnum(*s) && *s != '_' && *s != '-' && *s != '.')
return (0);
++s;
+ ++n;
}
return (1);
}