Joshua Brindle

How to Win At Security

SE for Android GS4 howto and exploit demo

The client

I've uploaded my changes to the SEAdmin client to bitbucket (be sure to check out the samsung-API branch) for brave souls who want to experiment with this. I also have an apk for those who don't want to build their own. This must be installed to the system partition in order to work. It is also crazy hacked together so don't blame me if your phone blows up.

After rooting your phone with something like motochopper put the apk onto /system:

$ adb push SEAndroidAdminActivity.apk /sdcard/
2146 KB/s (758399 bytes in 0.345s)

$ adb shell
shell@android:/ $ su
su
root@android:/ # mount -orw,remount /system
mount -orw,remount /system
root@android:/ # cp /sdcard/SEAndroidAdminActivity.apk /system/app

If it doesn't show up in your app list go ahead and reboot.

root@android:/ # reboot

Run it and enable it as a device administrator by sliding the top slider and hitting activate. It isn't technically a device admin anymore but I didn't disable that code.

After that go to SELinux Administration:

SELinux Administration - permissive

Before you click on enforce it is a good idea to get an adb shell running as system so that you don't have to continually reboot your device:

$ adb shell
shell@android:/ $ su
su
root@android:/ # runcon u:r:system:s0 sh
runcon u:r:system:s0 sh
root@android:/ # id -Z
id -Z
uid=0(root) gid=0(root) context=u:r:system:s0

We are all set, go ahead and click enforce:

SELinux Administration - enforcing

It will be checked now, unfortunately if you leave this screen and come back it won't be checked. This is due to the app not having permission to check enforcing status. You can always check whether you are enforcing by going to settings->More->About Device and scrolling to the bottom:

SELinux settings

The exploit

Now, lets try to run motochopper on an phone in enforcing:

$ ./run.sh 
<snip>
[*] 
[*] Waiting for device...
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
[*] Device found.
[*] Pushing exploit...
4382 KB/s (1283460 bytes in 0.286s)
[*] Pushing root tools...
5119 KB/s (366952 bytes in 0.070s)
4373 KB/s (1867568 bytes in 0.417s)
        pkg: /data/local/tmp/Superuser.apk
Success
4520 KB/s (1578585 bytes in 0.341s)
[*] Rooting phone...
[+] This may take a few minutes.
[-] Failure.
[*] Cleaning up...
[*] Exploit complete. Press enter to reboot and exit.
Press any key to continue . . .   

As you can see it failed.

Howto

You can continue running it with the default policy but apps that require root will not work. If you are interested in working on the policy you can use adb to pull it:

$ adb pull /sepolicy
3379 KB/s (134977 bytes in 0.039s)

And then use the policy injector to add rules. Afterward you'll need to reload the policy manually:

$ adb push sepolicy /sdcard/
3138 KB/s (134977 bytes in 0.042s)

Then on your system shell (you did keep a system shell handy, right?)

# cd /data/security
# cp /sdcard/sepolicy .
# setprop selinux.reload_policy 1

The system shell can also toggle enforcing and permissive (I know, that would have been easier than using a client but I wanted to see what real support there was first)

root@android:/ # setenforce 0
setenforce 0
root@android:/ # getenforce
getenforce
Permissive
root@android:/ # setenforce 1
setenforce 1
root@android:/ # getenforce
getenforce
Enforcing

Without denials working on the policy will be quite tedious. Hopefully I'll be able to post a modified kernel soon to turn auditing back on. In the mean time, have fun.