Exploring the iPhone file system sandbox

Wed Sep 12 14:28:28 UTC 2012

Exploring the iPhone file system sandbox

There is a little known way to explore the iPhone file system without jailbreaking, at least on iPhone 4 and iOS 5.1.1:

  1. Take any app with file browser or FTP server functionality.
  2. Create a relative symbolic link to the file system root in its Documents folder:
    $ ifuse --appid APPID ~/mnt
    $ cd ~/mnt
    $ ln -snf ../../../../../.. root
    
  3. Open the app (or the FTP client)
  4. Enjoy!

Note that sandbox restrictions still apply; you will not be able to read another app's data this way.

I also did a brute force search for writable directories outside the app sandbox, and did not find any. I wrote this script for the purpose:

#!/usr/bin/perl

use strict;
use warnings;

use Net::FTP;

my $list_regex = qr/
        ^
        (?<type>d)
        (?<perms>\S+)
        \s+
        (?<links>\S+)
        \s+
        (?<user>\S+)
        \s+
        (?<group>\S+)
        \s+
        (?<size>\S+)
        \s+
        (?<date>\w\w\w\ .{8})
        \s+
        (?<name>.*)
        $
/x;

@ARGV == 5
        or die "Usage: $0 host port user pass root";
my ($host, $port, $user, $pass, $root) = @ARGV;

my $ftp = Net::FTP->new("$host:$port", Debug => 0, Passive => 1)
        or die "No ftp: $@";
$ftp->login($user, $pass)
        or die "No user/pass: $ftp->message";

open my $fh, ">", "ls-lR.txt"
        or warn ">ls-lR.txt: $!";

my @results = ();

my @queue = ($root);
while(@queue)
{
        my $item = shift @queue;
        print STDERR "[$item] found @{[scalar @results]} results\n";
        $ftp->mkdir($item . "/WRITETEST");
        my $list = $ftp->dir($item);
        print $fh "$item:\n";
        for(@$list)
        {
                print $fh "$_\n";
                /$list_regex/
                        or next;
                my $name = $+{name};
                next
                        if $name eq '.' or $name eq '..';
                if($name eq 'WRITETEST')
                {
                        push @results, $item;
                        $ftp->rmdir($item . "/WRITETEST");
                        next;
                }
                push @queue, "$item/$name";
        }
        print $fh "\n";
}

close $fh;

print "$_\n"
        for @results;

$ftp->quit;

UPDATE: This symlink hack has been fixed in iOS 6. I found a new way to create this link; however, apparently due to an issue in ideviceinstaller, doing this loses the Documents content of the app:

$ ideviceinstaller -o uninstall -o remove -o copy=. -a com.dspmobile.dbmeterpro
$ unzip -l com.dspmobile.dbmeterpro.ipa
$ mkdir -p "Payload/dB Meter Pro.app"
$ ln -snf ../../../../../.. "Payload/dB Meter Pro.app/root"
$ zip -0y com.dspmobile.dbmeterpro.ipa "Payload/dB Meter Pro.app/root"
$ ideviceinstaller -i com.dspmobile.dbmeterpro.ipa
$ ifuse --appid com.dspmobile.dbmeterpro ~/mnt
$ ln -snf "../dB Meter Pro.app/root" ~/mnt/root
$ fusermount -u ~/mnt

Posted by OpBaI | Permanent link | File under: ios, perl