Watch you lookin’ at? Good • Permissions model well implemented • App removal • Logging •...

84
Labs.mwrinfosecurity.com | © MWR Labs Watch you lookin’ at? 27 Feb 2015 A look at the security of Android Wear

Transcript of Watch you lookin’ at? Good • Permissions model well implemented • App removal • Logging •...

Labs.mwrinfosecurity.com | © MWR Labs 1

Labs.mwrinfosecurity.com | © MWR Labs

Watch you lookin’ at?

27 Feb 2015

A look at the security of Android Wear

Labs.mwrinfosecurity.com | © MWR Labs 2

Labs.mwrinfosecurity.com | © MWR Labs 3

Labs.mwrinfosecurity.com | © MWR Labs 4

Who are we?

Jahmel Harris

Owen Evans

Security Researchers and Consultants – MWR InfoSecurity

Labs.mwrinfosecurity.com | © MWR Labs 5

Part one:

- Brief overview of wear security / minor findings

- Application deployment & execution

- Notification fun

Part two:

- Overview of Android wear internals

- Future research

Labs.mwrinfosecurity.com | © MWR Labs 6

Let’s begin…

The Good

• Permissions model well implemented

• App removal

• Logging

• Same as regular android… mostly

The Bad…

• No lock screen

• BTLE – broken [1]

• No message level encryption

• Easy to crash the device

• Undermine company policies

(BYOD / MDM)

[1] Mike Ryan, iSecPartners, BlackHat 2013:

https://www.isecpartners.com/media/105670/bluetooth_smart_good_bad_ugly_fix-mikeryan-blackhat_2013.pdf

Labs.mwrinfosecurity.com | © MWR Labs 7

Application deployment

Packaging

• No ‘wear appstore’

• Wear applications have mobile

counterpart

• Wear applications packaged within

mobile applications

• No user notifications! – Silent

deployment

Android_app.apk - AndroidManifest.xml - Classes.dex - /META-INF/ - /res/ - Resources.arsc

android_wear_micro_apk.apk - AndroidManifest.xml - Classes.dex - /META-INF/ - /res/ - Resources.arsc

Labs.mwrinfosecurity.com | © MWR Labs 8

Improving on silent deployment

Hiding the app from the menu

• Remove the following from AndroidManifest.xml:

– <category android:name="android.intent.category.LAUNCHER" />

Executing some code

• Since Android 3.1 – Apps installed in ‘stopped’ state.

• Auto-starting code – Historically, code started by registering broadcast receivers

• We’ve been working on a way to bypass this… but

Labs.mwrinfosecurity.com | © MWR Labs 9

Quick Recap

So…

Bring it together:

• Smuggled a wearable application onto a users device inside a normal .apk

• (Without them knowing!)

• Hidden the application by removing the manifest entry

• Automatic code execution

• Demo?

Labs.mwrinfosecurity.com | © MWR Labs 10

Using wear to facilitate attacks

Notifications

Some other stuff

• Notifications are a primary function of android wear

• Written in basically the same way as normal

• What does a wear notification look like?

Labs.mwrinfosecurity.com | © MWR Labs 11

Spoofing a notification

What does wear have to offer?

• Images

• Interactivity / additional layer of trust

• Demands / Actions

What can we do to spoof?

• Set Title / message to look the same

• Icons can be obtained from legitimate applications .apk

Labs.mwrinfosecurity.com | © MWR Labs 12

Building our spoofed notification

The Intent:

The Notification: // build notification object Notification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.some.icon) .setContentTitle(someTitle) .setContentText(someBody) .addAction(R.drawable.some.other.icon, "Update Payment Details", demandPendingIntent) .build();

Intent demandIntent = new Intent(Intent.ACTION_VIEW); demandIntent.setData(Uri.parse(someURL)); PendingIntent demandPendingIntent = PendingIntent.getActivity(this, 0, demandIntent, 0);

Labs.mwrinfosecurity.com | © MWR Labs 13

So lets compare our notifications…

Real: Fake:

Labs.mwrinfosecurity.com | © MWR Labs 14

Quick recap

So…

Bring it together:

• (Having silently deployed an .apk, hidden it and started code execution…)

• Build a notification, using icons retrieved from legitimate app, setting text to

something convincing

• Add a demand / action screen for the wearable notification

• Link the action to something interesting (URI.parse intent)

• Open our malicious link in the browser on the phone

• Demo?

Labs.mwrinfosecurity.com | © MWR Labs 15

Brief Summary

We’ve looked at:

• Brief overview of android wear – quick security points

• How applications are installed (silently)

• Launching code

• Using wear for phishing attacks

And now over to Jahmel…

Labs.mwrinfosecurity.com | © MWR Labs 16

Android Wear internals

Labs.mwrinfosecurity.com | © MWR Labs 17

WearableListenerService

WearableListenerService

GoogleAPI

GoogleAPI

/path

/path

Labs.mwrinfosecurity.com | © MWR Labs 18

ClockworkHomeGoogle

Settings Media Controls Incoming Calls

WearableListenerService

WearableService

Labs.mwrinfosecurity.com | © MWR Labs 19

<service name=“MyWearableListenerService">

<intent-filter>

<action

name="com.google.android.gms.wearable.BIND_LISTENER">

</action>

</intent-filter>

</service>

Labs.mwrinfosecurity.com | © MWR Labs 20

Labs.mwrinfosecurity.com | © MWR Labs 21

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 22

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 23

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 24

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 25

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 26

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 27

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 28

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 29

Exploring Wear

Labs.mwrinfosecurity.com | © MWR Labs 30

Our goal:

Send a message to ANY app on the

wearable.

Labs.mwrinfosecurity.com | © MWR Labs 31

• Bind to WearableListenerService

• Bind to WearableService

• Send data over Bluetooth

Labs.mwrinfosecurity.com | © MWR Labs 32

• Bind to WearableListenerService

• Bind to WearableService

• Send data over Bluetooth

Labs.mwrinfosecurity.com | © MWR Labs 33

MusicWearListenerService

Labs.mwrinfosecurity.com | © MWR Labs 34

Labs.mwrinfosecurity.com | © MWR Labs 35

OnPeerDisconnected()

Event: Peer Disconnected

Labs.mwrinfosecurity.com | © MWR Labs 36

OnPeerDisconnected()

Labs.mwrinfosecurity.com | © MWR Labs 38

WearableListenerService

onMessageReceived

onPeerConnected

onDataChanged

onPeerDisconnected

class MusicWearListenerService extends WearableDataListenerService

class WearableDataListenerService extends WearableListenerService

Labs.mwrinfosecurity.com | © MWR Labs 39

Malware Google Play Service

Labs.mwrinfosecurity.com | © MWR Labs 40

BindToService()

{

Intent intent = new Intent();

intent.setClassName("com.google.android.music","com.g

oogle.android.music.MusicWearListenerService");

this.bindService(intent,connection,Context.BIND_AUTO_

CREATE);

}

Labs.mwrinfosecurity.com | © MWR Labs 41

private ServiceConnection connection = new

ServiceConnection()

{

public void onServiceConnected(ComponentName

className, Binder service )

{

Log.d(TAG, "onServiceConnected:

"+className.getClassName);

}

Labs.mwrinfosecurity.com | © MWR Labs 42

…..

Labs.mwrinfosecurity.com | © MWR Labs 43

public final IBinder onBind(Intent paramIntent)

{

if

("com.google.android.gms.wearable.BIND_LISTENER".equals(paramInt

ent.getAction()))

return this.Qv;

return null;

}

WearableListenerService.java

Labs.mwrinfosecurity.com | © MWR Labs 44

BindToService()

{

Intent intent = new Intent();

intent.setClassName("com.google.android.music","com.g

oogle.android.music.MusicWearListenerService");

this.bindService(intent,connection,Context.BIND_AUTO_

CREATE);

}

Labs.mwrinfosecurity.com | © MWR Labs 45

BindToService()

{

Intent intent = new Intent();

intent.setClassName("com.google.android.music","com.g

oogle.android.music.MusicWearListenerService");

intent.setAction("com.google.android.gms.wearable.BIN

D_LISTENER");

this.bindService(intent,connection,Context.BIND_AUTO_

CREATE);

}

Labs.mwrinfosecurity.com | © MWR Labs 46

BindToService()

{

Intent intent = new Intent();

intent.setClassName("com.google.android.music","com.go

ogle.android.music.MusicWearListenerService");

intent.setAction("com.google.android.gms.wearable.BIND

_LISTENER");

this.bindService(intent,connection,Context.BIND_AUTO_C

REATE);

}

Labs.mwrinfosecurity.com | © MWR Labs 47

Labs.mwrinfosecurity.com | © MWR Labs 48

???

Labs.mwrinfosecurity.com | © MWR Labs 49

public final IBinder onBind(Intent paramIntent)

{

if

("com.google.android.gms.wearable.BIND_LISTENER".equals(paramInt

ent.getAction()))

return this.Qv;

return null;

}

private IBinder Qv;

this.Qv = new a(null);

WearableListenerService.java

private class a extends ae.a

{

public void a(final ai paramai){}

public void a(final al paramal){}

public void aa(final DataHolder

paramDataHolder){}

public void b(final al paramal){}

}

Labs.mwrinfosecurity.com | © MWR Labs 51

public void a(final ai paramai) {

if (Log.isLoggable("WearableLS", 3))

Log.d("WearableLS", "onMessageReceived: " + paramah);

}

public void a(final al paramal) {

if (Log.isLoggable("WearableLS", 3))

Log.d("WearableLS", "onPeerConnected: “

}

Labs.mwrinfosecurity.com | © MWR Labs 52

public void aa(final DataHolder paramDataHolder) {

if (Log.isLoggable("WearableLS", 3))

Log.d("WearableLS", "onDataItemChanged: "

}

public void b(final al paramal) {

if (Log.isLoggable("WearableLS", 3))

Log.d("WearableLS", "onPeerDisconnected: "

}

Labs.mwrinfosecurity.com | © MWR Labs 53

WearableListenerService

onMessageReceived

onPeerConnected

onDataChanged

onPeerDisconnected

Labs.mwrinfosecurity.com | © MWR Labs 54

WearableListenerService

a(final ai paramai)

a(final al paramal)

aa(final DataHolder paramDataHolder)

b(final al paramal)

Labs.mwrinfosecurity.com | © MWR Labs 57

public void onServiceConnected(ComponentName className, Binder

service )

{

Log.d(TAG, "onServiceConnected: "+className.getClassName);

ae my_ae = ae.a.bY(service);

my_ae.aa(null);

}

IWearableListenerService.Stub.asInterface(service);

Labs.mwrinfosecurity.com | © MWR Labs 58

W/Binder ( 962): Caught a RuntimeException from the

binder stub implementation.

W/Binder ( 962): java.lang.SecurityException: Caller is not

GooglePlayServices

Labs.mwrinfosecurity.com | © MWR Labs 59

private void rl()

throws SecurityException

{

int i = Binder.getCallingUid();

if (i == this.Pj)

return;

if ((GooglePlayServicesUtil.b(getPackageManager(), "com.google.android.gms")) && (bh(i)))

{

this.Pj = i;

return;

}

throw new SecurityException("Caller is not GooglePlayServices");

}

Labs.mwrinfosecurity.com | © MWR Labs 60

.method static synthetic b(Lcom/google/android/gms/wearable/WearableListenerService;)V

.locals 0

.annotation system Ldalvik/annotation/Throws;

value = {

Ljava/lang/SecurityException;

}

.end annotation

invoke-direct {p0}, Lcom/google/android/gms/wearable/WearableListenerService;->rl()V

return-void

.end method

Labs.mwrinfosecurity.com | © MWR Labs 61

public void aa(final DataHolder paramDataHolder) {

if (Log.isLoggable("WearableLS", 3))

Log.d("WearableLS", "onDataItemChanged: " +

WearableListenerService.a(WearableListenerService.this) + ": " +

paramDataHolder);

WearableListenerService.b(WearableListenerService.this);

}

Labs.mwrinfosecurity.com | © MWR Labs 62

OnPeerDisconnected()

Labs.mwrinfosecurity.com | © MWR Labs 63

• Bind to WearableListenerService

• Bind to WearableService

• Send data over Bluetooth

Labs.mwrinfosecurity.com | © MWR Labs 64

Labs.mwrinfosecurity.com | © MWR Labs 65

MusicWearListenerService

WearableService

WearableService Google API

Labs.mwrinfosecurity.com | © MWR Labs 66

WearableService

Labs.mwrinfosecurity.com | © MWR Labs 70

my_jt.e(my_js,1,"com.google.android.music");

Labs.mwrinfosecurity.com | © MWR Labs 71

W/AppOps ( 1077): Bad call: specified package

com.google.android.music under uid 10203 but it is really 10082

E/AndroidRuntime(13094): FATAL EXCEPTION: main

E/AndroidRuntime(13094): Process:

com.example.harrisj.servicetest, PID: 13094

E/AndroidRuntime(13094): java.lang.SecurityException: Unknown

calling package name 'com.google.android.music'.

Labs.mwrinfosecurity.com | © MWR Labs 72

WearableService

Labs.mwrinfosecurity.com | © MWR Labs 73

• Bind to WearableListenerService

• Bind to WearableService

• Send data over Bluetooth

Labs.mwrinfosecurity.com | © MWR Labs 74

BluetoothSocket

OutputStream

BluetoothSocket

InputStream

Labs.mwrinfosecurity.com | © MWR Labs 75

BluetoothSocket

OutputStream

BluetoothSocket

InputStream

Labs.mwrinfosecurity.com | © MWR Labs 77

Labs.mwrinfosecurity.com | © MWR Labs 78

[package name] wear://nodeid/path data

[signature_of_package]

Labs.mwrinfosecurity.com | © MWR Labs 79

INTRODUCING…

…….

Labs.mwrinfosecurity.com | © MWR Labs 80

Data

Modified

Data

Labs.mwrinfosecurity.com | © MWR Labs 81

Data

Modified

Data

Labs.mwrinfosecurity.com | © MWR Labs 82

com.app.app1

/path

aa:bb:cc:dd

com.app.app1

/path

aa:bb:cc:dd

com.zzz.app2

/path

11:22:33:44

Labs.mwrinfosecurity.com | © MWR Labs 83

com.app.app1 wear://nodeid/path data aa:bb:cc:dd

Labs.mwrinfosecurity.com | © MWR Labs 84

com.app.app1

/path

aa:bb:cc:dd

com.app.app1

/path

aa:bb:cc:dd

com.zzz.app2

/path

11:22:33:44

Labs.mwrinfosecurity.com | © MWR Labs 85

com.zzz.app2 wear://nodeid/path data aa:bb:cc:dd

Labs.mwrinfosecurity.com | © MWR Labs 86

W/WearableService( 629): ensureBindStarted: app does

not match record's app key:

AppKey[com.app.app1,aabbccdd] !=

AppKey[com.zzz.app2,11223344]

Labs.mwrinfosecurity.com | © MWR Labs 87

com.app.app1

/path

aa:bb:cc:dd

com.app.app1

/path

aa:bb:cc:dd

com.zzz.app2

/path

11:22:33:44

Labs.mwrinfosecurity.com | © MWR Labs 88

com.zzz.app2 wear://nodeid/path data 11:22:33:44

Labs.mwrinfosecurity.com | © MWR Labs 89

com.app.app1

/path

aa:bb:cc:dd

com.app.app1

/path

aa:bb:cc:dd

com.zzz.app2

/path

11:22:33:44

Labs.mwrinfosecurity.com | © MWR Labs 90

Demo

Labs.mwrinfosecurity.com | © MWR Labs 91

Still more research to do. On other wearables, on other

attack vectors.

Need root access to use this tool. Can be good for

assessing wearable applications.

We can’t trust data being sent to/from device.