Despite significant effort from the research community in developing privacy leak detection tools, it is still unclear whether apps and ad libraries can hide the fact that they are leaking private information. In fact, all existing analysis tools have strong limitations. We proposed a new approach to privacy leak detection that is not affected by such limitations, and it is also resilient to obfuscation techniques, such as encoding, encryption, performed on private information before it is leaked. Our work is based on black-box differential analysis, and it works in two steps: first, it establishes a baseline of the network behavior of an app; then, it modifies sources of private information, such as the device ID and location, and detects leaks by observing deviations in the resulting network traffic. Unfortunately, differential analysis is not practical enough to analyze modern mobile apps. In fact, their network traffic contains many sources of non-determinism, which, when not handled properly, cause too much noise to correlate output changes with input changes. In this talk we show that such non-determinism can often be explained and eliminated, and it is thus possible to reliably use variations in the network traffic to detect privacy leaks in Android apps. We implemented this approach in a tool, called Agrigento, and we evaluated it on more than one thousand Android apps. Our evaluation shows that our approach works well in practice and outperforms current state-of-the-art techniques. We conclude our talk by discussing several case studies that show how popular apps and ad libraries currently exfiltrate data by using complex combinations of encoding and encryption mechanisms.
26. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
...
App
Sources of Leak
......
App
Sources of Leak Contextual Info
Network Trace
Instrumented Environment
27. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
... Network Behavior
Summary
App
Sources of Leak
Phase 1: Network Behavior
Summary Extraction
......
App
Sources of Leak Contextual Info
Network Trace
Instrumented Environment
28. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
... Network Behavior
Summary
Contextualized Trace
Final
Run
App
Sources of Leak
Phase 1: Network Behavior
Summary Extraction
......
App
Sources of Leak
App
Sources of Leak
Contextual Info
Network Trace
Contextual Info
Network Trace
Instrumented Environment
Instrumented Environment Phase 2: Differential Analysis
29. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
... Network Behavior
Summary
Contextualized Trace
Final
Run
App
Sources of Leak
Differential
Analysis
Phase 1: Network Behavior
Summary Extraction
Phase 2: Differential Analysis
......
App
Sources of Leak
App
Sources of Leak
Contextual Info
Network Trace
Contextual Info
Network Trace
Instrumented Environment
Instrumented Environment
30. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
... Network Behavior
Summary
Contextualized Trace
Final
Run
App
Sources of Leak
Differential
Analysis
Leaks
Phase 1: Network Behavior
Summary Extraction
Phase 2: Differential Analysis
......
App
Sources of Leak
App
Sources of Leak
Contextual Info
Network Trace
Contextual Info
Network Trace
Instrumented Environment
Instrumented Environment
31. Contextual Info
Network Trace
Contextualized TraceInstrumented Environment
Contextualized Trace
#1
Run
#n
Run
... Network Behavior
Summary
Contextualized Trace
Final
Run
App
Sources of Leak
Differential
Analysis
Leaks
Phase 1: Network Behavior
Summary Extraction
Phase 2: Differential Analysis
......
App
Sources of Leak
App
Sources of Leak
Contextual Info
Network Trace
Contextual Info
Network Trace
Instrumented Environment
Instrumented Environment
40. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());
41. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());
42. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());
43. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());
44. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());
45. String aid = class.getDeclaredMethod( "getAndroidId" ,
Context. class).invoke(context); // get Android ID by Reflection
MessageDigest sha1 = getInstance( "SHA-1"); // hash
sha1.update(aid.getBytes());
byte[] digest = sha1.digest();
Random random = new Random(); // generate random key
int key = random.nextint();
// XOR Android ID with the randomly generated key
byte[] xored = customXOR(digest, key);
String encoded = Base64.encode(xored);
// send the encrypted value and key to ad server
HttpURLConnection conn = url.openConnection();
conn.write(Base64.encode(encoded).getBytes());
conn.write(("key=" + key).getBytes());