Buggy debug output from nrpe since 2.1
Andreas Ericsson
ae at op5.se
Fri Feb 24 11:38:46 CET 2006
sean finney wrote:
> hi guys,
>
> On Thu, Feb 23, 2006 at 09:21:16PM +0100, Gerhard Lausser wrote:
>
>>Ethan, you applied my nrpe-2.3-allow_weak_random_seed patch to the 2.4
>>branch. Would you be so kind and add another line, which came to my mind
>>later? The results of the rand() calls in the last fallback might be
>>predictable, so seeding with the current time is necessary.
>>It's just a "srand(time(NULL));" after the syslog call. I attached a patch
>>file for the 1.42
>
>
> i'd like to advise against this, and maybe comment on a bit
> more on the use of random bits in nrpe.
>
> srand should really only be called once, and with a value that is as
> unpredictable as possible. instead of calling srand(time(NULL)), i
> might suggest something like the following:
>
> seed=(int)time(NULL)*311-getpid()*359+getppid()*383;
>
> which makes remote attacks on the prng more or less impossible, and local
> ones difficult at best. i'm not sure why you would need to call it
> multiple times.
>
Unfortunately it doesn't. It's possible to determine what a hosts system
clock is set to by either watching ntp traffic to/from the host (with
great accuracy), or by watching arbitrary packets sent from the host
(with less precision, but still accurate enough for a time() seeding).
Since the constants are known the integer overflowing is irrelevant for
all practical purposes.
For cracking the above seeding, one can take a wild guess that ppid is
one less than pid and do something like this:
guessed_seed = (sniffed_time - 1) * 42761567;
Multiplication takes precedence, remember?
If your omitting of parentheses was a mistake it makes the thing a bit
more computationally expensive, but not so much it's impossible using
any reasonably modern computer.
> also, nrpe currently reads a random byte from /dev/urandom for seeding
> it the first time. i'd like to point out that this means that the prng
> is seeded with a value that is strictly between 0 and 255 inclusive.
> that's not a very large search space for someone trying to crack
> something.
>
True. It would be far better to read a full int. For time-seeding it's
preferrable to xor-fold a timeval-struct into an int, like so:
gettimeofday(&tv);
sec = (int)(tv.tv_sec ^ tv.tv_sec >> (__WORDSIZE - 32));
usec = (int)(tv.tv_usec ^ tv.tv_usec >> (__WORDSIZE - 32));
seed = sec ^ usec;
It might be useful to throw in a clock() count there as well, since
those aren't so easily determined remotely.
> it also drains precious entropy from the system by reading from the
> random device.
You would have to read an exceedingly large data-set from the random
devices to drain it of entropy. The PRNG (in Linux at least) loops after
2^64 bytes unless the state is continuously and additively seeded (which
it is).
However, considering we're not transmitting passwords or anything people
would usually like to bend over backwards to keep secret, I'd say random
seeding isn't something to spend a lot of time on.
--
Andreas Ericsson andreas.ericsson at op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
More information about the Developers
mailing list