

Exploit Information Leaks in Random Numbers from Python, Ruby and PHP - SODaniel
https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php

======
Xk
Those interested in this should look at a paper from Vern Paxon and Nicholas
Weaver:

<http://www.icir.org/vern/papers/witty-imc05.pdf>

A summary of it: A worm used a linear congenital generator to generate its
randomness. It used this generator to pick which IPs to try to infect, which
hard drives to write data to, and what to write. These researchers used a /8,
and were able to use that to count, exactly, the bandwith of all infected
machines, how many hard drives machines each had, the time they started up,
and locate the exact machine which initially spread the worm. It's really
quite amazing that you can get all of this from just packet captures, before
you think about it.

~~~
fx5
Very interesting, thank you for sharing.

------
tptacek
This is a pretty great post. We need lots more posts on practical exploit
development for RNG flaws, because there are a lot of bad random number
generators out there.

I want to respond to this headline, though. Use of MT as a CSPRNG is very,
very common in PHP applications. And it's also true that MT is the algorithm
used by Ruby for it's "rand". But this is not a very common Ruby flaw, at
least not like it is in PHP, because virtually every Ruby build provides an
explicit secure random number generator, either through OpenSSL or (more
commonly) through Rails' SecureRandom.

You should know that unless your RNG calls itself "secure" or "cryptographic"
--- like, _in the function name_ \--- you are using rand(), not a CSPRNG, and
you can't count on it for security ever. You will have the exact same problem
in most mainstream languages. Secure random number generators say they're
secure. Nobody says Ruby's rand() is secure.

(I'm pretty sure the same is true of Python, but I'm less confident of the
specifics. I think this is a very fair issue to raise with PHP in general,
though.)

~~~
Jabbles
Is there any advice you're able to give on how to distinguish situations where
you need secure RNG from those that don't matter?

For instance, you definitely need it in poker hand generation - would you need
it for random loot generation in an MMO?

Also by "secure" you mean /dev/random, and /dev/urandom is used as if it was
rand()?

~~~
tptacek
You should pretty much just default to secure random.

/dev/urandom is fine; in Ruby apps, I'd use OpenSSL::Random.random_bytes or
ActiveSupport::SecureRandom.random_number.

~~~
Jabbles
What cases do you reserve /dev/random for? SSH keygen?

Do those functions just read from /dev/urandom?

~~~
tptacek
I don't. Just use urandom.

------
praptak
I remember someone inferring the Nethack RNG state to show off on online
servers by dying three times in a row because of kicking a wand of wishing.
Here:

[http://taeb-nethack.blogspot.com/2009/03/predicting-and-cont...](http://taeb-
nethack.blogspot.com/2009/03/predicting-and-controlling-nethacks.html?m=1)

------
doe88
Indeed as the author rightfully mentioned in his article this method is not
designed for crypto purpose. One can use the following Python method instead
random.SystemRandom().randint(...)

~~~
gojomo
SystemRandom uses the system's urandom, which may not be ideal, either. (The
man page for urandom mentions theoretical problems when system entropy pools
are depleted.)

The PyCrypto.Random.random option mentioned in another thread by wulczer might
be better... but would love an authoritative recommendation from an expert.

~~~
tptacek
You should probably use your system urandom/random in preference to any
application-layer CSPRNG. Your OS developers are charged with maintaining a
high-profile high-value CSPRNG used for most applications on the system, and
vulnerabilities in it are a hair-on-fire problem. The same is not true of
application-layer replacements. The kernel RNG is also in a privileged
position to collect entropy.

~~~
wglb
And what about them new-fangled Intel random number generating instructions?

~~~
tptacek
You should trust that your OS will use them when it makes sense to use them.
:)

(I'm being glib.)

~~~
wglb
And I was being a bit silly.

------
cynwoody
Here's a hardware solution to the "pseudo" problem:
<http://gamesbyemail.com/News/DiceOMatic>

It's a dice-rollingmachine "that can belch a continuous river of dice down a
spiraling ramp, then elevate, photograph, process and upload almost a million
and a half rolls to the server a day. I may not get nominated for a Nobel
prize, but the deep rumbling vibration you feel more than hear when two rooms
away is quite impressive."

------
rarrrrrr
Worth it just for that video of the perfect game of Asteroids.

~~~
sp332
This one is even cooler, to me, since the ship flies around a lot more
[http://www.heise.de/video/artikel/Asteroids-Vladimir-
Bleifus...](http://www.heise.de/video/artikel/Asteroids-Vladimir-Bleifuss-
Panteleev-17-Platz-1573642.html)

------
jgrahamc
Funny, that someone did this. I wanted to implement something similar to check
that GCHQ weren't lying to me about this: [http://blog.jgc.org/2011/12/back-
channel-confirms-that-im-ri...](http://blog.jgc.org/2011/12/back-channel-
confirms-that-im-right.html) Essentially, I thought that it was possible that
this block of code was not what they actually used (partially because 0x7f did
not appear in the output).

I didn't do it because I had only 326 bytes of random material with 7 bits per
byte. Too little to recover the state.

~~~
marshray
Depends on how much state they seeded it with. It's pretty common for MT to be
seeded with 32 or less bits of entropy.

------
kdsudac
Interesting read. Realistically, to "know all the cards in online poker games"
wouldn't you also have to reverse engineer how they map the random number to a
card?

You would get a jack of hearts, not an integer between 1 and 52, right? or
does the exploit somehow work for arbitrary patterns as well?

~~~
jsaxton86
I think the author was alluding to the following:
[http://www.cigital.com/papers/download/developer_gambling.ph...](http://www.cigital.com/papers/download/developer_gambling.php)

------
antirez
A PRNG based on RC4 should be very fast but much more secure than a MT or a
LCG.

EDIT: also it is very important to seed with care if you are interested in
security. Even a strong PRNG seeded with seed_prng(time(NULL)) will be an easy
target for brute force attacks.

At least /dev/urandom should be used for seeding purposes in applications
where you need an unguessable PRNG.

~~~
carbocation
> At least /dev/urandom should be used for seeding purposes in applications
> where you need an unguessable PRNG.

I usually consume /dev/urandom and convert it to the base I require, using
that directly as my random number. When you say you should use it for seeding
purposes, are you referring to using /dev/urandom as a seed for something like
PHP's rand(), or do you mean something else?

~~~
tptacek
Seeding is largely a problem you have if you're building (or retrofitting in)
your own CSPRNG, which you shouldn't do. The random/urandom interface Unixes
provide will allow you to shovel in high-entropy data, but I think you're more
likely to do harm than good (it's a marginal impact in either direction,
though).

You're doing the right thing already.

~~~
carbocation
Aha, that makes sense. Thanks!

------
lelf
<http://news.ycombinator.com/item?id=639976>

~~~
tptacek
That post, which is great, is the normal way bad RNGs are broken by attackers:
you trace down how they're seeded and then brute force the seed values.

What's great about this blog post is that it attacks the underlying algorithm;
the post you linked to is more fun, but this post is a little more useful.

In either case: just use random/urandom and this stuff is taken care of for
you.

