Real-World Android Apps
Mobile Systems and Smartphone Security
(MOBISEC 2020)
Prof: Yanick Fratantonio
EURECOM 1
Pro-ing up
- Last time: basic things about Android apps
- Today: "complicated" things about real-world apps
- Many of these things are used by malware or have
security repercussions
2
App Signing
- Each app is signed with a certificate
- A certificate is
- the public key of a public/private key pair
- some other metadata identifying the owner of the key
- The owner of the certificate holds the corresponding
private key
3
Primer on cryptographic signatures
- Developer generates a public/private key pair:
- private key: PRIV
- public key: PUB
- The developer keeps PRIV secret
- PUB, as the name suggests, is public
4
Primer on cryptographic signatures
- Two primitives: sign & verify
- sign(MESSAGE, PRIV) ~> SIGN
- Only the developer can create a valid signature
- verify(MESSAGE, SIGN, PUB) ~> VALID / NOT VALID
- Everybody can check whether the signature is valid or not
5
App Signing
- Certificate doesn't need to be signed by cert. authority
- Apps' certificates can be self-signed
- Major difference with SSL certificates
- Purpose: distinguish app authors, NOT identify them
- You can distinguish "system" vs "normal" apps
- System apps are those that are signed with a "system" certificate
- That's how the system deals with "signature" permissions
6
App Signing
- You can determine that a given Facebook app has the
same developer as a given Messenger app
- But by only checking an app's certificate...
- ...you CANNOT determine whether the Facebook app you
have is the legitimate/official one!
7
App's certificate vs. SSL certificate
- Your browser knows that the "facebook.com" website you
are talking to IS the real, legitimate one
- That certificate is signed by another certificate, which is
signed by another certificate, which is signed by ....
- ... which is signed by a certificate that your browser trusts
8
android:sharedUserId (doc)
- Apps can request to be assigned the same Linux User ID
- Only if their certificates are identical
- All security barriers discussed so far are gone
- Two apps with the same Linux User ID share everything
- Both can access each other (private) internal storage
- Both can access each other components, regardless of configuration
<manifest xmlns:android="..." <manifest xmlns:android="..."
package="com.mobisec.app.ONE" package="com.mobisec.app.TWO"
android:sharedUserId="com.mobisec.shareduser"> android:sharedUserId="com.mobisec.shareduser">
9
Resources (doc)
- Resources are the additional files and static content that
your code uses
- drawable, layout, raw
- values
- arrays
- colors
- strings
10
Resources example: strings.xml
- In strings.xml
<resources>
<string name="secret_string">Juicy Secret</string>
</resources>
- In the Java code
String secret = getResources().getString(R.string.secret_string);
- From the docs
11
Resources under the hood
invoke-virtual {p0},
Lcom/example/MyActivity;->getResources()Landroid/content/res/Resources;
move-result-object v3
const v4, 0x7f07002b
invoke-virtual {v3, v4},
Landroid/content/res/Resources;->getString(I)Ljava/lang/String;
move-result-object v1
From res/values/strings.xml
<string name="secret_string">Juicy Secret</string>
From res/values/public.xml (it specifies the mapping)
<public type="string" name="secret_string" id="0x7f07002b" />
12
RunTime.exec() (doc)
- Analogous of C's system() or Python's os.system()
- Runtime.exec("cp ../flag /sdcard/leaked-flag.txt")
13
Reflection (doc)
- Java interface to programmatically "play" with Java
objects beyond what's normally possible
- Bypass access modifiers (e.g., private, protected, final)
- You can invoke private methods or get/set private fields
- Enumerate / iterate over methods/fields of a class
14
Example of Reflection
peppa.pig();
try {
Method m = peppa.getClass().getMethod("pig");
m.invoke(peppa);
} catch (...) {
...
}
15
Reflection Benign Use Cases
- Google gson's library: github
- "Gson is a Java library that can be used to convert Java
Objects into their JSON representation. It can also be
used to convert a JSON string to an equivalent Java
object."
16
Reflection Malicious Use Cases
- Malware authors are big fans of reflection
- peppa.pig();
It's a string!
invoke-virtual {v3, v4},
Lcom/example/Peppa;->pig()V
- peppa.getClass().getMethod("pig").invoke(peppa)
???????
Obfuscation made easy!
17
Dynamic Code Loading
- Apps can "load" additional code at run-time
- This code can be loaded from the file-system
- It could be embedded in the app itself
- It could be a "just-downloaded" piece of code
- Benign apps do this to
- A/B testing
- Sharing common framework
- Download additional parts (e.g., "levels" of a game)
18
Dynamic Code Loading
- Malicious apps do this for... obfuscation!
DexClassLoader classloader = new DexClassLoader(
peppaApkFile.getAbsolutePath(), tmpDir.getAbsolutePath(),
"data/local/tmp/natives/",
ClassLoader.getSystemClassLoader());
Class<?> cls = (Class<?>) classloader.loadClass("com.mobisec.Peppa");
Method m = cls.getMethod("pig");
Execute This! Analyzing Unsafe and Malicious
Dynamic Code Loading in Android Applications, Strings!
Poeplau et al., NDSS 2013
19
Serialization
class Peppa():
def __init__(self, n, s):
p = Peppa(42, "ciao")
self.n = n # int
self.s = s # string
pickle.dumps(p)
def pig(self):
return n*s
"(i__main__\nPeppa\np0\n(d
p1\nS's'\np2\nS'ciao'\np3\ns
S'n'\np4\nI42\nsb."
20
Serialization
- The serialized version ...
- ... encodes details about a specific instance of Peppa
- ... does NOT encode the actual definition of Peppa
- To load the instance of Peppa from the raw bytes
- You code needs to have Peppa's definition within the visible classes
- How is this relevant for Android apps?
21
Serialization
- Objects need to be serialized before are sent via Binder
- Example: Intents!
- Two main interfaces
- Parcelable (doc)
- Implemented by objects whose instance can be written to / restored from a Parcel
- Parcel: a container for an object to be sent via Binder (doc)
- Serializable (doc)
- More generic serializable interface
- Nice tutorial: link
22