• Aucun résultat trouvé

Finding Other Local Attack Surfaces

Dans le document ffi rs.indd 01:50:14:PM 02/28/2014 Page ii (Page 195-200)

socket 0666 root system /dev/socket/pb [...]

directory 0771 shell shell /data/local/tmp [...]

The -u and -g options passed to canhazaxs correspond to the user and groups that should be considered when determining whether the entry is readable, writable, or executable. After those options, you can specify any number of directories to inspect. For each of these directories, canhazaxs recursively enu-merates entries in all directories within. After everything is inspected, entries that are accessible are shown prioritized by potential impact. For each entry, canhazaxs shows the type, permissions, user, group, and path. This streamlines the process of enumerating attack surfaces exposed via the fi le system.

Finding the code behind each endpoint depends on the type of entry. For kernel drivers, searching the kernel source code for the specifi c entry’s name, as discussed further in Chapter 10, is the best method. It’s diffi cult to fi nd exactly what code operates on any particular regular fi le or directory. However, inspecting the init.rc and related commands have led to the discovery of privilege escalation vulnerabilities in the past. Determining the code behind a socket endpoint can be tricky and is discussed further in the “Finding the Code Behind a Socket” section later in this chapter. When you fi nd the code, you can determine the functionality provided by the endpoint. The deeper attack surfaces beneath these endpoints present an opportunity to uncover previously unknown privilege escalation issues.

Finding Other Local Attack Surfaces

Not all local attack surfaces are exposed via entries in the fi le system. Additional attack surfaces exposed by the Linux kernel include system calls, socket imple-mentations, and more. Many services and apps in Android expose attack surfaces locally through different types of IPC, including sockets and shared memory.

System Calls

The Linux kernel has a rich attack surface that is exposed to local attackers.

Apart from things represented by an entry in the fi le system, the Linux kernel also processes potentially malicious data when it executes system calls. As such, system call handler functions inside the kernel represent an interesting attack surface. Finding such functions is easily accomplished by searching for the SYSCALL_DEFINE string within the kernel source code.

Sockets

Software running on Android uses various types of sockets to achieve IPC. To understand the full extent of the attack surface exposed by various types of sockets you must fi rst understand how sockets are created. Sockets are created using the socket system call. Although various abstractions for creating and managing sockets exist throughout Android, all of them eventually use the socket system call. The following excerpt from the Linux manual page shows this system call’s function prototype:

int socket(int domain, int type, int protocol);

The important thing to understand is that creating a socket requires specify-ing a domain, type, and protocol. The domain parameter is most important as its value determines how the protocol parameter is interpreted. More detailed information about these parameters, including supported values for each, can be found from the Linux manual page for the socket function. Further, it’s possible to determine which protocols are supported by an Android device by inspecting the /proc/net/protocols fi le system entry:

shell@ghost:/data/local/tmp $ ./busybox wc -l /proc/net/protocols 24 /proc/net/protocols

Each of the entries in this fi le represents an interesting attack surface to explore further. The source code that implements each protocol can be found within the Linux kernel source in the net subdirectory.

Common Socket Domains

Most Android devices make extensive use of sockets in the PF_UNIX, PF_INET, and PF_NETLINK domains. Sockets in the PF_INET domain are further broken down into those that use the SOCK_STREAM and SOCK_DGRAM types, which use the TCP and UDP protocols. Detailed information about the status of instances of each type of socket can be obtained via entries in the /proc/net directory as depicted in Table 5-2.

Table 5-2: Status Files for Common Socket Domains

SOCKET DOMAIN STATUS FILE

PF_UNIX /proc/net/unix

PF_INET (SOCK_STREAM) /proc/net/tcp PF_INET (SOCK_DGRAM) /proc/net/udp PF_NETLINK /proc/net/netlink

The fi rst, and most commonly used, socket domain is the PF_UNIX domain.

Many services expose IPC functionality via sockets in this domain, which

expose endpoints in the fi le system that can be secured using traditional user, group, and permissions. Because an entry exists in the fi le system, sockets of this type will appear when using the methods discussed in the “Exploring the File System” section earlier in this chapter.

In addition to traditional PF_UNIX domain sockets, Android implements a special type of socket called an Abstract Namespace Socket. Several core system services use sockets in this domain to expose IPC functionality. These sockets are similar to PF_UNIX sockets but do not contain an entry in the fi le system.

Instead, they are identifi ed only by a string and are usually written in the form

@socketName. For example, the /system/bin/debuggerd program creates an abstract socket called @android:debuggerd. These types of sockets are created by specifying a NUL byte as the fi rst character when creating a PF_UNIX socket.

The characters that follow specify the socket’s name. Because these types of sockets do not have a fi le system entry, they cannot be secured in the same way as traditional PF_UNIX sockets. This fact makes abstract socket endpoints an interesting target for further exploration.

Any application that wants to talk to hosts on the Internet uses PF_INET sockets.

On rare occasions, services and apps use PF_INET sockets to facilitate IPC. As shown earlier, this socket domain includes communications that use TCP and UDP protocols. To create this type of socket, a process must have access to the inet Android ID (AID). This is due to Android’s Paranoid Networking feature that was fi rst discussed in Chapter 2. These types of sockets are especially interesting when used for IPC or to implement a service exposed to the network.

The fi nal common type of socket in Android is the PF_NETLINK socket. These types of sockets are usually used to communicate between kernel-space and user-space. User-space processes, such as /system/bin/vold, listen for events that come from the kernel and process them. As previously discussed in Chapter 3, the GingerBreak exploit relied on a vulnerability in vold’s handling of a maliciously crafted NETLINK message. Attack surfaces related to PF_NETLINK sockets are interesting because they exist in both kernel-space and privileged user-space processes.

Finding the Code Behind a Socket

On typical Linux systems, you can match processes to sockets using the lsof command or the netstat command with the -p option. Unfortunately, this doesn’t work out of the box on Android devices. That said, using a properly built BusyBox binary on a rooted device is able to achieve this task:

root@mako:/data/local/tmp # ./busybox netstat -anp | grep /dev/socket/pb unix 2 [ ] DGRAM 5361 184/mpdecision /dev/socket/pb

Using the preceding single command, you are able to discover that /dev/

socket/pb is in use by process ID 184 called mpdecision.

In the event that a properly built BusyBox is not available, you can achieve the same task using a simple three-step process. First, you use the specifi c entries within the proc fi le system to reveal the process that owns the socket:

root@mako:/data/local/tmp # ./busybox head -1 /proc/net/unix Num RefCount Protocol Flags Type St Inode Path root@mako:/data/local/tmp # grep /dev/socket/pb /proc/net/unix 00000000: 00000002 00000000 00000000 0002 01 5361 /dev/socket/pb

In this example, you can see the /dev/socket/pb entry inside the special /proc/net/unix fi le. The number that appears immediately before the path is the inode number for the fi le system entry. Using the inode, you can see which process has an open fi le descriptor for that socket:

root@mako:/data/local/tmp # ./busybox ls -l /proc/[0-9]*/fd/* | grep 5361 [...]

lrwx--- 1 root root 64 Jan 2 22:03 /proc/184/fd/7 ->

socket:[5361]

Sometimes this command shows that more than one process is using the socket.

Thankfully, it’s usually obvious which process is the server in these cases. With the process ID in hand, it’s simple to fi nd more information about the process:

root@mako:/data/local/tmp # ps 184

USER PID PPID VSIZE RSS WCHAN PC NAME

root 184 1 7208 492 ffffffff b6ea0908 S /system/bin/mpdecision

Regardless of whether you use the BusyBox method or the three-step method, you now know where to start looking.

Sockets represent a signifi cant local attack surface due to the ability to commu-nicate with privileged processes. The kernel-space code that implements various types of sockets might allow privilege escalation. Services and applications in user-space that expose socket endpoints might also allow privilege escalation.

These attack surfaces represent an interesting place to look for security issues.

By locating the code, you can look more closely at the attack surface and begin your journey toward deeper attack surfaces within.

Binder

The Binder driver, as well as software that relies on it, presents an attack surface that is unique to Android. As previously discussed in Chapter 2 and further explored in Chapter 4, the Binder driver is the basis of Intents that are used to communicate between app-level Android components. The driver itself is implemented in kernel-space and exposes an attack surface via the /dev/binder character device. Then, Dalvik applications communicate with one another through several levels of abstraction built on top. Although sending Intents

from native applications is not supported, it is possible to implement a service in native code directly on top of Binder. Because of the many ways Binder can be used, researching deeper attack surfaces might ultimately lead to achieving privilege escalation.

Shared Memory

Although Android devices do not use traditional POSIX shared memory, they do contain several shared memory facilities. As with many things in Android, whether a particular facility is supported varies from one device to the next.

As introduced in Chapter 2, Android implements a custom shared memory mechanism called Anonymous Shared Memory, or ashmem for short. You can fi nd out which processes are communicating using ashmem by looking at the open fi le descriptors in the /proc fi le system:

root@mako:/data/local/tmp # ./busybox ls -ld /proc/[0-9]*/fd/* | \ grep /dev/ashmem | ./busybox awk -F/ ‘{print $3}’ | ./busybox sort -u [...]

176 31897 31915 596 686 856

In addition to ashmem, other shared memory facilities—for example, Google’s pmem, Nvidia’s NvMap, and ION—exist on only a subset of Android devices.

Regardless of which facility is used, any shared memory used for IPC represents a potentially interesting attack surface.

Baseband Interface

Android smartphones contain a second operating system known as the baseband.

In some devices the baseband runs on an entirely separate physical central pro-cessing unit (CPU). In others, it runs in an isolated environment on a dedicated CPU core. In either situation, the Android operating system must be able to speak to baseband in order to make and receive calls, text messages, mobile data, and other communications that traverse the mobile network. The exposed endpoint, which varies from one device to the next, is considered an attack surface of the baseband itself. Accessing this endpoint usually requires elevated privileges such as to the radio user or group. It’s possible to determine exactly how the baseband is exposed by looking at the rild process. More information about Android’s Telephony stack, which abstracts access to the baseband interface, is presented in Chapter 11.

Attacking Hardware Support Services

A majority of Android devices contain myriad peripheral devices. Examples include GPS transceivers, ambient light sensors, and gyroscopes. The Android Framework exposes a high-level API to access information provided by these peripherals to Android applications. These APIs represent an interesting attack surface because data passed to them might be processed by privileged services or even the peripheral itself. The exact architecture for any given peripheral varies from one device to the next. Because of the layers between the API and the peripherals, the exposed API attack surface serves as an excellent example of how deeper attack surfaces lie beneath more shallow ones. A more thorough examination of this set of attack surfaces is beyond the scope of this book.

Dans le document ffi rs.indd 01:50:14:PM 02/28/2014 Page ii (Page 195-200)