SESSION ID:
#RSAC
Roee HayAndroid Serialization Vulnerabilities Revisited
MBS-F03
X-Force Application Security Team LeadIBM Security
@roeehay
Joint work with Or Peles
#RSAC
We will see how this Android SDK class
2
public class OpenSSLX509Certificateextends X509Certificate {
private final long mContext;…
}
MISSING MODIFIERBEFORE OURDISCLOSURE!
(NOW PATCHED)
#RSAC
Led to malware capable of this…
3
REPLACEMENT OF APPS
SELINUX
BYPASS
ACCESS TO APPS’ DATA
KERNEL CODE EXEC
(on select devices)
#RSAC
Serialization
5
class foo{int bar;String baz;long *qux;
}
SENDER RECIPIENT
MEDIA
= 1234= “hi”= 0x1f334233
#RSAC
Serialization
6
001010…0110
SENDER
SerializeMEDIA
class foo{int bar;String baz;long *qux;
}
= 1234= “hi”= 0x1f334233
RECIPIENT
#RSAC
Serialization
7
001010…0110
SENDER
Serialize DeserializeMEDIA
class foo{int bar;String baz;long *qux;
}
= 1234= “hi”= 0x1f334233
class foo{int bar;String baz;long *qux;
}
= 1234= “hi”= 0x14d3e2c3
RECIPIENT
#RSAC
Vulnerability Root Cause
8
ObjectInputStream ois = new ObjectInputStream(insecureSource);
Foo t = (Foo)ois.readObject();
DESERIALIZATION OF UNTRUSTED DATA
#RSAC
Vulnerability Root Cause
9
class dangerous{
…
}
class dangerous{
…
}
001010…0110
ATTACKER
Serialize DeserializeMEDIA
VICTIM
#RSAC
Example of a vulnerability
10
class dangerous{
int *ptr;
}
class dangerous{
int *ptr;
}
001010…0110
ATTACKER
Serialize DeserializeMEDIA
VICTIM
#RSAC
Example of a vulnerability
11
class dangerous{
int *ptr;
}
class dangerous{
int *ptr;
}
001010…0110
ATTACKER
Serialize DeserializeMEDIA
= 0x66666666 = 0x66666666
VICTIM
#RSAC
Vulnerability Root Cause
12
ObjectInputStream ois = new ObjectInputStream(insecureSource);
dangerous t = (dangerous)ois.readObject();
callNative(t.ptr)
RECIPIENT CODE
#RSAC
History of Serialization Vulnerabilities
13
2009 - Shocking News in PHP Exploitation2011 - Spring Framework Serialization-based remoting vulnerabilities2012 - AtomicReferenceArray type confusion vulnerability2013 - Apache Commons FileUpload Deserialization Vulnerability
- Ruby on Rails YAML Deserialization Code Execution2014 - Android <5.0 Privilege Escalation using ObjectInputStream2015 - Android OpenSSLX509Certificate Deserialization Vulnerability
- Apache Groovy Deserialization of Untrusted Data- Apache Commons Collections Unsafe Classes
#RSAC
History of Serialization Vulnerabilities
14
2009 - Shocking News in PHP Exploitation2011 - Spring Framework Serialization-based remoting vulnerabilities2012 - AtomicReferenceArray type confusion vulnerability2013 - Apache Commons FileUpload Deserialization Vulnerability
- Ruby on Rails YAML Deserialization Code Execution2014 - Android <5.0 Privilege Escalation using ObjectInputStream2015 - Android OpenSSLX509Certificate Deserialization Vulnerability
- Apache Groovy Deserialization of Untrusted Data- Apache Commons Collections Unsafe Classes
#RSAC
Previous work
CVE-2014-7911 (Jann Horn):
Non-SerializableClasses can be Deserializedon target.
#RSAC
Exploiting CVE-2014-7911
23
MALWARE
SYSTEM_SERVER
Step 2. Send target a ‘serialized’ object in a Bundle
Serialized Objectof
non-Serializable class
#RSAC
The Serialized Object
24
final class BinderProxy implements IBinder {
private long mOrgue; POINTER…
private native final destroy();
@Overrideprotected void finalize() throws Throwable{
try { destroy(); }finally { super.finalize(); }
}
#RSAC
The Serialized Object
29
final class BinderProxy implements IBinder {
private long mOrgue; POINTER…
private native final destroy();
@Overrideprotected void finalize() throws Throwable{
try { destroy(); }finally { super.finalize(); }
}
#RSAC
Exploiting CVE-2014-7911
30
MALWARE
SYSTEM_SERVER
Step 3. Make it deserialize on the target
Deserializedobject
#RSAC
Make it deserialize automatically
31
public String getString(String key)}
unparcel(); DESERIALIZES ALLfinal Object o = mMap.get(key);try { return (String) o; }catch (ClassCastException e)
{typeWarning…} }
All Bundle members are deserialized with a single ‘touch’ without type checking before deserialization
e.g.
#RSAC
Exploiting CVE-2014-7911
32
MALWARE
SYSTEM_SERVER
Step 4. Make one of its methods execute on target.
Executed Method of object
#RSAC
The Serialized Object
33
final class BinderProxy implements IBinder {
private long mOrgue; …
private native final destroy();
@Overrideprotected void finalize() throws Throwable{
try { destroy(); }finally { super.finalize(); }
}
EXECUTEDAUTOMATICALLY BY THE GC
#RSAC
The Serialized Object
37
final class BinderProxy implements IBinder {
private long mOrgue; …
private native final destroy();
@Overrideprotected void finalize() throws Throwable{
try { destroy(); }finally { super.finalize(); }
}
EXECUTEDAUTOMATICALLY BY THE GC
#RSAC
The Serialized Object
38
final class BinderProxy implements IBinder {
private long mOrgue; …
private native final destroy();
@Overrideprotected void finalize() throws Throwable{
try { destroy(); }finally { super.finalize(); }
}
NATIVE METHODTHAT USES THE PTR
#RSAC
Our Research Question
41
Class Foo implements Serializable {
private long mObject;…private native final destroy();
@Overrideprotected void finalize() throws Throwable{try { destroy(); }finally { super.finalize();
}}
CONTROLLABLEPOINTER
POINTER USED IN NATIVE CODE.
EXECUTED AUTOMATICALLY BY THE GC
#RSAC
Experiment 1
46
boot.artApp: Loaded classes using
Reflection
~13K Loadable
Java Classes
Dumped classes:1. Serializable2. Finalize method3. Controllable fields
#RSAC
public class OpenSSLX509Certificateextends X509Certificate {
private final long mContext;
@Overrideprotected void finalize() throws Throwable{...
NativeCrypto.X509_free(mContext);...
}}
The Result
48
#RSAC
public class OpenSSLX509Certificateextends X509Certificate {
private final long mContext;
@Overrideprotected void finalize() throws Throwable{...
NativeCrypto.X509_free(mContext);...
}}
The Result
49
(1) SERIALIZABLE
#RSAC
public class OpenSSLX509Certificateextends X509Certificate {
private final long mContext;
@Overrideprotected void finalize() throws Throwable{...
NativeCrypto.X509_free(mContext);...
}}
The Result
50
(1) SERIALIZABLE
(2) CONTROLLABLEPOINTER
#RSAC
public class OpenSSLX509Certificateextends X509Certificate {
private final long mContext;
@Overrideprotected void finalize() throws Throwable{...
NativeCrypto.X509_free(mContext);...
}}
The Result
51
(1) SERIALIZABLE
(2) CONTROLLABLEPOINTER
(3) EXECUTED AUTOMATICALLY BY THE GC
#RSAC
Arbitrary Decrement
52
NativeCrypto.X509_free(mContext)
X509_free(x509);
ASN1_item_free(x509, ...)
asn1_item_combine_free(&val, ...)
if (asn1_do_lock(pval, -1,...) > 0)return;
// x509 = mContext
// val = *pval = mContext
// Decreases a reference counter (mContext+𝟎𝐱𝟏𝟎) // MUST be POSITIVE INTEGER (MSB=𝟎)
#RSAC
Creating an Arbitrary Code Exec Exploit
59
ARSENAL
1. Arbitrary Decrement
2. Controlled Buffer
#RSAC
Constrained Arbitrary Memory Overwrite
60
Bundle
OpenSSLX509CertificatemContext=0𝑥11111100
∗ 0𝑥11111110 −= 1
#RSAC
Constrained Arbitrary Memory Overwrite
61
Bundle
OpenSSLX509CertificatemContext=0𝑥11111100
OpenSSLX509CertificatemContext=0𝑥11111100
∗ 0𝑥11111110 −= 2
#RSAC
Constrained Arbitrary Memory Overwrite
62
Bundle
OpenSSLX509CertificatemContext=0𝑥11111100
OpenSSLX509CertificatemContext=0𝑥11111100
OpenSSLX509CertificatemContext=0𝑥11111100
⋮
∗ 0𝑥11111110 −= 𝑛
#RSAC
Constrained Arbitrary Memory Overwrite
63
Bundle
OpenSSLX509CertificatemContext=0𝑥11111100
OpenSSLX509CertificatemContext=0𝑥11111100
OpenSSLX509CertificatemContext=0𝑥11111100
⋮
∗ 0𝑥11111110 −= 𝑛
and If we knew the original value:
Arbitrary Overwrite
#RSAC
Creating an Arbitrary Code Exec Exploit
64
ARSENAL
1. Arbitrary Decrement
2. Controlled Buffer
3. Arbitrary Overwrite
(if we knew the original value)
#RSAC
Creating an Arbitrary Code Exec Exploit
65
ARSENAL DEFENSES
1. Arbitrary Decrement
2. Controlled Buffer
3. Arbitrary Overwrite
(if we knew the original value)
1. ASLR
2. RELRO
3. NX pages
4. SELinux
#RSAC
Finding the original value: observation
system_server malwareroot@generic:/# cat /proc/<system_server>/maps
70e40000-72cee000 r—p ... boot.oat72cee000-74400000 r-xp ... boot.oat74400000-74401000 rw-p ... boot.oat…aa09f000-aa0c3000 r-xp ... libjavacrypto.soaa0c3000-aa0c4000 r--p ... libjavacrypto.soaa0c4000-aa0c5000 rw-p ... libjavacrypto.so…b6645000-b66d5000 r-xp ... libcrypto.sob66d6000-b66e1000 r--p ... libcrypto.sob66e1000-b66e2000 rw-p ... libcrypto.so
root@generic:/# cat /proc/<malware>/maps
70e40000-72cee000 r—p ... boot.oat72cee000-74400000 r-xp ... boot.oat74400000-74401000 rw-p ... boot.oat…aa09f000-aa0c3000 r-xp ... libjavacrypto.soaa0c3000-aa0c4000 r--p ... libjavacrypto.soaa0c4000-aa0c5000 rw-p ... libjavacrypto.so…b6645000-b66d5000 r-xp ... libcrypto.sob66d6000-b66e1000 r--p ... libcrypto.sob66e1000-b66e2000 rw-p ... libcrypto.so
#RSAC
Zygote app creation model
fork()
fork()
fork()
fork()fork without execve= no ASLR!
Zygote system_server
App_1
App_N
malware
#RSAC
Determining the value
fork()
fork()
<libXYZ> value
Zygote system_server
malware
<libXYZ> value
<libXYZ> value
#RSAC
Creating an Arbitrary Code Exec Exploit
69
ARSENAL DEFENSES
1. Arbitrary Decrement
2. Controlled Buffer
3. Arbitrary Overwrite
(if we knew the original value)
1. ASLR
2. RELRO
3. NX pages
4. SELinux
#RSAC
Using the Arbitrary Overwrite
70
Goal.
Overwite some pointer
Problem.
.got is read only (RELRO)
#RSAC
A Good Memory Overwrite Target
71
A function pointer under .data
id_callback in libcrypto
Called during deserialization of:
OpenSSLECPrivateKey
#RSAC
Triggering id_callback remotely
72
Bundle
system_serverOpenSSLECPrivateKey
BAD DATAthat leads to the right path
Malware
#RSAC
Creating an Arbitrary Code Exec Exploit
74
ARSENAL DEFENSES
1. Arbitrary Decrement
2. Controlled Buffer
3. Arbitrary Overwrite
(if we knew the original value)
1. ASLR
2. RELRO
3. NX pages
4. SELinux
#RSAC
Next Steps of the PoC Exploit (simplified)
75
system_server
pc→ r-x coderw- stackrw- ROP chain rw- shellcode
sp→
#RSAC
Problem 1: SP does not point at ROP chain
76
system_server
pc→ r-x coderw- stackrw- ROP chain rw- shellcode
sp→
#RSAC
Solution: Stack Pivoting
77
system_server
pc→ r-x code/pivotrw- stackrw- ROP chain rw- shellcode
sp→
Our buffer happens to be pointed by fp.The Gadget: mov sp, fp; …, pop {…}
Gadget:Stack Pivot
fp→
#RSAC
Solution: Stack Pivoting
78
system_server
pc→ r-x code/pivotrw- stackrw- ROP chain rw- shellcode
sp→
Our buffer happens to be pointed by fp.The Gadget: mov sp, fp; …, pop {…}
Gadget:Stack Pivot
#RSAC
Allocating RWX Memory
79
system_server
pc→ r-x code/mmaprw- stackrw- ROP chain rw- shellcode
sp→
Gadget:Stack Pivot
fp→
Gadget:mmap/RWX
#RSAC
Problem 2: SELinux should prohibit mmap/RWX
80
system_server
pc→ r-x code/mmaprw- stackrw- ROP chain rw- shellcode
sp→
Gadget:Stack Pivot
fp→
Gadget:mmap/RWX
#RSAC
Solution: Weak SELinux Policy for system_server
81
system_server
pc→ r-x code/mmaprw- stackrw- ROP chain rw- shellcode
sp→
Gadget:Stack Pivot
fp→
Gadget:mmap/RWX
#RSAC
Solution: Weak SELinux Policy for system_server
82
system_server
pc→ r-x code/mmaprw- stackrw- ROP chain rw- shellcode
sp→
Gadget:Stack Pivot
fp→
Gadget:mmap/RWX
allow system_server self:process execmem
#RSAC
Allocating RWX Memory
83
system_server
pc→ r-x code/mmaprw- stackrw- ROP chain rw- shellcoderwx -
sp→
Gadget:Stack Pivot
Gadget:mmap/RWX
#RSAC
Copying our Shellcode
84
system_server
pc→ r-x code/memcpy
rw- stackrw- ROP chain rw- shellcoderwx -
sp→
Gadget:Stack Pivot
Gadget:mmap/RWX
Gadget:memcpy
#RSAC
Copying our Shellcode
85
system_server
pc→ r-x code/memcpy
rw- stackrw- ROP chain rw- shellcoderwx shellcode
sp→
Gadget:Stack Pivot
Gadget:mmap/RWX
Gadget:memcpy
#RSAC
Executing our Shellcode
86
system_server
pc→
r-x coderw- stackrw- ROP chain rw- shellcoderwx shellcode
sp→
Gadget:Stack Pivot
Gadget:mmap/RWX
Gadget:memcpy
shellcode
#RSAC
Creating an Arbitrary Code Exec Exploit
87
ARSENAL DEFENSES
1. Arbitrary Decrement
2. Controlled Buffer
3. Arbitrary Overwrite
(if we knew the original value)
1. ASLR
2. RELRO
3. NX pages
4. SELinux
#RSAC
Shellcode
88
REPLACEMENT OF APPS
SELINUX
BYPASS
ACCESS TO APPS’ DATA
KERNEL CODE EXEC
(on select devices)
Runs as system, still subject to the SELinux, but can:
#RSAC
Google’s Patch for CVE-2015-3825
90
public class OpenSSLX509Certificateextends X509Certificate {
private transient final long mContext;…
}
MISSING MODIFIERBEFORE OURDISCLOSURE!
(NOW PATCHED)
#RSAC
Finding Similar Vulnerabilities in SDKs
Goal. Find vulnerable Serializable classes in 3rd-party SDKs
Why. Fixing the Android Platform Vulnerability is not enough. Apps can be exploited as well!
#RSAC
Experiment 2
95
Analyzed over 32K of popular Android apps
Main Results
CVE-2015-2000 Jumio SDK Code Exec.CVE-2015-2001 MetaIO SDK Code Exec.CVE-2015-2002 Esri ArcGis SDK Code Exec.CVE-2015-2003 PJSIP PJSUA2 SDK Code Exec.CVE-2015-2004 GraceNote SDK Code Exec.CVE-2015-2020 MyScript SDK Code Exec.
#RSAC
Root Cause (for most of the SDKs)
96
SWIG, a C/C++ to Java interoperability tool, can generate vulnerable classes.
public class Foo implements Bar {private long swigCPtr;protected boolean swigCMemOwn;...protected void finalize() {
delete();}public synchronized void delete() {
…exampleJNI.delete_Foo(swigCPtr); …
}...
}
CONTROLLABLEPOINTER
POINTER USED IN NATIVE CODE
POSSIBLYSERIALIZABLE
#RSAC
Apps are in a bad place
Vulnerable apps are still out there.
SDKs need to be updated by app developers.
Dozens of apps still use them! (as of Feb ‘16)
New vulnerable apps can emerge
Developers can introduce their own vulnerable classes.
#RSAC
Apps are in a bad place
Exploitation
Still no type-checking by Android before deserialization.
ASLR can still be defeated when malware attacks Zygote forked processes.
As opposed to system_server, The SELinux policy hasn’t been hardened for the apps domain.
#RSAC
Summary
Found a high severity vulnerability in Android (Exp. 1).
Wrote a reliable PoC exploit against it.
Found similar vulnerabilities in 6 third-party SDKs (Exp. 2).
Patches are available for all of the vulnerabilities and also for SWIG.
Consumers: Update your Android.
Developers:
Update your SDKs.
Do not create vuln. Serializable classes. Use transient when needed!
#RSAC
References
Paper. https://www.usenix.org/conference/woot15/workshop-program/presentation/peles
Video. https://www.youtube.com/watch?v=VekzwVdwqIY
Nexus Security Bulletin. https://source.android.com/security/bulletin/2015-08-01.html
AOSP Patch. https://android.googlesource.com/platform/external/conscrypt/+/edf7055461e2d7fa18de5196dca80896a56e3540
OpenSSLX509CertificateChecker.https://play.google.com/store/apps/details?id=roeeh.conscryptchecker
Top Related