Inspecting file permissions

One of the most commonly exploited ways to escalate privileges from within a local context is to abuse discrepancies and inadequacies in the way filesystem permissions—or access rights—are set up in an operating system. There are countless instances of vulnerabilities and privilege escalation attack methods that abuse file permissions, be it the setuid flag on a globally executable vulnerable binary, such as su or symlink, or the race condition attack on a file that is globally readable and written to by a superuser-owned application; for example, pulse audio CVE-2009-1894.

Being able to clearly identify any potential entry points presented by the filesystem is a good place to start defining the Android native attack surface. The walkthrough in this section details a few methods you can use to find dangerous or potential files that possibly enable exploitation while interacting with the device through an ADB shell.

Seeing that the following tutorial is focused on detailing ways to find files with inadequate or discrepant permissions, a fundamental skill you require in order to understand why certain commands are executed would be to understand how Linux- or Unix-based operating systems define file permissions. A quick side note: it's common in some Linux circles to talk about file and directory permissions as access rights; here, these terms will be used interchangeably.

Linux- or Unix-based operating systems' file permissions are defined in terms of the following:

  • The likely users (abbreviated as o) of the file that don't fall into the other user categories
  • The owner of the file (abbreviated as u)
  • The access control enforced on the group of users that the owner of file belongs to (abbreviated as g)

Categorizing users in this way allows mutual exclusivity, enabling a user to fine-tune who has access to the file. This means specification of access rights can be done with respect to the file and every likely user.

For each collection of users (group, other users, and the owner), five attributes of access control are defined, namely:

  • The Read ability (r) of the file; who is allowed to actually read the contents of the file.
  • The Write ability (w) of the file; this controls who is allowed to augment or modify the contents of the file.
  • The Execute ability (x) of the file; whether a given collection of users is allowed to execute the instructions of the file.
  • The Set Group ID ability (s); should the file be executable; this defines how the user's permissions are augmented according to its group permissions. This permission may allow a low-privileged user to escalate their privileges in order to perform certain tasks; for example, substitute a user who escalates the privileges of any user to root or any user it desires—given that the authentication succeeds, of course!
  • The Set User ID ability (s); this determines whether the user ID of the file owner, and therefore all the access rights that go along with it, can be transmitted to the executing process.

Each of these are defined in terms of either mnemonics—using abbreviations—or as the literal bitwise values encoded in octal format. For first timers, this may be a confusing description, which is why this section includes a small table that defines the values, both in binary and octal (numbers in base 8).

Why base 8? Well, because base 8 in binary allows space for three bits, each one describing the Boolean value of each of the attributes; 1 for on (or true) and 0 for off (or false):

Description

Binary value

Decimal value

Read

100

4

Write

010

2

Execute

001

1

These are combined by adding the binary values. Here is a table that describes that:

Description

Read

Write

Execute

Read

100

4

110

6

101

5

Write

 

010

2

011

3

Execute

 

001

1

These are specified for each collection of users; this means the permission has one bit for each user as well, seeing that there are three collections, namely the file owner, the group, and other users—commonly referred to as "the world". The permission bits also include an extra bit for the definition of setuid, setguid, and the sticky bit.

The sticky bit is an access right that allows only the owner of a file or directory to delete or rename a file or directory. When specified, it appears as a T symbol in the access right bits displayed by the ls command.

The structure looks as follows:

Owner

Group

Other

r

w

x

r

w

x

r

w

x

That's pretty much it as far as the basics of file access rights go; if you've followed the previous paragraphs carefully, you should have enough to spot the most fundamental flaws when it comes to Android's native access rights.

In order to properly appreciate the discrepancies that vendors add to device builds, you will need to know a little bit about what the "default" or standard Android filesystem looks like in terms of its structure and access permissions setup.

Inspecting file permissions

Here's the summary of the default or standard filesystem folders and their purposes according to the Linux filesystem hierarchy standard and the init.rc scripts on Jelly Bean. References for the init.rc scripts of other platforms are given in the See also section of the next tutorial Inspecting System Configurations.

Folder

Purpose

/acct

The cgroup mount point—accounting and monitoring of CPU resources

/cache

Temporary storage for downloads in progress and also used for nonessential data

/data

Directory containing apps and other application-specific storage

/dev

Device nodes, as in a classic Linux system, though not used as prolifically for device and hardware driver access

/etc

A symbolic link to /system/etc/ contains configuration scripts, some of which are launched at startup during the bootstrapping process

/mnt

A temporary mount point, akin to many other traditional Linux systems

/proc

Contains data structures and information about a process, as in traditional Linux- or Unix-based systems

/root

Typically an empty directory, but akin to the root users home directory as on many Linux/Unix systems

/sbin

A folder containing important utilities for system administrative tasks

/sdcard

Mount point for the external SD cards

/sys

Mount point for sysfs, holds exported kernel data structures

/system

Immutable (read-only) binaries and scripts generated during the system build; on many Android systems, this also holds system-owned applications

/vendor

A directory set aside for vendor-specific augmentations to the device, including binaries, applications, and configuration scripts

/init

The init binary executed during the bootstrapping process after the kernel has been loaded

/init.rc

The configuration script for the init binary

/init[device_name].rc

The device-specific configuration script

/ueventd.rc

The uevent daemon configuration script

/uevent[device_name].rc

The device-specific configuration script for the uevent daemon

/default.prop

The configuration file containing global properties for the system, including device names

/config

The mount point for configfs

/storage

The added directory for 4.1 devices and up; used as a mount point for external storage

/charger

A native standalone application that displays the battery's charge progress

Please keep in mind that the vendor builds of the devices may differ; take these to be the most basic, untouched filesystem layouts and purposes. Often, vendors also make mistakes in their usage of some of these file paths and go against their intended purpose, so keep an eye on the purpose of these folders and the default access rights.

This section doesn't go into full detail with the filesystem layout; however, there are some good sources on the semantics, layout, and conventions for Android and Linux filesystems in the See also section.

Let's look at how to hunt for interesting file- or directory-based targets on an Android system. The following walkthrough assumes you have ADB shell permission on the device being assessed.

Getting ready

In order to use the commands mentioned in the following example, you will need to be able to either install the find binary or Busybox for Android; the instructions for installation can be found at http://www.busybox.net/ and in the Setting up Busybox section of the Automated native Android fuzzing recipe at the end of this chapter.

How to do it...

To search for files with respect to their access rights, you can find a list of readable files by executing the following command in your ADB shell; firstly, for world readable, this command does the trick:

find [path-to-search] –perm  0444 –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

The previous screenshot—and the subsequent ones in this section—were taken from a rooted Samsung Galaxy S3. Here the command-line instruction included a redirect to /dev/null in order to omit the erroneous output caused by permission denial.

Tip

Just a little caveat for non-Linux/Unix users

/dev/null acts like a sort of "blackhole" for output, allowing Linux/Unix users to use it as a place to put output they are not interesting in seeing. As an added benefit, it also returns a value to let you know whether the write operation succeeded.

Moving on, if you're looking for world writable files, you can find them using the following arguments:

find [path-to-search] –perm  0222 –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

And for files that have executable permission set for all users:

find [path-to-search] –perm  0111 –exec ls –al {} ;

You aren't explicitly required to use the octal format; the find command also understands the popular shorthands for user collections and permissions.

For instance, to find files readable to everyone outside of the owner's group, you specify permissions this way:

find [path-to-search] –perm  a=r –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

The previous specifications will ensure only exact matches; this means files returned must have only the bits specified. If you're looking for files with at least the specified bits set and any of the other bits—which you will probably be doing most of the time—you can specify the permissions by including a - symbol as a prefix as in the preceding example. For the octal mode, this will work as follows:

find [path-to-search] –perm  -444 –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

This will at least match files that have read bits set for all user collections, which means the 445, 566, 777, and so on permission bits will be matched. And the 344, 424, 222, and so on would not be matched.

A couple of really useful access right patterns you would probably be interested in looking for include finding executable files with setuid:

find [path-to-search] –perm  -4111 –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

In the previous screenshot, we see that the su binary was found using the preceding command. If you ever find this binary on an Android device, it's always a strong indication that the device has been rooted.

You can also find files with setguid and execute permissions for all:

find [path-to-search] –perm  -2111 –exec ls –al {} ;

See the following screenshot for the sample output:

How to do it...

The find command also allows you to specify users as part of the search criteria; for instance:

  • You could list all the files that belong to the root user as follows:
    find [path-to-search] –user 0 –exec ls –al {} ;
    
  • You could list all the files for the system user as follows:
    find [path-to-search] –user 1000 –exec ls –al {} ;
    
  • You can also list files according to the group ID setting as follows:
    find [path-to-search] –group 0 –exec ls –al {} ;
    

You may want to get an idea of how much each user—or rather, application—on your Android system has access to, and to do this you may want to build a list of user IDs—or, more importantly, UIDs for applications. The easiest way to do this is to dump the access rights for the files in the /data/data directory since it contains the data for most of the apps installed on the Android device. However, in order to access this list from an ADB shell, you'll need access to the root or system account or any account that has equivalent permissions; this is easy to obtain on an emulator—it's granted automatically. Alternatively, if you so choose, you could fire off a couple of searches to the XDA developers site to look for a method to root your phone. The XDA developer's site is available at http://www.xda-developers.com/.

There are both good and bad things about rooting your phone; in this case, it allows you to inspect the filesystem and access rights in more detail. However, on the other hand, if access to root privileges are not managed properly, it can expose your phone to a number of very devastating attacks! So be stingy with your root permissions and only temporarily root phones when they need to be rooted.

Moving on, if you list all of the files in the /data/data directory, you should see the following; this is taken from a Samsung Galaxy S3:

How to do it...

You may notice the odd naming convention for each app, namely u[number]_a[number], which means to say u[profile number] for the user profile the app is installed on—since some Android versions support multiple user profiles, namely everything from Jelly Bean and later—and a[number], which is the application ID.

You can use the application ID to construct the actual system user ID (UID) for the app by adding this number to 10000; for instance, for the Mozilla installation that has a username of u0_a170, the corresponding UID will be 10170. To find all of the files that have this UID as its owner, you would then execute this command:

find /data/data/ -user 10170 –exec ls –al {} ;  2> /dev/null

See the following screenshot for the sample output:

How to do it...

You can find other usernames by checking out the Android_filesystem_config.h file referenced in the See also section of this recipe.

There's more...

A command that can make the output of the find command a little more useful is stat. This command displays properties of the file and allows you to specify the format in which you'd like these details to be displayed. The stat command has a myriad of features and makes hunting for incorrectly "permissioned" files a much more informative experience than just calling ls –al via the find –exec command.

You can use stat with find as follows:

find . –perm [permission mode] –exec stat –c "[format]" {} ;

For instance, if you'd like to display the following:

  • %A: The access rights in human-readable format
  • %u: The user ID of the file owner
  • %g: The group ID of the file owner
  • %f: The file mode in raw hex
  • %N: The quoted file name with dereference if it's a symbolic link

You can do so by executing the following command:

find . –perm [permission] –exec stat –c "%A %u %g  %f  %N" {} ;

This command produces output as follows—here the example uses -0666 as an example permission mode:

There's more...

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.243.18