Category Archives: Android

Android Master-Key Malware Already Blocked by McAfee Mobile Security

The Android Master Key vulnerability, which was first reported by BlueBox Security, has been big news this month. McAfee explained the vulnerability and defense against future malware exploiting it in a previous blog.

Last week the first malware that exploit the Master Key vulnerability were found in an Android application market in China. The app used the vulnerability to hide the malicious classes.dex from Android’s package signature verification.

 

exploit-masterkey-1

 

This vulnerability allows an attacker to inject malicious code by putting duplicate executable files–such as classes.dex–in an application package. The package verification step at installation is done against the original, legitimate file, but at runtime the second, malicious file takes over. The attacker’s malicious code in the second classes.dex collects and sends the device’s sensitive information to remote servers and also sends SMS messages to those who are in the victim’s contact list. A second AndroidManifest.xml file, corresponding to the second classes.dex, replaces the legitimate .xml so that additional permission declarations are injected along with several broadcast receivers and services registrations.

 

exploit-masterkey-2

 

The only good news might be that at installation users can see the list of requested permissions that are declared in the second AndroidManifest.xml; so they might at least notice the excessive permission requests.

McAfee provided its solution, via McAfee Mobile Security, to this threat before the first malware appeared in the wild, proactively detecting and blocking this threat as Exploit/MasterKey.A. The solution should also work against future variants of this Master Key malware.

 

exploit-masterkey-3

The post Android Master-Key Malware Already Blocked by McAfee Mobile Security appeared first on McAfee Blogs.

Building a wireless Android device using BeagleBone Black

Our previous posts were about code signing in Android, and they turned out to be surprisingly relevant with the announcement of the ‘master key’ code signing Android vulnerability. While details are yet to be formally released, it has been already patched and dissected, so we’ll skip that one and try something different for a change. This post is not directly related to Android security, but will discuss some Android implementation details, so it might be of some interest to our regular readers. Without further ado, let’s get closer to the metal than usual and build a wireless Android device (almost) from scratch.

Board introduction — BeagleBone Black

For our device we’ll use the recently released BeagleBone Black board. So what is a BeagleBone Black (let’s call it BBB from now on), then? It’s the latest addition to the ranks of ARM-based, single board credit-card-sized computers. It comes with an AM335x 1GHz ARM Cortex-A8 CPU, 512MB RAM,  2GB on-board eMMC flash, Ethernet, HDMI and USB ports, plus a whole lot of I/O pins. Best of all, it’s open source hardware, and all schematics and design documents are freely available. It’s hard to beat the price of $45 and it looks much, much better than the jagged Raspberry Pi. It comes with Angstrom Linux pre-installed, but can run pretty much any Linux flavour, and of course, Android. It is being used for anything from blinking LEDs to tracking satellites. You can hook it up to circuits you’ve build or quickly extend it using one of the many ‘cape‘ plug-in boards available. We’ll use a couple of those for our project, so ‘building’ refers mostly to creating an Android build compatible with our hardware. We’ll detail the hardware later, but let’s first outline some simple requirements for our mobile Android device:
  1. touch screen input
  2. wireless connectivity via WiFi
  3. battery powered
Here’s what we start with:

Building a kernel for Android

Android support for AM335x-based devices is provided by the rowboat project. It integrates the required kernel and OS patches and provides build configurations for each of the supported devices, including the BBB. The latest version is based on Android 4.2.2 and if you want to get started quickly, you can download a binary build from TI’s Sitara Android development kit page. All you need to do is flash it to an SD card, connect the BBB to an HDMI display and power it on. You will instantly get a fully working, hardware-accelerated Jelly Bean 4.2 device you can control using standard USB keyboard and mouse. If that is all you need, you might as well stop reading here. Our first requirement, however is a working touch screen, not an HDMI monitor, so we have some work to do. As it happens, a number of LCD capes are already available for the BBB (from circuitco and others), so those are our first choice. We opted for the LCD4 4.3″ cape which offers almost reasonable resolution and is small enough to be directly attached to the BBB. Unfortunately it doesn’t work with the rowboat build from TI. To understand why, let’s take a step back and discuss how the BBB supports extension hardware, including capes.

Linux Device Tree and cape support

If you look at the expansion header pinout table in the BBB reference manual, you will notice that each pin can serve multiple purposes, depending on configuration. This is called ‘pinmuxing’ and is the method modern SoC’s use to multiplex multiple peripheral functions to a limited set of physical pins. The AM335x CPU the BBB uses is no exception: it has pins with up to 8 possible peripheral functions. So, in order for a cape to work, the SoC needs to be configured to use the correct inputs/outputs for that cape. The situation becomes more complicated when you have multiple capes (up to 4 at a time). BBB capes solve this by using EEPROM that stores enough data to identify the cape, its revision and serial number. At boot time, the kernel identifies the capes by reading their EEPROMs, computes the optimal configuration (or outputs and error if the connected capes are not compatible) and sets the expansion header pinmux accordingly. Initially, this was implemented in a ‘board file’ in the Linux kernel, and adding a new cape required modifying the kernel and making sure all possible cape configurations were supported. Needless to say, this is not an easy task, and getting it merged into Linux mainline is even harder. Since everyone is building some sort of ARM device nowadays, the number of board files and variations thereof reached critical mass, and Linux kernel maintainers decided to decouple board specific behaviour from the kernel. The mechanism for doing this is called Device Tree (DT) and its goal is to make life easier for both device developers (no need to hack the kernel for each device) and kernel maintainers (no need to merge board-specific patches every other day). A DT is a data structure for describing hardware which is passed to the kernel at boot time. Using the DT, a generic board driver can configure itself dynamically. The BBB ships with a 3.8 kernel and takes full advantage of the new DT architecture. Cape support is naturally implemented using DT source (DTS) files and even goes a step further than mainline Linux by introducing a Cape Manager, an in-kernel mechanism for dynamically loading Device Tree fragments from userspace. This allows for runtime (vs. boot time) loading of capes via sysfs, resource conflict resolution (where possible), manual control over already loaded capes and more.
Going back to Android, the rowboat Android port is using the 3.2 kernel and relies on manual porting of extension peripheral configuration to the kernel board file. As it happens, support for our LCD4 cape is not there yet. We could try to patch the kernel based on the 3.8 DTS files, or take the plunge and attempt to run Android using 3.8. Since all BBB active development is going on in the 3.8 branch, using the newer version is the better (if more involved) choice.

Using the 3.8 kernel

As we know, Android adds a bunch of ‘Androidisms’ to the Linux kernel, most notably wakelocks, alarm timers, ashmem, binder, low memory killer and ‘paranoid’ network security. Thus you could not use a vanilla Linux kernel as is to run Android until recently, and a number of Android-specific patches needed to be applied first. Fortunately, thanks to the Android Mainlining Project, most of these features are already merged (in one form or another) in the 3.8 kernel and are available as staging drivers. What this means is that we can take a 3.8 kernel that works well on the BBB and use it run Android. Unfortunately, the BBB can’t quite use a vanilla 3.8 kernel yet and requires quite a few patches (including Cape Manager). However, building a 3.8 kernel with all BBB patches applied is not too hard to do, thanks to instructions and build scripts by Robert Nelson. Even better, Andrew Henderson has successfully used it in Android and has detailed the procedure. Following Andrew’s build instructions, we can create an Android build that has a good chance of supporting our touch screen. As Andrew’s article mentions, hardware acceleration (support for the BBB’s PowerVR SGX 530 GPU) is not yet available for the 3.8 kernel, so we need to disable it in our build. One thing that is missing from Andrew’s instruction is that you also need to disable building and installing of the SGX drivers, otherwise Android will try to use them at boot and fail to start SurfaceFlinger due to driver-kernel module incompatibility. You can do this by commenting out the dependency on sgx in rowboat’s top-level Makefile like this:

@@ -11,7 +13,7 @@
CLEAN_RULE = sgx_clean wl12xx_compat_clean kernel_clean clean
else
ifeq ($(TARGET_PRODUCT), beagleboneblack)
-rowboat: sgx
+#rowboat: sgx
CLEAN_RULE = sgx_clean kernel_clean clean
else
ifeq ($(TARGET_PRODUCT), beaglebone)

Note that the kernel alone is not enough though: the boot loader (Das U-Boot) needs to be able to load the (flattened) device tree blob, so we need to build a recent version of that as well. Android seems to run OK with this configuration, but there are still a few things that are missing. The first you might notice is ADB support.

ADB support

ADB (Android Debug Bridge) is one of the best things to came out of the Android project, and if you have been doing Android development in any form for a while, you probably take it for granted. It is a fairly complex piece of software though, providing support for debugging, file transfer, port forwarding and more and requires kernel support in addition to the Android daemon and client application. In kernel terms this is known as the ‘Android USB Gadget Driver’, and it is not quite available in the 3.8 kernel, even though there have been multiple attempts at merging it. We can merge the required bits from Google’s 3.8 kernel tree, but since we are trying to stay as close as possible to the original BBB 3.8 kernel, we’ll use a different approach. While attempts to get ADB in the mainline continue, Function Filesystem (FunctionFS) driver support has been added to Android’s ADB and we can use that instead of the ‘native’ Android gadget. To use ADB with FunctionFS:
  1. Configure FunctionFS support in the kernel (CONFIG_USB_FUNCTIONFS=y):
    Device Drivers -> USB Support -> 
    USB Gadget Support -> USB Gadget Driver -> Function Filesystem
  • Modify the boot parameters in uEnv.txt to set the vendor and product IDs, as well as the device serial number
    • g_ffs.idVendor=0x18d1 g_ffs.idProduct=0x4e26 g_ffs.iSerialNumber=<serial>
    • Setup the FunctionFS directory and mount it in your init.am335xevm.usb.rc file:
      • on fs
        mkdir /dev/usb-ffs 0770 shell shell
        mkdir /dev/usb-ffs/adb 0770 shell shell
        mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
      • Delete all lines referencing /sys/class/android_usb/android0/*. (Those nodes are created by the native Android gadget driver and are not available when using FunctionFS.)
      • Once this is done, you can reboot and you should see your device using adb devices soon after the kernel has loaded. Now you can debug the OS using Eclipse and push and install files directly using ADB. That said, this won’t help you at all if the device doesn’t boot due to some kernel misconfiguration, so you should definitely get an FTDI cable (the BBB does not have an on-board FTDI chip) to be able to see kernel messages during boot and get an ’emergency’ shell when necessary.

        cgroups patch

        If you are running adb logcat in a console and experimenting with the device, you will notice a lot of ‘Failed setting process group’ warnings like this one:

        W/ActivityManager(  349): Failed setting process group of 4911 to 0
        W/SchedPolicy( 349): add_tid_to_cgroup failed to write '4911' (Permission denied);

        Android’s ActivityManager uses Linux control groups (cgroups) to run processes with different priorities (background, foreground, audio, system) by adding them to scheduling groups. In the mainline kernel this is only allowed to processes running as root (EUID=0), but Android changes this behaviour (naturally, with a patch) to only require the CAP_SYS_NICE capability, which allows the ActivityManager (running as system in the system_server process) to add app processes to scheduling groups. To get rid of this warning, you can disable scheduling groups by commenting out the code that sets up /dev/cpuctl/tasks in init.rc, or you can merge the modified functionality form Google’s experimental 3.8 branch (which we’ve been trying to avoid all along…).

        Android hardware support

        Touchscreen

        We now have a functional Android development device running mostly without warnings, so it’s time to look closer at requirement #1. As we mentioned, once we disable hardware acceleration, the LCD4 works fine with our 3.8 kernel, but a few things are still missing. The LCD4 comes with 5 directional GPIO buttons which are somewhat useful because scrolling on a resistive touchscreen takes some getting used to, but that is not the only thing they can be used for. We can remap them as Android system buttons (Back, Home, etc) by providing a key layout (.kl) file like this one:

        key 105   BACK               WAKE
        key 106 HOME WAKE
        key 103 MENU WAKE
        key 108 SEARCH WAKE
        key 28 POWER WAKE

        The GPIO keypad on the LCD identifies itself as ‘gpio.12’ (you can check this using the getevent command), so we need to name the layout file to ‘gpio_keys_12.kl’. To achieve this we modify device.mk in the BBB device directory (device/ti/beagleboneblack):

        ...
        # KeyPads
        PRODUCT_COPY_FILES +=
        $(LOCAL_PATH)/gpio-keys.kl:system/usr/keylayout/gpio_keys_12.kl
        ...

        Now that we are using hardware buttons, we might want to squeeze some more screen real estate from the LCD4 by not showing the system navigation bar. This is done by setting config_showNavigationBar to false in the config.xml framework overlay file for our board:

        <bool name="config_showNavigationBar">false</bool>

        While playing with the screen, we notice that it’s a bit dark. Increasing the brightness via the display settings however does not seem to work. A friendly error message in logcat tells us that Android can’t open the /sys/class/backlight/pwm-backlight/brightness file. Screen brightness and LEDs are controlled by the lights module on Android, so that’s where we look first. There is a a hardware-specific one under the beagleboneblack device directory, but it only supports the LCD3 and LCD7 displays. Adding support for the LCD4 is simply a matter of finding the file that controls brightness under /sys. For the LCD4 it’s called /sys/class/backlight/backlight.10/brightness and works exactly like the other LCDs — you get or set the brightness by reading or writing the backlight intensity level (0-100) as a string. We modify light.c (full source on Github) to first try the LCD4 device and voila — setting the brightness via the Android UI now works… not. It turns out the brightness file is owned by root and the Settings app doesn’t have permission to write to it. We can change this permission in the board’s init.am335xevm.rc file:

        # PWM-Backlight for display brightness on LCD4 Cape
        chmod 0666 /sys/class/backlight/backlight.10

        This finally settles it, so we can cross requirement #1 off our list and try to tackle #2 — wireless support.

        WiFi adapter

        The BBB has an onboard Ethernet port and it is supported out of the box by the rowboat build. If we want to make our new Android device mobile though, we need to add either a WiFi adapter or 3G modem. 3G support is possible, but somewhat more involved, so we will try to enable WiFi first. There are a number of capes that provide WiFi and Bluetooth for the original BeagleBone, but they are not compatible with the BBB, so we will try using a regular WiFi dongle instead. As long as it has a Linux driver, it should be quite easy to wire it to Android by following the TI porting guide, right?

        We’ll use a WiFi dongle from LM Technolgies based on the Realtek RTL8188CUS chipset which is supported by the Linux rtl8192cu driver. In addition to the kernel driver, this wireless adapter requires a binary firmware blob, so we need to make sure it’s loaded along with the kernel modules. But before getting knee-deep into makefiles, let’s briefly review the Android WiFi architecture. Like most hardware support in Android, it consists of a kernel layer (WiFi adapter driver modules), native daemon (wpa_supplicant), HAL (wifi.c in libharware_legacy, communicates with wpa_supplicant via its control socket), a framework service and its public interface (WifiService and WifiManager) and application/UI (‘WiFi’ screen in the Settings app, as well as SystemUI, responsible for showing the WiFi status bar indicator). That may sound fairly straightforward, but the WifiService implements some pretty complex state transitions in order to manage the underlying native WiFi support. Why is all the complexity needed? Android doesn’t load kernel modules automatically, so the WifiStateMachine will try to load kernel modules, find and load any necessary firmware, start the wpa_supplicant daemon, scan for and connect to an AP, obtain an IP address via DHCP, check for and handle captive portals, and finally, if you are lucky, set up the connection and send out a broadcast to notify the rest of the system of the new network configuration. The wpa_supplicant daemon alone can go through 13 different states, so things can get quite involved when those are combined.

        Going step-by-step through the porting guide, we first enable support for our WiFi adapter in the kernel. That results in 6 modules that need to be loaded in order, plus the firmware blob. The HAL (wifi.c) can only load a single module though, so we pre-load all modules in the board’s init.am335xevm.rc and set the wlan.driver.status to ok in order to prevent WifiService from trying (and failing) to load the kernel module. We then define the wpa_supplicant and dhcpd services in the init file. Last, but not least, we need to set the wifi.interface property to wlan0, otherwise Android will silently try to use a test device and fail to start the wpa_supplicant. Both properties are set as PRODUCT_PROPERTY_OVERRIDES in device/ti/beagleboneblack/device.mk (see device directory on Github). Here’s how the relevant part from init.am335xevm.rc looks like:

        on post-fs-data
        # wifi
        mkdir /data/misc/wifi/sockets 0770 wifi wifi
        insmod /system/lib/modules/rfkill.ko
        insmod /system/lib/modules/cfg80211.ko
        insmod /system/lib/modules/mac80211.ko
        insmod /system/lib/modules/rtlwifi.ko
        insmod /system/lib/modules/rtl8192c-common.ko
        insmod /system/lib/modules/rtl8192cu.ko

        service wpa_supplicant /system/bin/wpa_supplicant
        -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf
        -e/data/misc/wifi/entropy.bin
        class main
        socket wpa_wlan0 dgram 660 wifi wifi
        disabled
        oneshot

        service dhcpcd_wlan0 /system/bin/dhcpcd -ABKL
        class main
        disabled
        oneshot

        service iprenew_wlan0 /system/bin/dhcpcd -n
        class main
        disabled
        oneshot

        In order to build the wpa_supplicant daemon, we then set BOARD_WPA_SUPPLICANT_DRIVER and WPA_SUPPLICANT_VERSION in device/ti/beagleboneblack/BoardConfig.mk. Note the we are using the generic wpa_supplicant, not the TI-patched one and the WEXT driver instead of the NL80211 one (which requires a proprietary library to be linked in). Since we are preloading driver kernel modules, we don’t need to define WIFI_DRIVER_MODULE_PATH and WIFI_DRIVER_MODULE_NAME.

        BOARD_WPA_SUPPLICANT_DRIVER      := WEXT
        WPA_SUPPLICANT_VERSION := VER_0_8_X
        BOARD_WLAN_DEVICE := wlan0

        To make the framework aware of our new WiFi device, we change networkAttributes and radioAttributes in the config.xml overlay file. Getting this wrong will lead to Android’s ConnectionManager totally ignoring WiFi even if you manage to connect and will result in the not too helpful ‘No network connection’ message. “1” here corresponds to the ConnectivityManager.TYPE_WIFI connection type (the built-in Ethernet connection is “9”, TYPE_ETHERNET).

        <string-array name="networkAttributes" translatable="false">
        ...
        <item>"wifi,1,1,1,-1,true"</item>
        ...
        </string-array>
        <string-array name="radioAttributes" translatable="false">
        <item>"1,1"</item>
        ...
        </string-array>

        Finally, to make Android aware of our newly found WiFi features, we copy android.hardware.wifi.xml to /etc/permissions/ by adding it to device.mk. This will take care of enabling the Wi-Fi screen in the Settings app:

        PRODUCT_COPY_FILES := 
        ...
        frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml
        ...

        After we’ve rebuild rowboat and updated the root file system, you should be able to turn on WiFi and connect to an AP. Make sure you are using an AC power supply to power the BBB, because the WiFi adapter can draw quite a bit of current and you may not get enough via the USB cable. If the board is not getting enough power, you might experience failure to scan, dropping connections and other weird symptoms even if your configuration is otherwise correct. If WiFi support doesn’t work for some reason, check the following:

        • that the kernel module(s) and firmware (if any) is loaded (dmesg, lsmod)
        • logcat output for relevant-lookin error messages
        • that the wpa_supplicant service is defined properly in init.*.rc and the daemon is started
        • that /data/misc/wifi and wpa_supplicant.conf are available and have the right owner and permissions (wifi:wifi and 0660)
        • that the wifi.interface and wlan.driver.status properties are set correctly
        • use your debugger if all else fails

        That was easy, right? We now have a working wireless connection, it’s time to think about requirement #3, powering the device.

        Battery power

        The BBB can be powered in three ways: via the miniUSB port, via the 5V AC adapter jack, and by using the power rail (VDD_5V) on the board directly. We can use any USB battery pack that provides enough current (~1A) and has enough capacity to keep the device going by simply connecting it to the miniUSB port. Those can be rather bulky and you will need an extra cable, so let’s look for other options. As can be expected, there is a cape for that. The aptly named Battery Cape plugs into the BBB’s expansion connectors and provides power directly to the power rail. We can plug the LCD4 on top of it and get an integrated (if a bit bulky) battery-powered touchscreen device. The Battery Cape holds 4 AA batteries connected as two sets in parallel. It is not simply a glorified battery holder though — it has a boost converter that can provide stable 1A current at 5V even if battery voltage fluctuates (1.8-5.5V). It does provide support for monitoring battery voltage via AIN4 input, but does not have a ‘fuel gauge’ chip so we can’t display battery level in Android without adding additional circuitry. That is ways our mobile device cannot display the battery level (yet) and unfortunately won’t be able to shut itself down when battery levels become critically low. That is something that definitely needs work, but for now we make the device always believe it’s at 100% power by setting the hw.nobattery property to true. The alternative is to have it display the ‘low battery’ red warning icon all the time, so this approach is somewhat preferable. Four 1900 mAh batteries installed in the battery cape should provide enough power to run the device for a few hours even when using WiFi, so we can (tentatively) mark requirement #3 as fulfilled.

        Flashing the device

        If you have been following Andrew Henderson’s build guide linked above, you have been ‘installing’ Android on an SD card and booting the BBB from it. This works fine and makes it easy to fix things when Android won’t load by simply mounting the SD card on your PC and editing or copying the necessary files. However, most consumer grade SD cards don’t offer the best performance and can be quite unreliable. As we mentioned at the beginning of the post, the BBB comes with 2GB of built-in eMMC, which is enough to install Android and have some space left for a data partition. On most Android devices flashing can be performed by either booting into the recovery system or by using the fastboot tool over USB. The rowboat build does not have a recovery image, and while fastboot is supported by TI’s fork of U-Boot, the version we are using to load the DT blob does not support fastboot yet. That leaves booting another OS in lieu of a recovery and flashing the eMMC form there, either manually or by using an automated flasher image. The flasher image simply runs a script at startup, so let’s see how it works by doing it manually first. The latest BBB Angstrom bootable image (not the flasher one) is a good choice for our ‘recovery’ OS, because it is known to work on the BBB and has all the needed tools (fdisk, mkfs.ext4, etc.). After you dd it to an SD card, mount the card on your PC and copy the Android boot files and rootfs archive to an android/ directory. You can then boot from the SD card, get a root shell on the Angstrom and install Android to the eMMC from there.

        Android devices typically have a boot, system and userdata parition, as well as a recovery one and optionally others. The boot partition contains the kernel and a ramdisk which gets mounted at the root of the device filesystem. system contains the actual OS files and gets mounted read-only at /system, while userdata is mounted read-write at /data and stores system and app data, as well user-installed apps. The partition layout used by the BBB is slightly different. The board ootloader will look for the first stage bootloader (SPL, named MLO in U-Boot) on the first FAT partition of the eMMC. It in turn will load the second state bootloader (u-boot.img) which will then search for a OS image according to its configuration. On embedded devices U-Boot configuration is typically stored as a set of variables in NAND, replaced by the uEnv.txt file on devices without NAND such as the BBB. Thus we need a FAT boot partition to host the SPL, u-boot.img, uEnv.txt, the kernel image and the DT blob. system and userdata will be formatted as EXT4 and will work as in typical Android devices.

        The default Angstrom installations creates only two partitions — a DOS one for booting, and a Linux one that hosts Angstrom Linux. To prepare the eMMC for Android, you need to delete the Linux partition and create two new Linux partitions in its place — one to hold Android system files and one for user data. If you don’t plan to install too many apps, you can simply make them equal sized. When booting from the SD card, the eMMC device will be /dev/block/mmcblk1, with the first partition being /dev/block/mmcblk1p1, the second /dev/block/mmcblk1p2 and so on. After creating those 3 partitions with fdisk we format them with their respective filesystems:

        # mkfs.vfat -F 32 -n boot /dev/block/mmcblk1p1
        # mkfs.ext4 -L rootfs /dev/block/mmcblk1p2
        # mkfs.ext4 -L usrdata /dev/block/mmcblk1p3

        Next, we mount boot and copy boot related files, then mount rootfs and untar the rootfs.tar.bz2 archive. usrdata can be left empty, it will be populated on first boot.

        # mkdir -p /mnt/1/
        # mkdir -p /mnt/2/
        # mount -t vfat /dev/block/mmcblk1p1 /mnt/1
        # mount -t ext4 /dev/block/mmcblk1p2 /mnt/2
        # cp MLO u-boot.img zImage uEnv.txt am335x-boneblack.dtb /mnt/1/
        # tar jxvf rootfs.tar.bz2 -C /mnt/2/
        # umount /mnt/1
        # umount /mnt/2

        With this, Android is installed on the eMMC and you can shutdown the ‘recovery’ OS, remove the SD card and boot from the eMMC. Note that the U-Boot used has been patched to probe whether the SD card is available and will automatically boot from it (without you needing to hold the BBB’s user boot button), so if you don’t remove the ‘recovery’ SD card, it will boot again.

        We now have a working, touch screen Android device with wireless connectivity. Here’s how it looks in action:

        Our device is unlikely to win any design awards or replace your Nexus 7, but it could be used as the basis of  dedicated Android devices, such as a wireless POS terminal or a SIP phone and extended even further by adding more capes or custom hardware as needed.

        Summary

        The BBB is fully capable of running Android and by adding off-the shelf peripherals you can easily turn it into a ‘tablet’ (of sorts) by adding a touch screen and wireless connectivity. While the required software is mostly available in the rowboat project, if you want to have the best hardware support you need to use BBB’s native 3.8 kernel and configure Android to use it. Making hardware fully available to the Android OS is mostly a matter of configuring the relevant HAL bits properly, but that is not always straightforward, even with board vendor provided documentation. The reason for this is that Android subsystems are not particularly cohesive — you need to modify multiple, sometimes seemingly unrelated, files at different locations to get a single subsystem working. This is, of course, not specific to Android and is the price to pay for building a system by integrating originally unrelated OSS projects. On the positive side, most components can be replaced and the required changes can usually be confined to the (sometimes loosely defined) Hardware Abstraction Layer (HAL). 

        Android Malware Set for July 4 Carries Political Message

        McAfee Mobile Security has identified a new Android Trojan embedded in a pirated copy of an exclusive app from rapper Jay Z. We suspect the malware author is attempting to go after the demand for the app Magna Carta Holy Grail on pirated sites. The legitimate app has been released exclusively for Samsung devices on Google Play.

        On the surface, the malware app functions identically to the legit app. But in the background, the malware sends info about the infected device to an external server every time the phone restarts. The malware then attempts to download and install additional packages. The only visible indication that a user is infected comes via a time-based trigger that is set to activate on July 4, Independence Day in the United States. On that day, the malware will replace the wallpaper on the infected device with an altered image (below, second from right) of President Obama that comments on recent events in the United States. Based on the political message and the fact that it was embedded in an app that coincides with the release of Jay Z’s latest album, we suspect the Trojan was recently introduced into the wild.

        image1

        The image and the service name NSAListener suggest a hacktivist agenda, but we haven’t ruled out the possibility that additional malware may target financial transactions or other data.

        Mobile malware seems to have no bounds when it comes to tactics or growth rates. To paraphrase lyrics from Jay Z, it seems Android malware has 99 problems and Android/AntiObscan just became another. We recommend that you always be cautious when downloading apps from unknown sources and keep your security product updated.

         

        The post Android Malware Set for July 4 Carries Political Message appeared first on McAfee Blogs.

        McAfee Hidden Device Admin Detector – Free Protection from Android Malware

        A few weeks ago, we told you about Obad, a backdoor Trojan that targets the Android operating system (OS). What differentiates a Trojan from a traditional virus is that this type of software attempts to masquerade as something useful in order to trick users into opening the file and then leaves a backdoor open so attackers can access your data at any time. This Trojan affects all Android OS users, and it is strongly recommended that you address this flaw immediately!

        What does Obad do? 

        Essentially, Obad enables the downloading of malicious apps onto your Android device right under your nose – these apps have the dangerous ability to take advantage of your device’s administrator capability without your knowledge. The apps are created so that they don’t show up in your device’s admin screen, ultimately preventing you from uninstalling the app even if McAfee Mobile Security identifies the app as a malicious one.

        New from McAfee – the McAfee Hidden Device Admin Detector, part of the McAfee Mobile Innovations app and now available on Google Play, protects your Android device from the Obad threat. Upon installation, use the app to scan your device for apps that have been granted device admin privileges, unbeknownst to you.

        Obad FAQs:

        Which devices are affected?
        Any device running the Android OS carries the risk of being affected by Obad

        How does it work?

        1. It’s hidden.
        Obad runs in the background of your mobile device so you may not know if you even have it or if you have unknowingly installed an infected app. It’s so well hidden that once Device Administrator privileges have been granted to the app, the malware, or malicious software, does not appear in the device administrator list, making it almost impossible to delete it.

        2. It executes remote commands.
        Devices infected with Obad can be controlled remotely by a Command and Control (C&C) server. Through a Command and Control (C&C) server, attackers are able to send commands and receive outputs from your device without ever alerting you. The attacker can send a variety of commands such as:

        • Making your mobile send unauthorized text messages (e.g. to premium rate numbers);
        • Downloading other malicious apps and installing them on your device;
        • Harvesting sensitive information (e.g. your contact list or capturing what you type on your device);
        • And acquiring the account balance.

        How does McAfee Hidden Device Admin Detector work?
        It scans and detects malicious apps that have been granted device administrator privileges and are hidden to prevent removal. The apps are then visible to you so that you may remove their device administrator privileges and then uninstall them from your Android device.

        See screenshots below of McAfee Hidden Device Admin Detector in action:

        2013-06-27 19.33.182013-06-27 19.33.28

        Do I need to be a McAfee customer to be able to take advantage of this free app?
        No. McAfee wants to ensure all Android users are safe, therefore, this app is available for free to all Android device users via Google Play.

        Will the McAfee Hidden Device Admin Detector eventually be a part of McAfee Mobile Security?
        Yes. We are planning to have it integrated as part of McAfee Mobile Security later this year, however, we wanted to make sure to have a solution that addresses Obad available as soon as possible for all Android users.

        What is the cost of this app and how can I get it?
        McAfee Hidden Device Admin Detector is available for free on Google Play, via the free McAfee Mobile Innovations App.

        Don’t let your Obad take control of your phone and sensitive data – download McAfee Hidden Device Admin Detector today.

        For future updates, be sure to follow us on Twitter at @McAfeeConsumer or on Facebook at http://facebook.com/McAfee.

        The post McAfee Hidden Device Admin Detector – Free Protection from Android Malware appeared first on McAfee Blogs.

        Code signing in Android’s security model

        In the previous post we introduced code signing as implemented in Android and saw that it is practically identical to JAR signing. Android requires all installed packages to be signed and makes heavy use of the attached code signing certificates in its security model. This is where the major differences with other platforms that use code signing lie, so we will explore the topic in more detail.

        Java access control

        Before we start digging into Android’s security model, let’s go through a quick overview of the corresponding features of the Java platform. Java was initially designed to support running potentially untrusted code, downloaded from a public network (mostly applets). The initial applet sandbox model was extended to a more flexible, policy-based scheme where different permissions can be granted based on the code’s origin and author. Code origin refers to the place where classes are loaded from, typically a local file or a remote URL, while authorship is asserted via code signatures and is represented by the signer’s certificate chain. Combined those two properties define a code source. Each code source is granted a set of permissions based on a policy, the default implementation being to read rules from a policy file (created with the policytool). At runtime a security manager (if installed) enforces access control by comparing code elements on the stack with the current policy. It throws a SecurityException if the permissions required to access a resource have not been granted to the requesting code source. Java code that runs (or is started in) the browser, such as applets or Java Web Start applications, is automatically run with a security manager installed, while for local applications you need to explicitly set the java.security.manager in order to install one. In practice, a security manager for local code is only used with some applications servers, and it is usually disabled by default. A wide range of permissions are supported by the platform, the major ones being file and socket-oriented, as well as different types of runtime permissions which control operations ranging from class and library loading to managing the current security manager. By defining multiple code sources and assigning each one specific permissions one can implement fine grained access control for both local and remote code.

        As we mentioned though, unless you are in the browser plugin or application server development business chances are you hadn’t heard about any of this until the beginning of this year. Just when everyone thought that Java applets were for all intents and purposes dead, they made somewhat of a comeback as a malware distribution medium. A series of vulnerabilities were discovered in the Oracle Java implementation that allow applets to escape the sandbox they run in and reset the security manager, effectively granting themselves full privileges. The exploits used to achieve this employ techniques ranging from reflection recursion to direct memory manipulation to bypass runtime security checks. Oracle has responded by releasing a series of patches, changing the default applet execution policy and introducing more visible warnings to let users know that potentially harmful code is being executed. Naturally, different ways to bypass this are being discovered to catch up.

        In short, Java has had full-featured code access control for some time, even though the most widely used implementation appears to be lacking in enforcing it. But let’s (finally!) get back to Android now. As the Java code access control mechanism can use code signer identity to define code sources and grant permissions, and Android code is required to be signed, one might expect that our favourite mobile OS would be making use of the Java’s security model in some form, just as it does with JAR files. As it turns out, this is not the case. Access control related classes are part of the Java API, and are indeed available in Android. However, looking at the implementation reveals that they are practically empty, with just enough code to compile. In addition, they feature a prominent ‘Legacy security code; do not use.’ notice. So why bother reviewing all of the above then? Even though Android’s access control model is very different from the legacy Java one, it does borrow some of the same ideas, and a comparison is helpful when discussing the design decisions made.

        Android security architecture basics

        Before we discuss the role of code signing in Android’s security model, let’s say a few words about Android’s general security architecture. As we know, Android is Linux-based and relies heavily on traditional UNIX features to implement its security architecture. Each application runs in a separate process with a distinct identity (user ID, UID). By default apps cannot modify each other’s resources and this is enforced by Linux which doesn’t allow different processes to access memory or files they don’t own (unless access is explicitly granted by the owner, a.k.a discretionary access control). Additionally, each app (UID) is granted a set of logical permissions at install time, and cannot perform operations (call APIs) that require permissions it doesn’t have. This is the biggest difference compared to the ‘standard’ Java permission model: code from different sources running in a single process cannot have different permissions, since permissions are granted at the UID level. Most permissions cannot be dynamically granted after the package has been installed, however as of 4.2 a number of ‘development’ permissions (e.g., READ_LOGS, WRITE_SECURE_SETTINGS) have been introduced that can be granted or revoked on demand using the pm grant/revoke command (or matching system APIs). The system will show a confirmation dialog showing permissions requested by an app before installing. With the exception of the new ‘development’ permissions, all requested permissions are permanently granted if the the user allows the install. For a certain messaging app it looks like this in Jelly Bean:

        Android permissions are typically implemented by mapping them to Linux groups that have the necessary read/write access to relevant system resources (files or sockets) and thus are ultimately enforced by the Linux kernel. Some permissions are enforced by system daemons or services by explicitly checking if the calling UID is whitelisted to perform a particular operation. The network access permission (INTERNET) is somewhat of a hybrid: it is mapped to a group (inet), but since network access is not associated with one particular socket, the kernel checks whether processes trying to open a socket are members of the inet group on each related system call (known as ‘paranoid network security’).

        Each permission has an associated ‘protection level‘ that indicates how the system proceeds when deciding whether to grant or deny the permission. The two levels most relevant to our discussion are signature and signatureOrSystem. The former is granted only to apps signed with the same certificate as the package declaring the permission, while the latter is granted to apps that are in the Android system image, even if the signer is different.

        Besides the built-in permissions, custom permissions can also be defined by declaring them in the app manifest file. Those can be enforced statically by the system or dynamically by app components. Permissions attached to components (activities, services, broadcast receivers or content providers) defined in AndroidManifest.xml are automatically enforced by the system. Components can also make use of framework APIs to check whether the calling UID has been granted a required permissions on a case-by-case basis (e.g., only for write operations, etc.). We will introduce other permission related details as necessary later, but you can refer to this Marakana presentation for a more complete and thorough discussion of Android permissions (and more). Of course, some official documentation is also available.

        The role of code signing

        As we saw in the previous article, Android code signing is based on Java JAR signing. Consequently, it uses public key cryptography and X.509 certificates as do a lot of other code signing schemes. However, this is where the similarities end. In practically all other platforms that use code signing (for example Java ME), code signing certificate needs to be issued by a CA that the platform trusts. While there is no lack of CAs that issue code signing certificates, in reality it is quite difficult to obtain a certificate that will be trusted by all targeted devices. Android solves this problem quite simply: it doesn’t care about the actual signing certificate. Thus you do not need to have it issued by a CA (although you could, and most will happily take your money), and virtually all code signing certificates used in Android are self-signed. Additionally, you don’t need to assert your identity in any way: you can use pretty much anything as the subject name (the Google Play store does have a few checks to weed out some common names, but not the OS itself). Signing certificates are treated as binary blobs by Android, and the fact that they are in X.509 format is merely a consequence of using the JAR format. Android doesn’t validate certificates as such: if the certificate is not self-signed, the signing CA’s certificate does not have to be present, yet alone trusted; it will also happily install apps with an expired signing certificate. If you are coming from a traditional PKI background, this may sound like heresy, but try to keep an open mind and note that Android does not make use of PKI for code signing.

        So what are code signing certificates used for then? Two things: making sure updates for an app are coming from the same author (same origin policy), and establishing trust relationships between applications. Both are implemented by comparing the signing certificate of the currently installed target app with the certificate of the update or related application. Comparison boils down to calling Arrays.equals() on the binary (DER) representation of both certificates. This method naturally knows nothing about CAs or expiration dates. One consequence of this is that once an app (identified by a unique package name) is installed, updates need to use the exact same signing certificates (with one exception, see next section). While multiple signatures on Android apps are not common, if the original application was signed by more than one signer, any updates need to be signed by the same signers, each using its original signing certificate. This means that if your signing certificate(s) expires, you cannot update your app and need to release a new one instead. This would result in not only losing any existing user base or ratings, but more importantly losing access to the legacy app’s data and settings (again, there are some exceptions). The solution to this problem is quite simple: don’t let your certificate expire. The currently recommended validity period is at least 25 years, and the Google Play Store requires validity until at least October 2033 (Y2K33?). While technically this only amounts to putting off the problem, proper certificate migration support might eventually be added to the platform. Unfortunately, this means that if your signing key is lost or compromised, you are currently out of luck.

        Let’s examine the major uses of code signing in Android in detail.

        Application authenticity and identity

        In Android all apps are managed by the system PacakgeManagerService, no matter if they are pre-installed, downloaded from an app market or side loaded. It keeps a database of currently installed apps, including their signing certificate(s), granted permissions and additional metadata in the /data/system/packages.xml file. A typical entry for a user-installed app might look like this:

        <package codepath="/data/app/com.chrome.beta-2.apk" 
        flags="572996" ft="13e20480558"
        installer="com.android.vending"
        it="13ca981cbe3" name="com.chrome.beta"
        nativelibrarypath="/data/app-lib/com.chrome.beta-2"
        userid="10092" ut="13e204816ce" version="1453060">
        <sigs count="1">
        <cert index="8">
        </cert>
        </sigs>
        <perms>
        <item name="android.permission.NFC"/>
        ...
        <item name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
        </perms>
        </package>

        As you can see above, a package entry specifies the package name, the location of the APK and associated libraries, assigned UID and some additional install metadata such as install and update time. This is followed by the number of signatures and the signing certificate as a hexadecimal string. Since a hex-encoded certificate will usually take up around 2K, the actual certificate contents is listed only once. All subsequent packages signed with the same certificate only refer to it by index, as is the case above. The PackageManagerService uses the <cert/> values in packages.xml to decide whether an update is signed with the same certificate as the original app. The certificate is followed by the list of permissions the package has been granted. All of this information is cached on memory (keyed by package name) at runtime for performance reasons.

        Just like user-installed apps, pre-installed apps (usually found in /system/app) can be updated without a full-blown system update, usually via the Play Store or a similar app distribution service. As the /system partition is mounted read-only though, updates are installed in /data, while the original app remains as is. In addition to a <package/> entry, such an app will also have a <updated-package> entry that might look like this:

        <updated-package name="com.google.android.youtube" 
        codePath="/system/app/YouTube.apk"
        ft="13cd6667b50" it="13ae93df638" ut="13cd6667b50"
        version="4216"
        nativeLibraryPath="/data/app-lib/com.google.android.youtube-1"
        userId="10067">
        <perms>
        <item name="android.permission.NFC" />
        ...
        </perms>
        </updated-package>

        The update (in /data/app) inherits the original app’s permissions and UID. System apps receive another special treatment as well: if an updated APK is installed over the original one (in /system/app) it is allowed to be signed with a different certificate. The rationale behind this is that if the installer has enough privileges to write to /system, it can be trusted to change the signing certificate as well. The UID, and any files and permissions are retained. Again, there is an exception though: if the package is part of a shared user (discussed in the next section), the signature cannot be updated, because that would affect other apps as well. In the reverse case, when a new system app signed by a different certificate than that of the currently installed non-system app (with the same package name), the non-system app will be deleted first.

        Speaking of system apps, most of those are signed by a number of so called ‘platform keys’. There are four different keys in the current AOSP tree, named platform, shared, media and testkey (releasekey for release builds). All packages considered part of the core platform (System UI, Settings, Phone, Bluetooth etc.) are signed with the platform key, launcher and contacts related packages — with the shared key, the gallery app and media related providers — with the media key, and everything else (including packages that don’t explicitly specify the signing key) — with the testkey. One thing to note is that the keys distributed with AOSP are in no way special, even though they have ‘Google’ in the certificate DN. Using them to sign your apps will not give you any specific privileges, you will need the actual keys Google or your carrier/device manufacturer uses. Even though the associated certificates may happen to have the same DN as the ones in AOSP, they are different and very unlikely to be publicly accessible. Custom ROMs are often an exception though, and some, including CyanogenMod, use the AOSP keys, or publicly available keys, as is (there are plans to change this for CyanogenMod though). Sharing the signing key allows packages to work together and establish trust relationships, which we will discuss next.

        Inter-application trust relationships

        Signature permissions

        As we mentioned above, Android permissions (system or custom) can be declared with the signature protection level. With this level, the permission is only granted if the requesting app is signed by the same signer as the package declaring the permission. This can be thought of as a limited form of mandatory access control (MAC). For custom (app-declared) permission, permissions are declared in the package’s AndroidManifest.xml file, and are added to the system when it is installed. Just as other package data, permissions are saved in the /data/system/packages.xml file, as children of the <permissions/> element. Here’s how the declaration of a custom permission used by some Google apps looks like:

        <permissions>
        ..
        <item name="com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD"
        package="com.google.android.gsf.login"
        protection="2" />
        ...
        </permissions>

        The entry has the permission name, declaring package and protection level (2 corresponds to signature) as attributes. When installing a package that requests this permission, the PackageManagerService will perform binary comparison (just as when upgrading packages) of its signing certificate against the certificate of the Google Login Service (the declaring package, com.google.android.gsf.login) in order to decide whether to grant the permission. A noteworthy detail is that the system cannot grant a permission it doesn’t know about. That is, if app A declares permission ‘foo’ and app B uses it, app B needs to be installed after app A, otherwise you will get a warning at install time and the permission won’t be granted. Since app installation order typically cannot be guaranteed, the usual workaround for this situation is to declare the permission in both apps. Permissions can also be added and removed dynamically using the PackageManger.addPermission() API (know as ‘dynamic permissions’). However, packages can only add permissions to a permission tree they define (i.e., you cannot add permissions to another app).

        That mostly explains custom permissions, but what about built-in, system permissions with signature protection level? They work exactly as custom permissions, except that the package that defines them is special. They are defined in the android package, sometimes also referred as ‘the framework’ or ‘the platform’. The core android framework is the set of classes shared by system services, some of them exposed via the public SDK. Those are packaged in JAR files found in /system/framework. Interestingly, those JAR files are not signed: while Android borrows the JAR format to implement code signing, only APK files are signed, not actual JARs. The only APK file in the framework directory is framework-res.apk. As the name implies, it packages framework resources (animation, drawables, layouts, etc.), but no actual code. Most importantly, it defines the android package and system permissions. Thus any app trying to request a system-level signature permission needs to be signed with the same certificate as the framework resource package. Not surprisingly, it is signed by the platform key discussed in the previous section (usually found in build/target/product/security/platform.pk8|.x509.pem). The associated certificate may looks something like this for an AOSP build:

        Version: 3 (0x2)
        Serial Number: 12941516320735154170 (0xb3998086d056cffa)
        Signature Algorithm: md5WithRSAEncryption
        Issuer: C=US, ST=California, L=Mountain View, O=Android, OU=Android,
        CN=Android/emailAddress=android@android.com
        Validity
        Not Before: Apr 15 22:40:50 2008 GMT
        Not After : Sep 1 22:40:50 2035 GMT
        Subject: C=US, ST=California, L=Mountain View, O=Android, OU=Android,
        CN=Android/emailAddress=android@android.com

        Shared user ID

        Android provides an even stronger inter-app trust relationship than using signature permissions:  the ability for different apps to run as the same UID, and optionally in the same process. It is usually referred to as ‘shared user ID‘. This feature is extensively used by core framework services and system applications, and while the Android team does not recommend that third-party application use it, it is available to user applications as well. It is enabled by adding the android:sharedUserId attribute to AndroidManifest.xml‘s root element. The ‘user ID’ specified in the manifest needs to be in Java package format (containing at least one ‘.’) and is used as an identifier, much like package names for applications. If the specified shared UID does not exist it is simply created, but if another package with the same shared UID is already installed, the signing certificate is compared to that of the existing package, and if they do not match, a INSTALL_FAILED_SHARED_USER_INCOMPATIBLE error is returned and installation fails. Adding the sharedUserId to the new version of an already installed app will cause it to change its UID, which would result in losing access to its own files (that was the case in some previous Android versions). Therefore, this is disallowed by the system, and it will reject the update with the INSTALL_FAILED_UID_CHANGED error. In short, if you plan to use shared UID for your apps, you have to design for it from the start, and have them use it since the very first release.

        A shared UID is a first class object in the system’s packages.xml and is treated much like apps are: it has associated signing certificate(s) and permissions. Android has 5 built-in shared UIDs, automatically added when the system is bootstrapped:

        • android.uid.system (SYSTEM_UID, 1000)
        • android.uid.phone (PHONE_UID, 1001)
        • android.uid.bluetooth (BLUETOOH_UID, 1002)
        • android.uid.log (LOG_UID, 1007)
        • android.uid.nfc (NFC_UID, 1027)

        Here’s how the system shared UID is defined:

        <shared-user name="android.uid.system" userId="1000">
        <sigs count="1">
        <cert index="4" />
        </sigs>
        <perms>
        <item name="android.permission.MASTER_CLEAR" />
        <item name="android.permission.CLEAR_APP_USER_DATA" />
        <item name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
        ...
        <shared-user/>

        As you can see, apart from having a bunch of scary permissions (about 60 on a 4.2 device), the declaration is very similar to the package declarations we showed previously. Conversely, packages that are a part of a shared UID, do not have an associated granted permission list. They inherit the permissions of the shared UID, which are a union of the permissions requested by all currently installed packages with the same shared UID. A side effect of this is, that if a package is part of a shared UID, it can access APIs it hasn’t explicitly requested permissions for, as long as some package with the same shared UID has already requested them. Permissions are dynamically removed from the <shared-user/> declaration as packages are installed or uninstalled though, so the set of available permissions is neither guaranteed nor constant. Here’s how the declaration of a system app (KeyChain) that runs under a shared ID looks like. It references the shared UID with the sharedUserId attribute and lacks explicit permission declarations:

        <package name="com.android.keychain" 
        codePath="/system/app/KeyChain.apk"
        nativeLibraryPath="/data/app-lib/KeyChain"
        flags="540229" ft="13cd65721a0"
        it="13c2d4721f0" ut="13cd65721a0"
        version="17"
        sharedUserId="1000">
        <sigs count="1">
        <cert index="4" />
        </sigs>
        </package>

        The shared UID is not just a package management construct, it actually maps to a shared Linux UID at runtime as well. Here is an example of two system apps running under the system UID:

        system    5901  9852  845708 40972 ffffffff 00000000 S com.android.settings
        system 6201 9852 824756 22256 ffffffff 00000000 S com.android.keychain

        The ultimate trust level on Android is, of course, running in the same process. Since apps that are part of the same shared UID already have the same Linux UID and can access the same system resources, this is not a problem. It can be requested by specifying the same process name in the process attribute of the <application/> element in the manifest for all apps that need to run in one process. While the obvious result of this is that the apps can share memory and communicate directly instead of using RPC, some system services allow special access to components running in the same process (for example direct access to cached passwords or getting authentication tokens without showing UI prompts). Google apps take advantage of this by requesting to run in the same process as the login service in order to be able to sync data in the background, without user interaction (e.g., Play Services and the Google location service). Naturally, they are signed withe same certificate and part of the com.google.uid.shared shared UID.

        Summary

        Android uses the Java JAR format for code signing, and signatures can be added to both application packages (APKs) and system update packages (OTA updates). While JAR signing is based on X.509 certificates and PKI, Android does not use or validate the signer certificates as such. They are treated as binary blobs and an exact byte match is required in order for the system to consider two packages signed by the same signer. Package signature matching is at the heart of the Android security model, used both to guarantee that package updates come from the same origin and when establishing inter-application trust relationships. Inter-app trust relationships can be created either using signature-level permissions (built-in or custom), or by allowing apps to share the same system UID and, optionally, process.