Introduction to Timing Attacks!
By: Selva Karthik
Tags: Side Channel Attacks, Timing Attacks, Spider, Hacker Series, Hacking

There is an ever-increasing need for speed in the digital world, which has lead to the software & hardware development process being aimed at improving the performance by inculcating several optimization methods during implementation. While these optimizations are significant at achieving much better efficiency, they also introduce subtle security loopholes that are, at times, ignored or overlooked. A timing attack is one such exploit that takes advantage of implementation flaws, which can have a catastrophic impact in critical scenarios, resulting in compromised security.

A timing attack is a security exploit that enables an attacker to spot vulnerabilities in a local or a remote system to extract potentially sensitive or secret information by observing the concerned system's response time to various inputs. A timing attack is a type of a broader class of attacks called Side-channel attacks!

What is a Side-Channel Attack?

Side-Channel Attack (SCA) refers to any attack which exploits implementation flaws in a computer system to retrieve sensitive information such as passwords. SCAs are a form of reverse engineering that takes advantage of information exhaust from the computer. Specifically, it utilizes the data gained from monitoring patterns in physical parameters such as EMF radiation, power consumption, response times, and acoustic emissions during cryptographic operations performed by the system. The attacker can break the encryption system by using the acquired information to discover the associated encryption key.

Image credits: thesecuritybuddy.com

How does a Timing Attack work?

Let us consider a simple example of implementing a string compare function, where we have to return true if the strings match and return false if they don’t.

In the above function, we first compare the two strings' lengths and then compare the individual characters if they are of equal length. While iterating over the loop, if we encounter two different characters, we return false. If we do not find any difference, we return true.

Although it looks fine, there is a flaw in this implementation which most of us don’t realize immediately!

Consider the scenario where this function is used for authenticating users on a website (or any app for that matter).

One of the two strings would be the password entered by the user (let’s say it’s assigned to s1), and the other string, s2, would contain the correct password (or it’s respective hash value in practical implementations) of the user from the database.

Assuming the required password to be a ten-digit integer, it would take an attacker 10¹⁰ possible combinations to use brute force to find it.

But this is where things get interesting!

Let us assume that the correct password is 5263987149, and the attacker starts guessing from the first digit (beginning from 0000000000). He measures that the system returns false after x seconds. After getting the same response time x for the first five guesses (i.e., from 0000000000 to 4000000000), he notices that the system takes a slightly longer time to respond ( x + ∆ x) when he tries 5000000000. This is because the for loop during its first iteration doesn’t return false since the first digit of the user input and the stored password is equal. Hence, the loop runs another iteration, thereby taking more time (∆x). Therefore, the attacker knows that the first digit he tried now is correct. He can repeat the same procedure to guess the remaining digits by observing the pattern of ∆x. In this way, it would take the attacker only 10*10 guesses at the maximum to find the correct password, compared to 10¹⁰ possible combinations while trying to brute force it…

To fix this flaw, we need to prevent the leakage of information about the pattern in execution time, enabling the attacker to know which character in the array differs. This implies that the loop needs to run a fixed number of times, irrespective of the number of correct/wrong elements between the two strings.

To do that, we have a variable flag which is initialized to True (after comparing the string lengths). Inside the for loop, we have the same if statement as before, but this time we store the boolean value in a flag variable instead of returning it as soon as we encounter a wrong digit. This ensures that the loop iterates through every element of the array and takes a constant amount of time, regardless of how many digits match. Therefore the timing-attack vulnerability in the concerned function is resolved.

Although real-world implementations wouldn’t be as easy to exploit (and counter) as shown above, this small function illustrates the essence of a basic timing-attack and helps understanding it in a simple manner.

That is the logic behind a simple Timing Attack!