Log In Sign Up

Incremental Adaptive Attack Synthesis

Information leakage is a significant problem in modern software systems. Information leaks due to side channels are especially hard to detect and analyze. In this paper, we present techniques for automated synthesis of adaptive side-channel attacks that recover secret values. Our attack synthesis techniques iteratively generate inputs which, when fed to code that accesses the secret, reveal partial information about the secret based on the side-channel observations, reducing the remaining uncertainty about the secret in each attack step. Our approach is incremental, reusing results from prior iterations in each attack step to improve the efficiency of attack synthesis. We use symbolic execution to extract path constraints, automata-based model counting to estimate probabilities of execution paths, and meta-heuristics to maximize information gain based on entropy in order to minimize the number of synthesized attack steps.


page 1

page 2

page 3

page 4


Attack Synthesis for Strings using Meta-Heuristics

Information leaks are a significant problem in modern computer systems a...

Monitoring Performance Metrics is not Enough to Detect Side-Channel Attacks on Intel SGX

Side-channel vulnerabilities of Intel SGX is driving the research commun...

Symbolic Execution + Model Counting + Entropy Maximization = Automatic Search Synthesis

We present a method of automatically synthesizing steps to solve search ...

Exploiting Behavioral Side-Channels in Observation Resilient Cognitive Authentication Schemes

Observation Resilient Authentication Schemes (ORAS) are a class of share...

Loki: Hardening Code Obfuscation Against Automated Attacks

Software obfuscation is a crucial technology to protect intellectual pro...

Electro-Magnetic Side-Channel Attack Through Learned Denoising and Classification

This paper proposes an upgraded electro-magnetic side-channel attack tha...

SCAUL: Power Side-Channel Analysis with Unsupervised Learning

Existing power analysis techniques rely on strong adversary models with ...

1 Introduction

It is common for modern software systems store and manipulate sensitive data. It is crucial for software developers to write code in a manner that prevents disclosure of sensitive data that should be kept secret to unauthorized users. However, computation that occurs over sensitive data can have measurable non-functional characteristics that can reveal information. This can allow a malicious user to infer information about sensitive data by measuring characteristics such as execution time, memory usage, or network delay. This type of unintended leakage of information about sensitive data due to non-functional behavior of a program is called a side-channel vulnerability. In this paper, we focus on automatically synthesizing adaptive side-channel attacks against functions that manipulate secret values. Our attack consists of a sequence of public inputs that a malicious user can use to leak information about a secret by observing side-channel behavior. By synthesizing an attack, we provide an exploit demonstrating the side-channel vulnerability of the function.

Our approach uses symbolic execution to extract constraints that characterize the relationship between the secret values in the program, attacker controlled inputs, and side-channel observations. We investigate and compare several methods for selecting the next attack input based on meta-heuristics for maximizing the amount of information gained and automata-based techniques for constraint solving and model counting. Our attack synthesis approach is adaptive, taking into account the information learned about the secret in previous steps while choosing the public input for the next attack step; and it is incremental, re-using the results from prior iterations in order to improve the performance of each attack synthesis step. Moreover, our attack synthesis approach can handle unbounded string constraints in addition to linear arithmetic constraints.

Contribution. Our contributions in this paper can be summarized as follows: (1) to the best of our knowledge, our work is the first that can automatically synthesize side-channel attacks for programs that manipulate both unbounded string and numeric values; (2) we use a greedy approach that maximizes the information gain about the secret in each attack step and we use meta-heuristics for searching the input space during attack synthesis, resulting in a generalized attack synthesis approach; (3) we present an incremental attack synthesis approach based on incremental automata-based model counting that reuses the results from prior attack steps in order to improve the efficiency of attack synthesis; and (4) we present experiments on Java functions and case studies demonstrating realistic attack scenarios, and our experiments demonstrate that our attack synthesis approach is effective and our incremental approach drastically improves the performance of attack synthesis, reducing the attack synthesis time by an order of magnitude.

2 Motivation

Motivating Example 1. Consider a PIN-based authentication function (Fig. 1) with inputs: 1) a secret PIN , and 2) a user input, . Both and are strings of digit characters (“0”–“9”) of length . We have adopted the nomenclature used in security literature where denotes the high-security value (the secret PIN) and denotes the low-security input value, (the input that the function compares with the PIN). The function compares the PIN and the user input character by character and returns false as soon as it finds a mismatch. Otherwise it returns true.

public Boolean checkPIN(String h, String l){   for (int i = 0; i < 4; i++)     if (h.charAt(i) != l.charAt(i))       return false;   return true; }
Figure 1: PIN checking example.

This function has a timing side-channel and one can infer information about the secret by measuring the execution time. In this implementation of checkPIN each length of the common prefix of and , the number of bytecode instructions that will be executed will differ which may cause an observable difference in execution time. Notice that if and have no common prefix, then checkPIN will have the shortest execution since the loop body will be executed only once; this corresponds to execution of 63 Java bytecode instructions. If and have a common prefix of one character, we see a longer execution since the loop body executes twice (78 instructions). In the case that and match completely, checkPIN has the longest execution (123 instructions).

If we assume that differences in the number of bytecode instructions are observable by measuring the execution time, then there are observable values since there are execution paths with different lengths, proportional to the length of the common prefix of and . In general, using the number of executed bytecode instructions as a measurable observation can result in observations that are indistinguishable in practice. Thus, we combine observations into indistinguishability intervals using an observability threshold . For this example assume that differences among execution path lengths are above this threshold.

Given this side-channel, an attacker can choose an input and use the timing observation to determine how much of a prefix of the input has matched the secret. In order to automate this process, our approach starts with automatically generating the path constraints and corresponding execution costs (in terms of number of executed bytecode instructions) using symbolic execution (Table 2). It merges path constraints based on the observability threshold, resulting in a set of observability constraints. It then uses these constraints to synthesize an attack which determines the value of the secret PIN. We make use of an uncertainty function, based on Shannon entropy, to measure the progress of an attack (Section 4.1). Intuitively, the attacker’s uncertainty, starts off at some positive value corresponding to the initial uncertainty of the sercret, and decreases during the attack. When , the attacker has fully learned the secret (Table 2).

tableObservation constraints generated by symbolic execution of the function in Figure 1. Observation Constraint, 1 63 2 78 3 93 4 108 5 123 tableAttack inputs (), uncertainty about the secret (), and observations (). Prefix matches are shown in bold. Step Step 1 13.13 “8299” 63 15 5.906 1392” 93 2 12.96 “0002” 63 16 5.643 1316” 93 3 9.813 1058” 78 17 5.321 1308” 93 4 9.643 1477” 78 18 4.906 1362” 93 5 9.451 1583” 78 19 4.321 1378” 93 6 9.228 1164” 78 20 3.169 1338” 108 7 8.965 1950” 78 21 3.000 1332” 108 8 8.643 1220” 78 22 2.807 1334” 108 9 8.228 1786” 78 23 2.584 1333” 108 10 7.643 1817” 78 24 2.321 1330” 108 11 6.643 1664” 78 25 2.000 1335” 108 12 6.491 1342” 93 26 1.584 1336” 108 13 6.321 1328” 93 27 0.000 1337 123 14 6.129 1386” 93

Suppose that the secret is “1337”. The initial uncertainty is

bits of information (assuming uniform distribution). Our attack synthesizer generates input “8229” at the first step and makes an observation with cost 63, which corresponds to

. This indicates that . Similarly, a second synthesized input, “0002”, implies and the uncertainty is again reduced. At the third step the synthesized input “1058” yields an observation of cost 78. Hence, is the correct path constraint to update our constraints on , which becomes

We continue synthesizing inputs and updating the constraints on , which tell us more information about , until the secret is known after 27 steps. At the final step, we make an observation which corresponds to indicating a full match and the remaining uncertainty is 0. As in this example, the goal of our search for attack inputs is to drive the entropy that characterizes the remaining uncertainty about the secret to 0. Thus, we propose entropy optimization techniques. This particular type of attack is called a segment attack which is known to be a serious source of security flaws [BAP16, CRIMEattack, Kel02, Law09.2, Nel10], and it is exponentially shorter than a brute-force attack. Our approach automatically synthesizes a segment attack.

Motivating Example 2. Consider another example (Figure 2). If secret value is lexicographically smaller than user input , the execution time of stringInequality corresponds to 47 instructions, and 62 otherwise. Symbolically executing the stringInequality method (note that, we do not symbolically execute the compareTo method from Java’s string library but capture it as a string constraint directly), two path constraints are inferred with distinguishable observations shown in Table 2. For simplicity, consider the secret domain to be from “AA” to “ZZ” ( strings), the secret value is “LL” and the first attack input is “AA”. In Table 2 we show an attack that recovers the secret in 20 attack steps.

We can generate an attack like the one shown in Table 2 by finding a satisfying solution (i.e., model) to the constraints on the low variable that is consistent with the observations about the secret we have accumulated so far. We call this the Model-based (M) approach (see section 5), and this approach does generate optimal segment attacks as we discussed above for the example shown in Fig. 1. However, for the example shown in Figure 2 the Model-based approach cannot generate an optimal attack.

The attack shown in Table 2 recovers the secret but it is not optimal in terms of the length of the attack. In order to generate an optimal attack we have to choose an input that maximizes the amount of information leaked in each attack step. Then, we can generate the attack shown in Table 2 which is optimal and requires only 9 steps. This corresponds to a binary search, finding the middle point to divide the domain of secret value in a balanced way. For our example, the domain size is and taking , we get attack steps in the worst case. In order to generate the optimal attack automatically, we need to construct an objective function (see section 4.1) characterizing the information gain for each attack step and use optimization techniques (see section 5) to maximize the objective function.

Let us have a look at the constraints on secret value at each attack step for the optimal attack from Table 2. At each attack step we gain new information about the secret value and a new constraint is added to the already existing constraint . The constraint grows and becomes more complex in each attack step. Constraint solving and model counting are the most expensive parts of our approach. So, if we can reuse prior solutions to constraint solving and model counting to take advantage of the incremental nature of attack synthesis, we can increase the efficiency of our approach. We call this approach incremental attack synthesis (see section 4) and demonstrate that it improves the efficiency of attack synthesis significantly (see section 6).

public static void stringInequality(String h, String l) {     if(h.compareTo(l) <= 0) {       for (int i = 1; i > 0 ; i–);     } else {       for (int i = 5; i > 0 ; i–);     } }
Figure 2: String inequality example.
tableObservation constraints of the function in Figure 2 1 42 2 67 tableNon-optimal attack Step Step 1 9.40 “AC” 67 11 7.56 “PJ” 42 2 9.39 “AE” 67 12 6.82 “PI” 42 3 9.39 “JZ” 67 13 6.80 “NA” 42 4 8.70 “XE” 42 14 5.70 “LZ” 42 5 8.41 “XB” 42 15 4.64 “LI” 67 6 8.40 “KQ” 67 16 4.00 “LR” 42 7 8.33 “XA” 42 17 3.00 “LK” 67 8 8.32 “KU” 67 18 2.58 “LO” 42 9 8.30 “SI” 42 19 1.58 “LM” 42 10 7.60 “KZ” 67 20 0.00 “LL” 42 tableOptimal attack Step 1 8.40 “MZ” 42 2 7.40 “GM” 67 3 6.40 “JS” 67 4 5.43 “LI” 67 5 4.39 “MD” 42 6 3.32 “LS” 67 7 2.32 “LN” 67 8 1.00 “LK” 67 9 0.00 “LL” 42
tableIncremental nature of constraints at each step of adaptive attack. Attack step Attack input Constraint on secret value, 1 “MZ” 2 “GM” 3 “JS” 9 “LL”

3 Synthesizing Adaptive Attacks

We use a two-phase attack synthesis approach as shown in Fig. 3 and Algorithm 1. We consider a function that takes as input a secret and an attacker-controlled input and that generates side-channel observations .

Static Analysis Phase. In the first phase we generate observation constraints from as shown in Algorithm 2. First, we perform symbolic execution on with the secret () and the attacker controlled input () marked as symbolic [King:1976:SEP:360248.360252, Pasareanu:2013:ASE]. Symbolic execution runs on symbolic rather than concrete inputs resulting in a set of path constraints . Each is a logical formula that characterizes the set of inputs that execute some path in . During symbolic execution, we keep track of a side-channel observation for each path. For timing side-channels, as in other works in this area, we model the execution time of the function by the number of instructions executed [BAP16, Pasareanu:2016:MSC, PhanCSF2017]. We assume that the observable values are noiseless, i.e., multiple executions of the program with the same input value will result in the same observable value. We augmented symbolic execution to return a function that maps a path constraint to an observation . Since an attacker cannot extract information from program paths that have indistinguishable side-channel observations, we combine observationally similar path constraints via disjunction (Algorithm 2, line 4), where we say that and are in the same equivalence class () if and only if . The resulting observation constraints (denoted and ) characterize the relationship between the secret () the attacker input () and indistinguishable side-channel observations (). Figure 3: Overview of Attack Synthesis Approach

Algorithm 1 SynthesizeAttack()
This algorithm calls the GenerateConstraints and RunAttack functions to synthesize adaptive attacks.

Attack Synthesis Phase. The second phase synthesizes a sequence of inputs that allow an attacker to adaptively learn the secret (Algorithm 3). During this phase, we fix a secret , unknown to the attacker. We maintain a constraint on the possible values of the secret . Initially, merely specifies the domain of the secret. We call algorithm AttackInput-SA, which uses the simulated annealing technique to maximize information gain about the secret expressed as entropy (as discussed in section 5), to determine the input value for the current attack step. Then, the observation that corresponds to running the program under attack with and is revealed by running the function using the public input . We update to reflect the new constraint on implied by the attack input and observation—we instantiate the corresponding observation constraint, , and conjoin it with the current (line 5). Based on , we compute an uncertainty measure for at every step using Shannon entropy [shannon48, Cover2006], denoted (Section 4.1). The goal is to generate inputs which drive as close as possible to zero, in which case there is no uncertainty left about the secret and the secret is fully known. This attack synthesis phase is repeated until it is not possible to reduce the uncertainty, , any further.

2: SymbolicExecution
3:for  do
Algorithm 2 GenerateConstraints()
Performs symbolic execution on function with secret string and attacker-controlled string . The resulting path constraints are combined according to indistinguishability of observations.
2:while  do
Algorithm 3 RunAttack()
Synthesizes a sequence of attack inputs, , for , given observation constraints , initial constraints on (), and unknown secret .

4 Incremental Attack Synthesis

In this section, we first describe the objective function we use to guide the synthesis of each attack step. Then, we discuss the use of automata-based model counting for computing the objective function. Finally, we describe our incremental approach to attack synthesis that reuses results of model counting queries from prior steps for improving efficiency.

4.1 Objective Function for Information Gain

Here we derive an objective function to measure the amount of information an attacker expects to gain by choosing an input value to be used in the attack search heuristics discussed in section 5. In the following discussion, , , and

are random variables representing high-security input, low-security input, and side-channel observation, respectively. We use entropy-based metrics from the theory of quantitative information flow 

[Smi09]. Given probability function , the information entropy of , denoted , which we interpret as the initial uncertainty about the secret, is


Given conditional distributions , and , we quantify the attacker’s expected updated uncertainty about , given a candidate choice of , with the expectation taken over all possible observations, . We compute the conditional entropy of   given with as


Now we can compute the expected amount of information gained about by observing after running the function with a specific input . The mutual information between and , given denoted is the difference between the initial entropy of and the conditional entropy of given when :


Equation (3) serves as our objective function. Providing input which maximizes maximizes information gained about . Equations (1) and (2) rely on , , and , which may change at every step of the attack. Recall that during the attack, we maintain a constraint on the secret, . Assuming that all secrets that are consistent with are equally likely, at each step, we can compute the required probabilities using model counting. Given a formula , performing model counting on gives the number of satisfying solutions for , which we denote . Thus, we observe that if satisfies and is otherwise. Hence, Equation 1 reduces to .

Algorithm 2 gives us side-channel observations and constraints over and corresponding to each , . The probability that the secret has a particular value, constrained by a particular , for a given can be computed by instantiating with and then model counting. Thus, . Similarly, .

In this paper, the Entropy (Equation (1)) and MutualInfo (Equation (3)) functions refer to the appropriate entropy-based computation just described, where , , and are computed using the ModelCount algorithm described in the next section. Using MutualInfo, an attacker can optimize the information gain by trying many different values and computing the corresponding MutualInfo. Observe that this process involves model counting for instantiating constraints for many values of . In the next section we describe how to perform this model counting step efficiently.

4.2 Automata-Based Constraint Solving and Model Counting

As mentioned above, we compute entropy, which is used in the objective function for information gain, using model counting. For this purpose, we use and extend the Automata-Based Model Counter (ABC) tool, which is a constraint solver for string and numeric constraints with model counting capabilities [ABB15]. The constraint language for ABC supports all numeric constraints solved by off the shelf constraints solvers as well as typical string operations such as charAt, length, indexOf, substring, begins, concat, , , etc. Given a constraint , ABC constructs a multi-track deterministic finite automaton (DFA) that characterizes all solutions for the constraint , where corresponds to the set of solutions for . For each string term or integer term in the constraint grammar [aydin2018parameterized], ABC implements an automata constructor function which generates an automaton that encodes the set of satisfying solutions for the term. Note that variables within string terms and integer terms appear in separate automata, as separate encodings are used for each (ASCII for strings, binary encoding for integers). ABC implements specialized DFA construction algorithms for atomic string operations. Boolean operations (, , ) are handled using standard DFA operations (intersection, union, and complement, respectively).

ABC counts the number of models (solutions) for a constraint by first constructing the corresponding automaton and using the observation that number of strings of length in is equal to the number of accepting paths of length in the DFA . Consequently, ABC treats the DFA that results from solving as a graph where DFA states are graph vertices and the weight of an edge is the number of symbols that have a transition between the source and destination vertices (states) of that edge. A dynamic programming algorithm that computes the th power of the adjacency matrix of the graph is used to count the number of accepting paths in the DFA of length (or less than or equal to [ABB15].

4.3 Incremental Constraint Solving and Model Counting

Attack synthesis requires solving and model counting the constraint on the secret, , and updating it with the current instantiated observation constraint, (Algorithm 3, line 5). This results in a new constraint, , which we then compute the entropy for (Algorithm 3, line 6). As this process is executed many times, multiple calls to ABC are required, often with similar constraints. In each iteration ABC starts from scratch re-solving each sub-constraint again and constructing a DFA for each of them, then combining them using DFA intersection. Note that, during attack synthesis, can become a complex combination of constraints that represent what we learned over the course of the attack. Then ABC would be unnecessarily re-solving the subconstraints of in each attack step. To summarize, we observe that, during attack synthesis 1) the constraint that characterizes the set of secrets that are consistent with the observations and low inputs () is constructed incrementally, and 2) computing entropy using incremental constraint solving can improve the performance by exploiting the incremental nature of attack synthesis.

We implemented incremental constraint solving and model counting by extending ABC so that it retains state over successive calls. Given a constraint, ABC constructs the automaton representing the set of solutions to the constraint, which is then stored for use in later calls. The steps of attack synthesis involve two types of model counting for and : during MutualInfo when an attacker optimizes the attack by trying many different , and in Entropy, during computation of the remaining uncertainty. In both situations, model counting is required on many different constraints, and most of the sub-constraints come from previous iterations. We augmented ABC with an interface so that, given , we can check if an automaton has already been constructed for either or , and if so, to get the already constructed automata for them, rather than re-solving each constraint. Note that for the purposes of model counting, can be represented as . Our incremental model counting approach is outlined in Algorithm 4. Given the constraint , GetDFA retrieves the previously constructed automaton for , . Algorithm 4 is called with a new observation constraint in each attack step, for which the automaton must first be constructed. Subsequent calls with the same use the previously constructed automaton. A new must be constructed for each model counting query (as each query involves a different ). The final automaton is constructed using automata product from . is exactly the same automaton constructed from , but it is constructed incrementally, thus allowing re-use of previously constructed automata.

2:if  then  
Algorithm 4 ModelCountIncremental()
Performs incremental model counting for constraint .

5 Attack Synthesis Heuristics

At every attack step the attacker’s goal is to choose a low input that reveals information about . Here we will describe techniques based on constraint solving and meta heuristics for synthesizing attack inputs . Meta heuristic approaches explore a subset of the possible low inputs. In order to search the space efficiently, we first observe that we need to restrict the search to those that are consistent with , which we now discuss.

Constraint-based Model Generation of Low Inputs. The first value can be chosen arbitrarily since initially we do not have any information about the secret . After the first step, our attack synthesis algorithm maintains a constraint which captures all values that are consistent with the observations so far (Algorithm 3, line 5). Using the observation constraints (which identify the relation among the secret , public input and the observation ), we project to a constraint on the input , which we call , and we restrict our search on to the set of values allowed by . I.e., we only look for values that are consistent with what we know about (which is characterized by ) with respect to . This approach is implemented in GetNeighborInput function which returns an by mutating the previous .

1:, GetInput(), MutualInfo()
2:while  do
3:      GetNeighborInput()
4:      MutualInfo()
5:     if  then
Algorithm 5 AttackInput-SA()
Generates a low input at each attack step via simulated annealing.

Searching via Random Model Generation. As a base-line search heuristic, we make use of the approach described above for generating low values that are consistent with . The simplest approach is to generate a single random model from and use it as the next attack input. We call this approach Model-based (M). A slightly more sophisticated approach is to generate random samples using , compute the expected information gain for each of them using Equation (3) (i.e., objective function is evaluated using the automata-based entropy computation) and then choose the best one. [string-attack-synthesis]

evaluates different meta heuristic techniques : genetic algorithm (GA) and simulated annealing (SA) to maximize information leakage and shows that SA performs better than GA. The reason is GA applies mutation and crossover to generate candidate low values. To restrict the search to

values that are consistent with , would require implementing mutation and crossover operations with respect to . We are not aware of a general approach for doing this, so during GA-based search, mutation and crossover operations can generate low values that are inconsistent with (and hence ). Note that, such values will have no information gain and will be ignored during search, but they can slow down the search increasing the search space and hence, we may end up having a higher number of attack steps compared to SA. So, the SA ends up being a more effective meta-heuristic for attack synthesis.

Simulated Annealing. Simulated annealing (SA) is a meta-heuristic for optimizing an objective function  [simulatedannealing]. SA is initialized with a candidate solution . At step , SA chooses a neighbor, , of candidate . If is an improvement, i.e., , then is used as the candidate for the next iteration. If is not an improvement, i.e. , then is still used as the candidate for the next iteration, but with a small probability . Intuitively, SA is a controlled random search that allows a search path to escape from local optima by permitting the search to sometimes accept worse solutions. The acceptance probability decreases exponentially over time, which is modeled using a search “temperature” which “cools off” and converges to a steady state. Our use of SA that incorporates automata-based entropy computation is given in Algorithm 5 where we use GetNeighborInput function to get new candidates.

6 Implementations and Experiments


The implementation of our approach consists of two primary components, corresponding to the two main phases described in section 3. We implemented Algorithm 2 using Symbolic Path Finder (SPF) [Pasareanu:2013:ASE]. We implemented Algorithm 3 as a Java program that takes the observation constraints generated by Algorithm 2 as input, along with , . AttackInput-SA from section 5 is implemented directly in Java as well. We implemented GetNeighborInput, ModelCount, and ModelCountIncremental by extending the existing string model counting tool ABC as described in section 4. We added these features directly into the C++ source code of ABC along with corresponding Java APIs.

Benchmark ID Operations Low Length High Length
passCheckInsec PCI charAt,length 4 4 5 5
passCheckSec PCS charAt,length 4 4 16 1
stringEquals SE charAt,length 4 4 9 9
stringInequality SI , 4 4 2 2
stringConcatInequality SCOI concat,, 4 4 2 2
stringCharInequality SCI charAt,length,, 4 4 80 2
indexOf IO charAt,length 1 8 9 9
compress CO begins,substring,length 4 4 5 5
editDistance ED charAt,length 4 4 2170 22
Table 1: Benchmark details with the number of path constraints () and the number of merged observation constraints ().

Benchmark Details. To evaluate the effectiveness of our attack synthesis techniques, we experimented on a benchmark of 9 Java canonical programs utilizing various logical and string manipulation operations, setting different sizes and lengths to define the domain of secret value (Table 1). The functions PCI and PCS are password checking implementations. Both compare a user input and secret password but early termination optimization (as described in section 1) induces a timing side channel for the first one and the latter is a constant-time implementation. We analyzed the SE method from the Java String library which is known to contain a timing side channel [MS14]. We discovered a similar timing side channel in the IO method from the Java String library. Function ED is an implementation of the standard dynamic programming algorithm to calculate minimum edit distance of two strings. Function CO is a basic compression algorithm which collapses repeated substrings within two strings. SI, SCOI and SCI functions check lexicographic inequality () of two strings whereas first one directly compares the strings, second one includes concat operation with inequality and third one compares characters in the strings.

Experimental Setup. For all experiments, we use a desktop machine with an Intel Core i5-2400S 2.50 GHz CPU and 32 GB of DDR3 RAM running Ubuntu 16.04, with a Linux 4.4.0-81 64-bit kernel. We used the OpenJDK 64-bit Java VM, build 1.8.0 171. We ran each experiment for 5 randomly chosen secrets. We present the mean values of the results in Table 2. For SA, we set the temperature range ( to ) from 10 to 0.001 and cooling rate as 0.1.

Results. In this discussion, we describe the quality of a synthesized attack according to these metrics: attack synthesis time, attack length, and overall change in uncertainty about the secret measured as entropy from to and efficiency of incremental attack synthesis in terms of time. Attacks that do not reduce the final entropy to zero are called incomplete. Incomplete attacks are mainly due to one of two reasons: the program is not vulnerable to side-channels (for example PCS) or the observation constraints are very complex, combining lots of path constraints which slows progress too much so that not enough information is leaked within the given time bound (for example ED and SCI). For the purpose of direct comparison, in our experiments, we set a bound of 5 hours for SA (slowest technique) on ED and SCI and computed a bound for of 17.28 and 14.48, respectively, while all other examples reduced to 0.0.These examples are marked with . Note that, M and SA-I techniques can reduce for ED and SCI to 14.34 and 12.28, respectively, after one hour.

Attack Synthesis Time Comparison. We observe that the model-based technique (M), which only uses to restrict the search space is faster than other techniques, as it greedily uses a random model generated by ABC as the next attack input, with no time required to evaluate the objective function. quickly generates attacks for most of the functions. We examined those functions and determined that their objective functions are “flat” with respect to . Any that is a model for at the current step yields the same expected information gain. Figure 4 shows how M can synthesize attacks faster compared to SA (in seconds).
Figure 4: Synthesis Time, M vs SA        Figure 5: Attack Length, M vs SA/SA-I Attack Length Comparison. Although M is fast in synthesizing attacks and generates attacks for each benchmark, experimental results show that it requires more attack steps (in terms of information gain) compared to the attacks generated by meta-heuristic techniques that optimize the objective function. As the experimental results show for the SI, SCOI and SCI, a meta-heuristic technique can reduce further but with fewer attack steps compared to the model-based approach (M). And, this case would be true for any example where different inputs at a specific attack step have different information gain. If attacker is aware of the “flat” objective function phenomenon, they can proceed with M. In general, M is not efficient to generate an attack with reduced number of attack steps and hence, meta heuristics like SA approach are required. Figure 5 shows how SA is better than M in terms of length of the generated attacks. Note that, we say M vs SA/SA-I as incremental version will make difference in attack synthesis time, not attack length. Efficiency of Incremental Attack Synthesis. On one hand, we can synthesize attacks faster using M but attacks synthesized by M require more attack steps in general. On the other hand, we can synthesize attacks with minimal number of attack steps using SA, but attack synthesis process is slower for SA. Our experiments demonstrate that incremental attack synthesis using SA gives us fast attack synthesis without increasing the attack length. We compare incremental version of SA (SA-I) against SA. Figure 6 shows SA-I is an order of magnitude faster than SA for all the examples from the benchmark. We also compare SA-I against M and Figure 7 shows that SA-I is comparable to M in terms of attack synthesis time (in seconds).
Figure 6: Synthesis Time, SA vs SA-I        Figure 7: Synthesis Time, M vs SA-I

ID Metrics M SA SA-I
PCS 18.8 Steps 108 14 99
18.8 18.8 18.8
Table 2: Experimental results for secure password checker (PCS). Time bound is set as 3600 seconds.

Vulnerability to Side-Channels. Finally, we observe that some of our selected benchmarks are more secure against our attack synthesizer than others. In particular, PCS, a constant-time implementation of password checking, did not leak any information through the side channel. One of the examples from the benchmark, ED also did not succumb to our approach easily, due to the relatively large number of generated constraints (2170), indicating a much more complex relationship between the inputs and observations. To summarize, our experiments indicate that our attack synthesis approach is able to construct side-channel attacks, providing evidence of vulnerability (e.g. PCI). Further, when attack synthesizer fails to generate attacks (PCS), or is only able to extract a relatively small information after many steps of significant computation time (ED), it provides evidence that the function under test is comparatively safer against side-channel attacks. Table 2 shows results for PCS, hardly reducing even after running for 1 hour for M, SA and SA-I.

7 Case Studies

Our experimental results show that synthesizing attacks face scalability issues for programs leading to large numbers of complex observation constraints. Note that, this limitation depends on the limitations of the building blocks: constraint solvers and model counters. The more powerful these tools become, more powerful attack synthesis will be. We now present two case studies. CRIME Attack. The “Compression Ratio Info-leak Made Easy” (CRIME) attack [CRIMEattack] allows an attacker to learn fields of encrypted web session headers by injecting extraneous text () into a procedure that compresses and encrypts the header (). Despite the encryption, an attacker can infer how much of the injected text matched the unknown header by observing the number of bytes in the compressed result [BAP16, CRIMEattack]. Our approach automatically synthesizes this attack. Symbolic execution of the compression function (LZ77T) for a secret of length 3 and alphabet size 4 yields 187 path constraints and 4 observations, leading to 4 observation constraints. M synthesizes an attack in 6.8 steps within 468.5 seconds. SA-I could generate the attack in 7.8 steps within 757.4 seconds. SA-I does not improve over M due to “flat” objective function. Note that [BAP16] performs leakage quantification for this example but does not synthesize attacks.

Law Enforcement Database. The Law Enforcement Employment Database Server is a network service application included as a part of the DARPA STAC program [darpa, stac]. This application provides access to records about law enforcement personnel. Employee information is determined by an employee ID number. The database contains restricted and unrestricted employee information. Users can search ranges of employee IDs. If an ID query range contains one or more restricted IDs, the returned data will not contain the restricted IDs. We decompiled the application and then symbolically executed the channelRead0 method from the UDPServerHandler class which performs the database search operation. We limited the domain of ids to 1024, added 30 unrestricted IDs and 1 restricted ID. Symbolic execution gives us 1669 path constraints with 162 distinguishable observations ( instructions). M generates attack with an attack length of 8.2 in 270.1 seconds whereas SA-I generates an attack with length of 6.5 in 810.7 seconds. SA-I requires less attack length as the objective function is not “flat”.

8 Related Work

There are two previous results that are most closely related to our work [BAP16, PhanCSF2017]. The first focuses on quantifying information leakage through side channels for programs manipulating strings [BAP16]

. This work assumes that the given program has a segment oracle side-channel vulnerability and then quantifies the amount of information leakage for that vulnerability. Other recent work synthesizes side-channel attacks using either entropy-based or SAT-based objective functions, but works only for linear arithmetic and bit-vector constraints 

[PhanCSF2017], using model counters and constraint solvers for those theories [DeLoera20041273]. This earlier approach also relies on generation of a closed form objective function that represents the information leakage, and uses model counting techniques that specialize on linear integer arithmetic to construct such a function. In contrast, our approach is more general and can handle any program with numeric, string and mixed constraints. Furthermore, our approach does not require a closed form solution for the objective function as we use meta heuristics to search for input values that leak maximum information. Both of these earlier approaches use constraint solving and model counting queries to quantify the information leakage, but they do not use an incremental approach and, therefore, re-compute many sub-queries.

There are many works on analyzing side-channels in various settings [Brumley:2003:RTA:1251353.1251354, Chen:2010:SLW:1849417.1849974, DBLP:conf/sp/MardzielAHC14, Do2015, Pasareanu:2016:MSC, BAP16]. A few recent works address either synthesizing attacks or quantifying information leakage under a model where the attacker can make multiple invocations of the system [DBLP:conf/ccs/KopfB07, DBLP:conf/sp/MardzielAHC14, Pasareanu:2016:MSC, BAP16, BRB18]. Single-run analysis is addressed in [Heusser:2010:QIL:1920261.1920300] where bounded model checking is used over the -composition of a program to determine if it can yield different outputs. Further, LeakWatch [DBLP:conf/esorics/ChothiaKN14] estimates leakage in Java programs based on sampling program executions on concrete inputs. There has been work on multi-run analysis using enumerative techniques [DBLP:conf/ccs/KopfB07]. None of these earlier results present a symbolic and incremental approach to adaptive attack synthesis as we present in this paper.

Due to the importance of model counting in quantitative program analyses, model counting constraint solvers are gaining increasing attention [LSS14, TCJ17, ABB15]. ABC is the only one that supports string, numeric and mixed constraints. We extended ABC to perform incremental model counting for our attack synthesis approach. Other work in quantifying information leakage [PhanCSF2017, Pasareanu:2016:MSC, Phan:2014:QILURA, BRB18] have used symbolic execution and model-counting techniques for linear integer arithmetic.

Preliminary results from this paper were discussed in a short workshop paper [string-attack-synthesis] which did not include our results on incremental attack synthesis and real world scenarios but was focused on studying different meta-heuristic techniques such as random search, genetic algorithm, and simulated annealing.

9 Conclusion

In this paper, we presented techniques for synthesizing adaptive side-channel attacks on programs that manipulate string and numeric values. Our approach uses meta-heuristics for selecting public inputs that maximize the amount of information gained about the secret by computing the amount of remaining uncertainty about the secret using entropy and model counting. We exploit the iterative nature of attack synthesis by presenting an incremental approach that reuses results from prior iterations. We implemented our attack synthesis approach for Java programs using symbolic execution tool SPF and ABC model counter. We evaluated the effectiveness of our attack synthesis approach on several functions and two case studies. Our experiments demonstrate that our incremental approach greatly improves the efficiency of attack synthesis.