Upgrade to Pro — share decks privately, control downloads, hide ads and more …

All in the Timing: Side-Channel Attacks

All in the Timing: Side-Channel Attacks

Here, you’ll learn about a category of security issue known as side channel attacks. You’ll be amused to see how features like automatic data compression, short-circuit execution, and deterministic hashing can be abused to bypass security systems. No security background knowledge is required.

“Never write your own cryptography!” is an oft-heard cry in the computer security space. But why is that? In this talk, we’ll cover some of the ways you can write software using algorithms and approaches that are mathematically perfect, but which, due to implementation artifacts, leave your applications exposed.

We’ll start with the mother of all timing attacks, password forms and non-constant time, to give the audience a foundation on what timing attacks are. From there, we’ll explore real-world attacks in the KeyCzar library, the BREACH attack, and PYTHONHASHSEED. All examples will show python code or pseudocode where appropriate, and will be abased on real-world attacks.

We’ll finish with a discussion of Spectre, a recent class of side channel attack that required patches and reboots across the majority of computers on the web – including the complete reboot of many cloud providers.

Our hope is that the audience will come away with a clearer understanding of this corner of the world of computer security, and will have a better answer to “Why shouldn’t I build my own cryptography software?”

Philip James

August 25, 2018
Tweet

More Decks by Philip James

Other Decks in Technology

Transcript

  1. 2,821,109,907,456 combinations = ~89 years p a s s w

    o r d _ _ _ _ _ _ _ _ 36 36 36 36 36 36 36 36
  2. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  3. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  4. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  5. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  6. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  7. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  8. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  9. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  10. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  11. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  12. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  13. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  14. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  15. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  16. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  17. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  18. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  19. m a s s w o r d p a

    s s 1 2 3 4 p a s s w o r d p a s s w o r d
  20. 144 tries 18 + 18 + 18 + 18 +

    18 + 18 + 18 + 18
  21. 144 tries 18 + 18 + 18 + 18 +

    18 + 18 + 18 + 18 = 144ms
  22. 0 1 2 3 4 5 6 7 8 9

    1 2 3 4 5 6
  23. In [1]: password = 'password' In [2]: %timeit 'massword'.encode('utf-8') ==

    password.encode('utf-8') 306 ns ± 3.65 ns per loop (…) In [3]: %timeit 'pass1234'.encode('utf-8') == password.encode('utf-8') 314 ns ± 4.5 ns per loop (…) In [4]: %timeit 'password'.encode('utf-8') == password.encode('utf-8') 325 ns ± 12.8 ns per loop (…) Data-dependent @me
  24. In [1]: from django.utils.crypto import constant_time_compare In [2]: %timeit constant_time_compare('massword',

    'password') 93.5 ms ± 426 µs per loop (...) In [3]: %timeit constant_time_compare('pass1234', 'password') 92.5 ms ± 550 µs per loop (...) In [4]: %timeit constant_time_compare('password', 'password') 93.3 ms ± 479 µs per loop (…) Constant @me
  25. In [1]: from django.utils.crypto import constant_time_compare In [2]: %timeit constant_time_compare('massword',

    'password') 93.5 ms ± 426 µs per loop (...) In [3]: %timeit constant_time_compare('pass1234', 'password') 92.5 ms ± 550 µs per loop (...) In [4]: %timeit constant_time_compare('password', 'password') 93.3 ms ± 479 µs per loop (…) Constant @me O(1)
  26. if len(sig_bytes) != len(mac_bytes): return False result = 0 for

    x, y in zip(mac_bytes, sig_bytes): result |= ord(x) ^ ord(y) return result == 0 https://github.com/google/keyczar/blob/master/python/src/keyczar/keys.py#L582
  27. Cross site request forgery protec@on http://example.com Username Password Submit <input

    type=”hidden” value=”abc123xyz” name=”csrf_token”>
  28. Cross site request forgery protec@on https://example.com Username Password Submit <input

    type=”hidden” value=”abc123xyz” name=”csrf_token”>
  29. Cross site request forgery protec@on https://example.com Username Password Submit 10Kb

    <input type=”hidden” value=”abc123xyz” name=”csrf_token”>
  30. Cross site request forgery protec@on https://example.com Username Password Submit 3Kb

    GZipped! <input type=”hidden” value=”abc123xyz” name=”csrf_token”>
  31. 0 1 2 3 4 5 6 7 8 9

    1 2 3 4 5 6
  32. data = memory[1] if data % 2 == 0: message

    = memory[10] else: message = memory[11] print message 0 1 2 2^64
  33. data = memory[1] if data % 2 == 0: message

    = memory[10] else: message = memory[11] print message ¯\_(ツ)_/¯ 0 1 2 2^64
  34. data = memory[1] if data % 2 == 0: message

    = memory[10] else: message = memory[11] print message ¯\_(ツ)_/¯ 0 1 2 2^64