There have even been timing attacks that let you recover AES keys from analyzing a device's power usage.
In layman's terms: computers are extremely complicated beasts of coordinated timing of software and hardware, and timing data leaks many things about what a piece of software is doing. This is the reason that many modern encryption libraries pad operations as a defense against timing attacks.
So, how does this work? I set a timer, and then read the time a bit later, and somehow I recovered an AES key from a different process? I'm still missing a piece :-)
Notably, how can timing data leak things?
I mean, I can see how I can do
1. Start hi-res timer
2. Kick off something that involves out-of-sandbox data
3. Stop hi-res timer
and do this often enough and with well-tuned input to read useful data out. Is that how it works?But how can I use this to read stuff in entirely different processes? Moreover, how can I do that in a targeted manner? Eg I suspect my target is using internet banking but I don't know which other programs are running, how many cores the machine has, etc etc etc.
Where they are different is that timing attacks usually serve as information extraction tools, which attackers can choose to further leverage by basing subsequent attacks on the information they obtained, where as buffer overflow attacks can do pretty much anything up to and including rooting a box or breaking out of a hypervisor.
That part's simple. Naive crypto code will often vary in speed based on the data. A 0 bit in the key causes some behavior, a 1 bit causes some slightly different behavior, and suddenly if you can measure the length of each step you can recover the secrets.
Getting the timing data is a little bit trickier from javascript, but it's also simple in concept. As sensitive code runs, it affects the CPU cache. Javascript can use memory locations that go in the same cache slots as sensitive code. This goes a few nanoseconds faster or slower based on what parts of the sensitive code have finished. Now you have timing data.
If you don't know what else is running or if you're on the same core, you just have to try repeatedly.
A lot of crypto code, especially implementations of asymmetric crypto, is not constant time, meaning that by timing it's execution you can extract key or plaintext fragments. Of course, authors try to make them as constant time as possible, but it's very, very hard to mask a non-constant time operation (required by some algorithms). So a higher resolution timer for the attacker means that it's easier and faster to attack these applications.
(This was a major design motivation for Curve25519. Previous ECC algorithms all had special cases, which mean non-constant-time, even with masking. Curve25519 was specifically designed to avoid that. -- That doesn't mean you can't implement it badly, though ;)
Due to the memory hierarchy (i.e. the fact that a CPU has caches) key or plaintext-dependent memory accesses lead to time variations as well. There are attacks that can be used to amplify these, by poisoning or preparing the caches in a way that forces main-memory or L3 reads for certain addresses.
(Some badly written libraries also use completely naive implementations, e.g. BouncyCastle used a not-at-all constant time implementation of AES, which was trivial to attack.)
For example measuring the time of a=b with constant b tells you roughly how large a[:n] such that a[:n] = b[:n].