

Multiple programming languages vulnerable to DoS via hash algorithm collision - kmfrk
http://www.ocert.org/advisories/ocert-2011-003.html

======
tptacek
This is a pretty old attack class. A great starting point for it is
Crosby/Wallach from 2003:

[http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec...](http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003/)

... but this was also one of Tim Newsham's (many) contributions to our joint
research project on IDS in '97:

<http://insecure.org/stf/secnet_ids/secnet_ids.html>

Glad to see it getting more attention. It seems to pop up every couple years.
(This might be the first generalization of the technique to arbitrary web
requests, which, yeah, will probably get _a lot_ more attention).

------
Groxx
An interesting technique - construct requests that produce pathological hashes
(which degrade to linked lists, which have O(n^2) insertions). Make it big
enough, and you tank the server. It may be useful to note their link to a
previous article, which implies this has been known since 2003 in Perl.[1] Any
news of actual attacks using this technique?

The great part is that, as long as you convert request params into hashes (a
reasonable step, I'd imagine the vast majority of web frameworks do this),
you're screwed if your language is vulnerable to this. Of course, you can
tweak your framework to not use native hashes (or detect such attacks and
handle them separately), but that's not generally an option as it's a pretty
involved operation.

I wonder: would a hashtable that uses cuckoo hashes be vulnerable?
Technically, sure, but would it make the attack infeasible due to the
difficulty in creating double-collisions? Or is that not as hard as I'm
thinking it could be?

[1]:
[http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec...](http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003.pdf)

~~~
ced
Isn't it trivially easy to defend against by adding a secret character/number
to all of your keys, eg.: "dog" becomes "dogu" and "julia" becomes "juliau"?

In fact, why not do this at the language level? python could pick a random
character at startup, and use it for the duration of the process.

~~~
mikeash
A single character wouldn't be any good, since it would be trivial to discover
which one was in use by brute force.

A longer salt would probably work, but there may well be ways for an attacker
to discover the salt in use, and longer salts mean more overhead.

~~~
obtu
A single pseudorandom byte chosen at container initialisation would work here,
because url hashes are ephemeral. Persistent structures on the other hand are
already DOS-prone, but need attacks more tailored to the application.

~~~
mikeash
Even with a random per-initialization byte, you could still brute force it.
Pick a random byte on your side, generate colliding keys with it, and send the
request. If it doesn't work, just try again until it does. You'd expect to
only have to try this ~256 times before succeeding, still seems pretty
practical.

Of course, bump this up to 2-4 bytes and it no longer is.

~~~
oconnore
256 attempts is the upper bound. The expected value of attempts should be 128.

------
jemfinch
This is precisely why I agree with C++'s choice of a balanced binary tree as
the default map implementation for its standard library. There's no denying
that in the vast majority of cases hashing is faster, but that's an
optimization, unnecessary except in a few specific instances, and while
balanced binary trees provide many other advantages in compensation for their
slight performance penalty: predictable performance (via non-amortized worst-
case bounds), minimized reallocation, insertion/deletion without invalidating
iterators, ordered iteration, range queries, and so on.

------
sonnym
This is the video from the technical demonstration and explanation:

<http://www.youtube.com/watch?v=R2Cq3CLI6H8>

------
radicalbyte
Although not listed, Microsoft's ASP.Net is also susceptable to this attack.

<http://www.theregister.co.uk/2011/12/28/ms_zero_day/>

------
pkteison
I'm late to the party, but I found the details interesting so thought I'd do
the best technical summary I could: An attacker precomputes a lot of different
values that hash to the same value, then posts them in a web request and it
eats CPU on an N^2 operation of processing the form variables due to its
hashtable now being N^2 since all hashes are the same. There are some
optimizations that make it easier than brute force to calculate collisions
against the hash algorithms in use by almost everybody today, see [1].

The interesting part is this is a precomputed attack which relies on hash
algorithms being well known and invariant.

Ruby has fixed this by initializing their hash function with a random seed
each time an app runs, so an attacker can't do the pre-compute step - a
collision calculated on his system won't necessarily be a collision on the
server. [2]

Other workarounds include limiting the size of post requests so the dictionary
can't get too big, limiting the CPU time available to a single web request, or
using a balanced tree instead of a hash table.

[1]: This is a great link on the problem:
<http://www.nruns.com/_downloads/advisory28122011.pdf>

[2]: Ruby's fix: <http://osdir.com/ml/ruby-talk/2009-05/msg00167.html>

~~~
kovyrin
Since there is no patch available for the latest Ruby Enterprise Edition,
we've made a quick port of the official ruby solution:
<http://kovyrin.net/2011/12/29/ree-hash-collision-patch/>

------
dchest
Lua isn't mentioned there, so I'd like to ask: since Lua interns every string,
isn't it vulnerable even if a framework doesn't put request parameters into
the table?

~~~
josephcooney
C#/.NET is also not mentioned. Clearly I'm out of touch, I hadn't realized
that Rubinius and JRuby were more popular than C# and VB.NET. Anyone have any
idea if/how .NET might be impacted by this?

~~~
Encosia
Vulnerable, but a patch is being released tomorrow night:
[http://weblogs.asp.net/scottgu/archive/2011/12/28/asp-net-
se...](http://weblogs.asp.net/scottgu/archive/2011/12/28/asp-net-security-
update-shipping-thursday-dec-29th.aspx)

~~~
ams6110
From that link: _On Dec 28th 2011, details were published at a security
conference describing a new method to exploit hash-table data-structures_

From what I've been reading, this sounds like something that's not new at all
and in fact has been an open vulnerability for years.

------
adrianpike
So I'm digging around in the Rack source right now trying to see what's up, I
haven't seen anywhere that it doesn't just rely on the native Ruby Hash class.

Does anybody closer to the matter know if Rack's actually vulnerable in 1.9?

~~~
rmoriz
As far as I understand, Rack is not vulnerable unless the underlaying Ruby
interpreter is vulnerable, like old 1.8, Rubinius, older JRuby.

Rack introduced a workaround in
[https://github.com/rack/rack/commit/5b9d09a81a9fdc9475f0ab00...](https://github.com/rack/rack/commit/5b9d09a81a9fdc9475f0ab0095cb2a33bf2a8f91)

this may help in some cases when an interpreter fix is not
available/installable but not fix the hashing problem in general, especially
outside of POST params.

------
privacyguru
Emergency out-of-cycle Patch being issued today by Microsoft:

[http://www.securityweek.com/microsoft-issue-emergency-fix-
ad...](http://www.securityweek.com/microsoft-issue-emergency-fix-address-hash-
collision-attack-vulnerability-thursday)

------
draegtun
Related to this earlier HN post: <http://news.ycombinator.com/item?id=3401254>

