Hash-flooding DoS reloaded:   attacks and defenses    Jean-Philippe Aumasson, Kudelski GroupDaniel J. Bernstein, Universit...
Hash-flooding DoS reloaded:   attacks and defenses    Jean-Philippe Aumasson, Kudelski GroupDaniel J. Bernstein, Universit...
Jean-PhilippeCryptography expert at the Kudelski GroupApplied crypto researcherhttps://131002.net @aumassonMartinIndepende...
Hash-flooding DoS reloaded:   attacks and defenses
Denial-of-Service (DoS) attacks“Attempt to make a machine or networkresource unavailable to its intended users.”Wikipedia
Popular DoS techniques are distributedHTTP or TCP SYN flood… (DDoS)
More subtle techniques exploit propertiesof TCP-congestion-avoidance algorithms…
Hash-flooding DoS reloaded:   attacks and defenses
Hash tables used in many applications tomaintain an association between objectsExample: Python dictionariesd={}           ...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes       O(...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes       O(...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes       O(...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes       O(...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes    O(n2)...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes    O(n2)...
If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes    O(n2)...
Hash flooding:Send to a server many inputs with asame hash (a multicollision) so as to  enforce worst-case insert time
send 2MB of POST data consisting of   200.000 colliding 10B strings≈ 40.000.000.000 string comparisons (at least 10s on a ...
Previous workCrosby, Wallach. Denial of Service via AlgorithmicComplexity Attacks, USENIX Security 2003-> attack formalize...
Previous workCrosby, Wallach. Denial of Service via AlgorithmicComplexity Attacks, USENIX Security 2003-> attack formalize...
Patches released consisting of astronger hash with randomization(to make colliding values impossible to find)
MurmurHash2“used in code by Google, Microsoft,     Yahoo, and many others”  http://code.google.com/p/smhasher/wiki/MurmurH...
MurmurHash3“successor to MurmurHash2”   Oracle’s Java SE, Rubinius
Hash-flooding DoS reloaded:   attacks and defenses
1. Theory
MurmurHash3 coreProcesses the input per blocks of 4 bytesfor (i=0;i<nblocks;i++) {    uint32_t k1 = getblock(blocks, i);  ...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference wit...
M1            M2              32-bit  32-bit                       h1=f(X)=H                   h1=X           M1^D1       ...
M1       M2               M3   M4               M5   M6              collision             collision         collision    ...
A multicollision works for any seed         => “Universal” multicollisionsh1=seed;for (i=0;i<nblocks;i++) {     uint32_t k...
Even simpler for MurmurHash2
Consequence:Systems using MurmurHash2/3 remain     vulnerable to hash-flooding
Other hash attacked
Even weaker than MurmurHash2…   Also vulnerable to hash flooding
CityHash64(   BU9[85WWp/ HASH!,   16   )   =   b82e7612e6933d2fCityHash64(   8{YDLn;d.2 HASH!,   16   )   =   b82e7612e693...
2. Practice
Breaking Murmur:     We‘ve got the recipe –Now all we need is the (hash) cake
Where are hashes used?
Internally vs. Externally
Parser symbol tables    Method lookup tablesAttributes / Instance variables         IP Addresses        Transaction IDs   ...
=> Where aren’t they used?
Can’t we use something different?
We could,but amortized constant time is just too sexy
Possible real-life attacks
Attack internal use?
Elegant, but low impact
Need a high-profile target
Web Application
Example #1   Rails
First:Attacking MurmurHash in Ruby
Straight-forward with a few quirks
Apply the recipe
Demo
Should work with Rails out of the box, no?
Unfortunately, no
Demo
def POST  …  @env["rack.request.form_hash"] = parse_query(form_vars)  …end
def parse_query(qs) Utils.parse_nested_query(qs)end
def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).e...
def unescape(s, encoding = Encoding::UTF_8) URI.decode_www_form_component(s, encoding)end
def self.decode_www_form_component(str, enc=Encoding::UTF_8) raise ArgumentError, "invalid %-encoding (#{str})"       unle...
/A[^%]*(?:%hh[^%]*)*z/           ???
Catches invalid % encodings(e.g. %ZV, %%1 instead of %2F)
def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).e...
def normalize_params(params, name, v = nil) name =~ %r(A[[]]*([^[]]+)]*) k = $1 ||   …end
%r(A[[]]*([^[]]+)]*)           ???
helps transform [[]] to []
idea:pre-generate matching values
create random valuespassing the regular expressions
that should do it, right?
Demo
def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).e...
class KeySpaceConstrainedParamsdef []=(key, value) @size += key.size if key && !@params.key?(key) raise RangeError, exceed...
What now? Rails is safe?
Remember:Hashes are used everywhere
So ifapplication/x-www-form-urlencoded     doesnt work, how about         application/json                ?
Again, with the encoding...
Fast-forward...
Demo
ConclusionPatchwork is not helping
too many places
code bloat
yet another loophole will be found
Fix it         at theroot
Example #2   Java
String(byte[] bytes)
public String(byte bytes[], int offset, int length,              Charset charset) {…char[] v = StringCoding.decode(charset...
Tough nut to crack
What now? Java is safe?
String(char[] value)
public String(char value[]) {    int size = value.length;    this.offset = 0;    this.count = size;    this.value = Arrays...
No decoding!
Substitute byte[] operationswith equivalent operations         on char[]
Demo
Disclosure    Oracle (Java): Sep 11CRuby, JRuby, Rubinius: Aug 30
Hash-flooding DoS reloaded:   attacks and defenses
SipHash: a fast short-input PRFNew crypto algorithm to fix hash-flooding:• Rigorous security requirements and analysis• Sp...
SipHash initialization256-bit state v0 v1 v2 v3128-bit key k0 k1v0 = k0 ⊕ 736f6d6570736575v1 = k1 ⊕ 646f72616e646f6dv2 = k...
SipHash initialization256-bit state v0 v1 v2 v3128-bit key k0 k1v0 = k0 ⊕ “somepseu”v1 = k1 ⊕ “dorandom”v2 = k0 ⊕ “lygener...
SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m0c iterations of SipRoundv0 ⊕= m0
SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m1c iterations of SipRoundv0 ⊕= m1
SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m2c iterations of SipRoundv0 ⊕= m2
SipHash compressionMessage parsed as 64-bit words m0, m1, …Etc.
SipRound
SipHash finalizationv2 ⊕= 255d iterations of SipRoundReturn v0 ⊕ v1 ⊕ v2 ⊕ v3
SipHash-2-4 hashing 15 bytes
Family SipHash-c-dFast proposal: SipHash-2-4Conservative proposal: SipHash-4-8Weaker versions for cryptanalysis:SipHash-1-...
Proof of simplicityJune 20: paper published onlineJune 28: 18 third-party implementationsC (Floodyberry, Boßlet, Neves); C...
Who is using SipHash?http://www.opendns.com/   http://www.rust-lang.org/       Soon?
Take home message• DoS is doable with only small data/bandwidth• Java- and Ruby-based web applications  vulnerable to DoS ...
Hash-flooding DoS reloaded:   attacks and defenses         THANK YOU!
ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet
ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet
ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet
ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet
Upcoming SlideShare
Loading in …5
×

ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet

1,331 views

Published on

At 28c3, Klink and Waelde demonstrated that a number of technologies (PHP, .NET, Ruby, Java, etc.) remained vulnerable to the decade-old hash-flooding DoS attacks. These attacks work by enforcing worst-case insert time in hash tables by sending many inputs hashing to the same value (a “multicollision”). Many vendors fixed the issue by replacing the weak deterministic hash function with stronger and randomized hash functions. In this presentation, we will show examples of such stronger randomized hash functions that fail to protect against hash-flooding, by presenting “universal multicollision” attacks based on differential cryptanalysis techniques. We will present demos showing how to exploit these attacks to DoS a Ruby on Rails application, as well as the latest Java OpenJDK; two technologies that chose to “fix” hash-flooding by using the MurmurHash hash functions. Finally, we will describe a reliable fix to hash-flooding with the SipHash family of pseudorandom functions: SipHash provides the adequate cryptographic strength to mitigate hash-flooding, yet is competitive in performance with the non-cryptographic hashes.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,331
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

ASFWS 2012 - Hash-flooding DoS reloaded: attacks and defenses par Jean-Philippe Aumasson / Martin Boßlet

  1. 1. Hash-flooding DoS reloaded: attacks and defenses Jean-Philippe Aumasson, Kudelski GroupDaniel J. Bernstein, University of Illinois at Chicago Martin Boßlet, freelancer
  2. 2. Hash-flooding DoS reloaded: attacks and defenses Jean-Philippe Aumasson, Kudelski GroupDaniel J. Bernstein, University of Illinois at Chicago Martin Boßlet, freelancer
  3. 3. Jean-PhilippeCryptography expert at the Kudelski GroupApplied crypto researcherhttps://131002.net @aumassonMartinIndependent SW engineer and security expertRuby core dev team memberhttp://www.martinbosslet.de @_emboss_
  4. 4. Hash-flooding DoS reloaded: attacks and defenses
  5. 5. Denial-of-Service (DoS) attacks“Attempt to make a machine or networkresource unavailable to its intended users.”Wikipedia
  6. 6. Popular DoS techniques are distributedHTTP or TCP SYN flood… (DDoS)
  7. 7. More subtle techniques exploit propertiesof TCP-congestion-avoidance algorithms…
  8. 8. Hash-flooding DoS reloaded: attacks and defenses
  9. 9. Hash tables used in many applications tomaintain an association between objectsExample: Python dictionariesd={} # empty tabled[12345]=0xc # insertiond[‘astring’]=‘foo’ # insertiond[(‘a’,‘tuple’)]=0 # insertionprint d[‘a string’] # lookup
  10. 10. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n) operations on average
  11. 11. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n) operations on average 0 1 2 12345: 0xcd[12345]=0xc, hash(12345)=1
  12. 12. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n) operations on average 0 1 2 ‘astring’: ‘foo’ 12345: 0xcd[‘astring’]=‘foo’ , hash(‘astring’)=0
  13. 13. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n) operations on average 0 1 2 ‘astring’: ‘foo’ 12345: 0xc (‘a’,’tuple’): 0d[(‘a’,’tuple’)=0; hash((‘a’,’tuple’))=2
  14. 14. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n2) operations in the worst case 0 1 2 12345: 0xcd[12345]=0xc, hash(12345)=1
  15. 15. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n2) operations in the worst case 0 1 2 12345: 0xc ‘astring’: ‘foo’d[‘astring’]=‘foo’ , hash(‘astring’)=0
  16. 16. If the table is about as large as thenumber of elements to be stored (=n),insertion or lookup of n elements takes O(n2) operations in the worst case 0 1 2 12345: 0xc ‘astring’: ‘foo’ (‘a’, ‘tuple’): ‘foo’d[(‘a’,’tuple’)=0; hash((‘a’,’tuple’))=2
  17. 17. Hash flooding:Send to a server many inputs with asame hash (a multicollision) so as to enforce worst-case insert time
  18. 18. send 2MB of POST data consisting of 200.000 colliding 10B strings≈ 40.000.000.000 string comparisons (at least 10s on a 2GHz machine…)
  19. 19. Previous workCrosby, Wallach. Denial of Service via AlgorithmicComplexity Attacks, USENIX Security 2003-> attack formalized and applied to Perl, Squid, etc.Klink, Wälde. Efficient Denial of Service Attacks onWeb Application Platforms. CCC 28c3-> application to PHP, Java, Python, Ruby, etc.
  20. 20. Previous workCrosby, Wallach. Denial of Service via AlgorithmicComplexity Attacks, USENIX Security 2003-> attack formalized and applied to Perl, Squid, etc.Klink, Wälde. Efficient Denial of Service Attacks onWeb Application Platforms. CCC 28c3-> application to PHP, Java, Python, Ruby, etc.
  21. 21. Patches released consisting of astronger hash with randomization(to make colliding values impossible to find)
  22. 22. MurmurHash2“used in code by Google, Microsoft, Yahoo, and many others” http://code.google.com/p/smhasher/wiki/MurmurHash CRuby, JRuby
  23. 23. MurmurHash3“successor to MurmurHash2” Oracle’s Java SE, Rubinius
  24. 24. Hash-flooding DoS reloaded: attacks and defenses
  25. 25. 1. Theory
  26. 26. MurmurHash3 coreProcesses the input per blocks of 4 bytesfor (i=0;i<nblocks;i++) { uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  27. 27. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  28. 28. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=0 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D1 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; diff in k1:0x00040000 h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  29. 29. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=0 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D1 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; diff in k1:0x00040000 h1 ^= k1; diff in h1 0x00040000 h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  30. 30. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=0 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D1 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; diff in k1:0x00040000 h1 ^= k1; diff in h1 0x00040000 h1 = ROTL32 ( h1 ,13); 0x80000000 h1 = h1 *5+0 xe6546b64;} 0x80000000
  31. 31. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=1 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D2 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  32. 32. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=1 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D2 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; diff in k1:0x80000000 h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  33. 33. Differential cryptanalysis strategy1/ introduce a difference in the state h1 via the input k12/ cancel this difference with a second well chosen differencefor (i=0;i<nblocks;i++) { i=1 uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; inject difference D2 k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; diff in k1:0x80000000 diff in h1: 0x80000000 ^ 0x80000000 = 0 h1 ^= k1; h1 = ROTL32 ( h1 ,13); COLLISION! h1 = h1 *5+0 xe6546b64;}
  34. 34. M1 M2 32-bit 32-bit h1=f(X)=H h1=X M1^D1 M2^D2 32-bit 32-bit h1=f(X^D3^D3)=H h1=X^D32 colliding 8-byte inputs
  35. 35. M1 M2 M3 M4 M5 M6 collision collision collision Chain collisions => multicollisions 8n bytes => 2 n colliding inputs
  36. 36. A multicollision works for any seed => “Universal” multicollisionsh1=seed;for (i=0;i<nblocks;i++) { uint32_t k1 = getblock(blocks, i); k1 *= 0xcc9e2d51 ; k1 = ROTL32(k1 ,15); k1 *= 0x1b873593; // transform of k1 independent of the seed! h1 ^= k1; h1 = ROTL32 ( h1 ,13); h1 = h1 *5+0 xe6546b64;}
  37. 37. Even simpler for MurmurHash2
  38. 38. Consequence:Systems using MurmurHash2/3 remain vulnerable to hash-flooding
  39. 39. Other hash attacked
  40. 40. Even weaker than MurmurHash2… Also vulnerable to hash flooding
  41. 41. CityHash64( BU9[85WWp/ HASH!, 16 ) = b82e7612e6933d2fCityHash64( 8{YDLn;d.2 HASH!, 16 ) = b82e7612e6933d2fCityHash64( d+nkK&t?yr HASH!, 16 ) = b82e7612e6933d2fCityHash64( {A.#v5i]V{ HASH!, 16 ) = b82e7612e6933d2fCityHash64( FBC=/hJeA!HASH!, 16 ) = b82e7612e6933d2fCityHash64( $03$=K1.-H!HASH!, 16 ) = b82e7612e6933d2fCityHash64( 3oLPiw!HASH!, 16 ) = b82e7612e6933d2fCityHash64( duDu%qaUS@"HASH!, 16 ) = b82e7612e6933d2fCityHash64( IZVo|0S=BX"HASH!, 16 ) = b82e7612e6933d2fCityHash64( X2V|P=<u,=#HASH!, 16 ) = b82e7612e6933d2fCityHash64( 9<%45yG]qG#HASH!, 16 ) = b82e7612e6933d2fCityHash64( 6?4O:<Vho#HASH!, 16 ) = b82e7612e6933d2fCityHash64( 2u 2}7g^>3$HASH!, 16 ) = b82e7612e6933d2fCityHash64( kqwnZH=cKG$HASH!, 16 ) = b82e7612e6933d2fCityHash64( Nl+:rtvw}K$HASH!, 16 ) = b82e7612e6933d2fCityHash64( s/pI!<5u*]$HASH!, 16 ) = b82e7612e6933d2fCityHash64( f|P~n*<xPc$HASH!, 16 ) = b82e7612e6933d2fCityHash64( Cj7TCG|G}}$HASH!, 16 ) = b82e7612e6933d2fCityHash64( a4$>Jf3PF%HASH!, 16 ) = b82e7612e6933d2f
  42. 42. 2. Practice
  43. 43. Breaking Murmur: We‘ve got the recipe –Now all we need is the (hash) cake
  44. 44. Where are hashes used?
  45. 45. Internally vs. Externally
  46. 46. Parser symbol tables Method lookup tablesAttributes / Instance variables IP Addresses Transaction IDs Database Indexing Session IDs HTTP Headers JSON RepresentationURL-encoded POST form data Deduplication (HashSet) A* search algorithm Dictionaries …
  47. 47. => Where aren’t they used?
  48. 48. Can’t we use something different?
  49. 49. We could,but amortized constant time is just too sexy
  50. 50. Possible real-life attacks
  51. 51. Attack internal use?
  52. 52. Elegant, but low impact
  53. 53. Need a high-profile target
  54. 54. Web Application
  55. 55. Example #1 Rails
  56. 56. First:Attacking MurmurHash in Ruby
  57. 57. Straight-forward with a few quirks
  58. 58. Apply the recipe
  59. 59. Demo
  60. 60. Should work with Rails out of the box, no?
  61. 61. Unfortunately, no
  62. 62. Demo
  63. 63. def POST … @env["rack.request.form_hash"] = parse_query(form_vars) …end
  64. 64. def parse_query(qs) Utils.parse_nested_query(qs)end
  65. 65. def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| k, v = p.split(=, 2).map { |s| unescape(s) } normalize_params(params, k, v) end return params.to_params_hashend
  66. 66. def unescape(s, encoding = Encoding::UTF_8) URI.decode_www_form_component(s, encoding)end
  67. 67. def self.decode_www_form_component(str, enc=Encoding::UTF_8) raise ArgumentError, "invalid %-encoding (#{str})" unless /A[^%]*(?:%hh[^%]*)*z/ =~ str str.gsub(/+|%hh/, TBLDECWWWCOMP_).force_encoding(enc)end
  68. 68. /A[^%]*(?:%hh[^%]*)*z/ ???
  69. 69. Catches invalid % encodings(e.g. %ZV, %%1 instead of %2F)
  70. 70. def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| k, v = p.split(=, 2).map { |s| unescape(s) } normalize_params(params, k, v) end return params.to_params_hashend
  71. 71. def normalize_params(params, name, v = nil) name =~ %r(A[[]]*([^[]]+)]*) k = $1 || …end
  72. 72. %r(A[[]]*([^[]]+)]*) ???
  73. 73. helps transform [[]] to []
  74. 74. idea:pre-generate matching values
  75. 75. create random valuespassing the regular expressions
  76. 76. that should do it, right?
  77. 77. Demo
  78. 78. def parse_nested_query(qs, d = nil) params = KeySpaceConstrainedParams.new (qs || ).split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| k, v = p.split(=, 2).map { |s| unescape(s) } normalize_params(params, k, v) end return params.to_params_hashend
  79. 79. class KeySpaceConstrainedParamsdef []=(key, value) @size += key.size if key && !@params.key?(key) raise RangeError, exceeded available parameter key space‘ if @size > @limit @params[key] = valueendend
  80. 80. What now? Rails is safe?
  81. 81. Remember:Hashes are used everywhere
  82. 82. So ifapplication/x-www-form-urlencoded doesnt work, how about application/json ?
  83. 83. Again, with the encoding...
  84. 84. Fast-forward...
  85. 85. Demo
  86. 86. ConclusionPatchwork is not helping
  87. 87. too many places
  88. 88. code bloat
  89. 89. yet another loophole will be found
  90. 90. Fix it at theroot
  91. 91. Example #2 Java
  92. 92. String(byte[] bytes)
  93. 93. public String(byte bytes[], int offset, int length, Charset charset) {…char[] v = StringCoding.decode(charset, bytes, offset, length);…}
  94. 94. Tough nut to crack
  95. 95. What now? Java is safe?
  96. 96. String(char[] value)
  97. 97. public String(char value[]) { int size = value.length; this.offset = 0; this.count = size; this.value = Arrays.copyOf(value, size);}
  98. 98. No decoding!
  99. 99. Substitute byte[] operationswith equivalent operations on char[]
  100. 100. Demo
  101. 101. Disclosure Oracle (Java): Sep 11CRuby, JRuby, Rubinius: Aug 30
  102. 102. Hash-flooding DoS reloaded: attacks and defenses
  103. 103. SipHash: a fast short-input PRFNew crypto algorithm to fix hash-flooding:• Rigorous security requirements and analysis• Speed competitive with that of weak hashesPeer-reviewed research paper (A., Bernstein).published at DIAC 2012, INDOCRYPT 2012
  104. 104. SipHash initialization256-bit state v0 v1 v2 v3128-bit key k0 k1v0 = k0 ⊕ 736f6d6570736575v1 = k1 ⊕ 646f72616e646f6dv2 = k0 ⊕ 6c7967656e657261v3 = k1 ⊕ 7465646279746573
  105. 105. SipHash initialization256-bit state v0 v1 v2 v3128-bit key k0 k1v0 = k0 ⊕ “somepseu”v1 = k1 ⊕ “dorandom”v2 = k0 ⊕ “lygenera”v3 = k1 ⊕ “tedbytes”
  106. 106. SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m0c iterations of SipRoundv0 ⊕= m0
  107. 107. SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m1c iterations of SipRoundv0 ⊕= m1
  108. 108. SipHash compressionMessage parsed as 64-bit words m0, m1, …v3 ⊕= m2c iterations of SipRoundv0 ⊕= m2
  109. 109. SipHash compressionMessage parsed as 64-bit words m0, m1, …Etc.
  110. 110. SipRound
  111. 111. SipHash finalizationv2 ⊕= 255d iterations of SipRoundReturn v0 ⊕ v1 ⊕ v2 ⊕ v3
  112. 112. SipHash-2-4 hashing 15 bytes
  113. 113. Family SipHash-c-dFast proposal: SipHash-2-4Conservative proposal: SipHash-4-8Weaker versions for cryptanalysis:SipHash-1-0, SipHash-2-0, etc.SipHash-1-1, SipHash-2-1, etc.Etc.
  114. 114. Proof of simplicityJune 20: paper published onlineJune 28: 18 third-party implementationsC (Floodyberry, Boßlet, Neves); C# (Haynes)Cryptol (Lazar); Erlang, Javascript, PHP (Denis)Go (Chestnykh); Haskell (Hanquez)Java, Ruby (Boßlet); Lisp (Brown); Perl6 (Julin)
  115. 115. Who is using SipHash?http://www.opendns.com/ http://www.rust-lang.org/ Soon?
  116. 116. Take home message• DoS is doable with only small data/bandwidth• Java- and Ruby-based web applications vulnerable to DoS (and maybe others…)• SipHash offers both security and performance Contact us if you need to check your application
  117. 117. Hash-flooding DoS reloaded: attacks and defenses THANK YOU!

×