About | Buy | Forum | Industry Watch | Learning Curve | Products | Search | Twitter | Xnews
Home » Learning Curve » Developers Workshop

Apple Rooting Their Own Systems?

And this has gone undetected for a year?


Buy It

Try It

CUPERTINO (Rixstep) — The lengths some will go to in order to accomplish the questionable: after years of playing 'cat and mouse' with hidden directories (really hidden - and not the kind that bake fanboy noodles) Apple seem to have gone to the 'root kit' concept to keep things out of sight and out of touch. Which makes the conscientious user all the more uneasy about trusting Apple with anything. For how can a user ever feel safe knowing they're hiding things out of reach on one's own property?

And it's got those who made the discovery scratching their heads and asking: 'for what purpose?'

But the evidence seems clear: where Apple heretofore tried thwarting access to system areas with wild file names, today they're hooking into syscall through the OS kernel instead.

For the supposedly 'inaccessible' (and hidden) directories are fully accessible when 10.7 drives are mounted from other versions of the same operating systems - to then yield totally different system data.

Back a Few Steps

But first back a few steps in order to explain what's going on.

Rixstep's GDE was introduced back in the days of 10.4 Tiger. GDE stands for 'getdirentries', the name of the lower level Unix API for accessing directory data.

There are two directory enumeration calls in Unix: getdirentries and readdir. The difference is that the one gives you it all and the other gives you only what you conceivably can need.

But Apple played cheeky here, injecting code of their own to change the 'what you conceivably can need' to 'what we don't want you to ever see'.

GDE was introduced five years ago today. And the signs of what was to follow were already there.

A special version of Xfile called 'Red Pill' was released shortly thereafter.

Both applications used the lower level getdirentries to do their dirty work.

Despite being 'hidden' and 'cloaked' (not returned by readdir) and despite having a zero inode, +HFS Private Data was eminently accessible.

Something Happened

Accessing +HFS Private Data when it had a zero inode shared with other files should have been impossible. Yet it wasn't. Leading one to conclude that it wasn't Unix APIs from a Unix file system at work. More likely HFS constructs.

But that seems to be a thing of the past. As is the case with /.vol.

Ryan Kubasiak of Apple Examiner has been working on an article series on Apple file systems.

I'd like to write my article looking at the HFS+ Private Data folder as a specific example. I can see the folder through the GDE app. How do I give the app privs so I can navigate into this area and show the contents? I think I'm still doing something wrong. I haven't been successful yet.

Hi Ryan,

You're not doing anything wrong. That's 'Unix'. But we suspect Apple upped the ante here. We've not looked into this before but they seem to be dodging things again.

Ryan had used forensic tools for grabbing disk images and was able to see the contents of the hidden directories. But even GDE and its low level access with getdirentries didn't help.

Computer science student Marco Gambero of the University of Rome began digging.

Yes, I see. I can't cd them. No info sheet, 'No such file or directory'. Can't even chmod from the command line. No way. Uh, WTF is going on?

Then:

Made some tests.

1.
You can't cd the hidden directories even on an other volume. Even if it contains a 10.6 installation. Even if this other volume is mounted with 'noowners'. You always get the no such file error.

2.
If you boot on 10.6 and then mount the volume (+noowners) with 10.7 you *can* stat and cd the hidden directories on this volume. No errors.

'.HFS+ Private Directory Data' is accessible w/o a chmod. Is empty.

'␀␀␀␀HFS+ Private Data' contains the usual iNodeXXXXXX files, you must chmod to cd.

Then I reboot on the 10.7 volume. These are still inaccessible, even the one I chmoded.

Maybe they wrap syscalls to not permit access to these directories? Reminds me of the thing with dtrace - you can't dtrace an __APPLE__ binary, no? I think the whole thing is simply perverse.

The Screenshots

Marco also provided myriad screenshots to clarify what he'd found.

Entering HFS+ Private Data from a remote computer. [Note all the files have Finder gunk on them.]

Looking at iNode100123 with Xattrib. [Yes the file really exists.]

Navigating 'HFS+ Private Data' on 10.7.4 with GDE run from a 10.6 system.



iNode100123 turned out to be the trio bunzip, bzcat, and bzip2.

And 'HFS+ Private Data' of course eminently accessible.

The Basic Test

Back on 10.7, Marco corroborated a simple basic fact Rixstep found two days earlier.

#include <sys/stat.h>
#include <stdio.h>

int main() {
    struct stat st;

    if (stat("/.HFS+ Private Directory Data\x0d", &st))
        perror("stat() failed");

    return 0;
}

--

No error on 10.6.8 (no root).

On 10.7.4 (with or w/o privileges) you get:

$ ./a.out
stat() failed: No such file or directory

Now What?

Apple have been playing a 'cat and mouse' game with their non-Unix hidden directories and files for years. They've made subtle changes to the file names. Last time around (10.6) they used funky filenames in /var/folders with '-Cache-' and '-Tmp-' in an attempt to thwart script kiddies. (They've since tired of that.)

But now they seem to have upped the game again. Using who knows what type of gunk - most likely hooks into syscall that are tantamount to what a root kit does - they continue to run, obfuscate, and hide.

And nobody can understand why. Or how the great 'Mac developer community' can remain so silent.

Postscript: hfs_vget()

From the source to XNU.

/*
 * Look up an HFS object by ID.
 * * * *
 */
int
hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock, int allow_deleted)
{
    /* * */

    /* Check for cnids that should't be exported. */
    if ((cnid < kHFSFirstUserCatalogNodeID) &&
        (cnid != kHFSRootFolderID && cnid != kHFSRootParentID)) {
        return (ENOENT);
    }
    /* Don't export our private directories. */
    if (cnid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid ||
        cnid == hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) {
        return (ENOENT);
    }

    /* * */
}

See Also
GDE - Got Root?
Developers Workshop: GDE-FAQ
Developers Workshop: Getting Around HFS+ Private Data
Developers Workshop: GDE Screenshots
Developers Workshop: Red Pill
Developers Workshop: Red Pill Screenshot 2
Developers Workshop: Red Pill Screenshot 3
Apple Examiner: OS X Folder Layout - Part 1
Apple Examiner: OS X Folder Layout - Part 2
Learning Curve: Apple and the Myth of Unix

About | Buy | Forum | Industry Watch | Learning Curve | Products | Search | Twitter | Xnews
Copyright © Rixstep. All rights reserved.