Apple Configurator has now been in my grubby hands long enough for me to start looking at it a little deeper than I did in the introductory article I did awhile back
. Architecturally, Apple Configurator keeps its data in ~/Library/Application Support/com.apple.configurator. Here, you’ll find a directory called IPSWs, another called Resources, file called AppleConfigurator.storedata and another called Users.storedata.
The IPSWs directory is where operating system versions, per model of iOS are stored. These look something like iPad2,1_5.1_9B176_Restore.ipsw, which is iOS 5.1 for a standard iPad 2. iPad 1, the retina display iPad, as well as each iPod Touch and iPhone 4 each have their own entry as well. The IPSWs are automatically downloaded here when you initially perform a restore using Apple Configurator for each model of iOS device. You can copy each model’s ipsw into this directory proactively to keep Apple Configurator from downloading updates. You can also populate this directory manually with older copies of iOS if you are running them or if you are a developer, with developer releases of ipsw files.
The Resources directory is going to house applications and documents/content that you’ll be pushing to devices if you use the Assign options to assign content (and possibly other assets, although thus far I seem to only be getting apps and documents in here). They don’t look like applications or documents though. Each entry in this directory is assigned a generated identifier. The size of each and date/time stamp should match the size of the object and when it was added to Apple Configurator, respectively. When you delete an application or document from Apple Configurator then you should see the entries here disappear. Running strings against the entries that are applications, you should be able to identify which is which pretty quickly. Running such commands against documents (or other assigned content) can net much spottier results due to the fact that there aren’t always references to what you’re looking at inside of what you’re looking at… Either way, just looking at the raw data that comprises these application and content objects isn’t the only way to grab the name of the file. We’ll take a look at that a little later.
In addition to these two directories, Apple Configurator can throw data almost anywhere because it allows users to do so when creating backups of devices. These backups are in the form of files ending with .iosdevicebackup and by default getting placed into ~/Documents. When these are created, they can be saved to any location you choose. Deleting them from the file system automatically causes Apple Configurator to forget about them (although I have had to restart the application after removing the .iosdevicebackup file).
And then there’s the databases. As I mentioned, there are two, AppleConfigurator.storedata and Users.storedata. These are both sqlite databases and are both accessible through standard sqlite3 commands/queries. I haven’t been able to find any documentation of what each table is used for, but I’ve run devices through a number of regressions and think I’ve mostly pieced it together, which I’m in some cases able to back up with writing directly to the SQL table. Each database consists of the following tables (although not all are used and in some cases they are used for different purposes in each database), which I show followed by a description of what I think each is doing along with the more important columns of each table:
- ZAPPINSTALL: In AppleConfigurator.storedata keeps track of applications that have been deployed via Configurator. Each application has a ZAPPLICATION column, which is a numeric identifier for each application. The ZCODE is a human readable column that shows what kind of application was deployed and the ZDEVICERECORD indicates which device that Apple Configurator placed the application on. This table does not appear to be used in Users.storedata.
- ZMOBILEAPPLICATIONICON: In the AppleConfigurator.storedata, the Z_PK column in this table should match the ZDEVICERECORD column in ZAPPINSTALL. Other than that, thus far the columns appear to be the same for each row. This table does not appear to be used in the Users.storedata.
- ZDEVICEPROPERTIES: Not used in Users.storedata, the table in AppleConfigurator.storedata is used to track information about devices under supervision. The Z_PK column does not match the Z_PK column in the ZMOBILEAPPLICATIONICON but the ZECID, ZDISKCAPACITY, ZENABLEWIFICONNECTIONS, ZBLUETOOTHADDRESS, ZBUILDVERSION, ZDEVICECLASS, ZNAME, ZPRODUCTVERSION, ZSERIALNUMBER, ZTYPE and ZUDID match what their names imply if you de-prefix the Z from the column names.
- ZPROFILE – Each profile created is tracked in this table. Given that a profile is just a property list, the ZDATA column consists of text data that we’ll look at a little more in a bit. The ZPAYLOADUUID column is a unique identifier for the payload, which appears in the payload as well. The ZNAME column tracks the user-enterable name for each profile you create.
- Z_19MEMBERS: Not used in AppleConfigurator.storedata, this table is used to track manual group membership in the Users.storedata database.
- Z_15SUPERVISIONRECORDS: Table used to track supervision with manually created groups.
- ZDEVICERECORD: Each iOS device that has been docked into Apple Configurator is tracked using this table. Here, the name of the iOS device is trapped in the ZNAME column, the serial number in the ZSERIALNUMBER column and the UDID of the device in the ZUDID column.
- ZSUPERVISIONRECORD: AppleConfigurator.storedata uses this table to attach UUIDs for users (in the ZPOLICYUSERUUID column and ZUSERUUID columns) to devices (ZUDID and ZDEVICESERIALNUMBER columns)
- Z_METADATA: Used in both .storedata databases, appears to link a UUID to a property list.
- ZIPSWPACKAGE: Doesn’t appear to be used. Based on the column headers, I think this table is supposed to link the IPSW path to the build version and device types. This seems to be getting derived from elsewhere though (e.g. the metadata directly on IPSWs). Given that you can drop an IPSW into the directory and it will just use it I, I think that Configurator is just getting the data directly from the bundleID and skipping this altogether, which given the relatively small number of IPSWs that people will use doesn’t seem to be very costly in terms of runtime/efficiency… For me the jury is still out on this as I haven’t made it do anything yet.
- ZSUPERVISIONRECORDGROUP: Stores information about manually created device groups (as opposed to user groups). The ZNAME column is where the name you enter for the group is kept, so you can direct queries here to see the rest of the contents for each row. Used by AppleConfigurator.storedata, not Users.storedata.
- Z_PRIMARYKEY: The Z_NAME row in this table is the same in both Users.storedata and AppleConfigurator.storedata as is the Z_SUPER column. However, the Z_MAX is different, as it indicates the highest number of entries (in terms of IDs) in the column for the corresponding object (e.g. the highest Z_PK entry in the ZMOBILEAPPLICATION table).
- ZMANAGEDFILEOBJECT: The users.storedata table uses this directory to track data that has been assigned to each user. The ZURLSTRING column indicates the path to the file, the ZAPPLICATION IDENTIFIER indicates the application the file is bound for in the iOS filesystem and the ZNAME1 column indicates the name of the object. This table is also used in the AppleConfigurator.storedata database, but there it simply lists the instance of each application, the generated ID for the application and the location on the filesystem.
- ZUSER: Show’s the UUID of the user in the ZUUID column, which matches with the ZUSERUUID in column in the ZSUPERVISIONRECORD table, (assigned in Configurator), whether there is an image for the user from the directory service (ZIMAGEISFROMDIRECTORY column, boolean), the hash of the image if there is one (ZOPENDIRECTORYIMAGEHASH column), the device the user has checked out (ZDEVICESERIALNUMBER), the last device the user checked out (ZLASTDEVICESERIALNUMBER), the Open Directory GUID (ZOPENDIRECTORYGUID) for the user, the short name (ZOPENDIRECTORYSHORTNAME) and the directory domain (ZOPENDIRECTORYNODEPATH). This data is, as you can imagine, in Users.storedata and the AppleConfigurator.storedata for this table is empty.
- ZMOBILEAPPLICATION: Empty for Users.storedata, but keeps all the fun info on apps for AppleConfigurator.storedata. It keeps the name the app should have (ZNAME), the version of the app (ZVERSION), the identifier for the app (ZIDENTIFIER), the genre (ZGENRE), the author (ZAUTHOR) the price paid for the app (ZORIGINALPURCHASEPRICE), the app image (the ZMOBILEAPPLICATIONICON Z_PK column matches the ZDATA and ZIMAGES columns here), whether you can push content to the app (using the ZSUPPORTFILESHARING column), whether the app is an enterprise app (ZISENTERPRISEAPP). The app has told Apple Configurator all of this information (notice when you add an app you have to have an internet connection) and so if you try and change it the app won’t deploy.
- ZUSERGROUP: Empty for AppleConfigurator.storedata, lists the name (in the ZNAME column) of groups, the Open Directory GUID if it’s an Open Directory group (ZOPENDIRECTORYGUID). You could do an export from dscl and then import it here if you wanted to pop a whole lot of groups into Apple Configurator.
Note: Again, these are my initial ideas of what these are. I’ll change them if I discover they’re something different or link to official documentation of the table map if it’s released.
Now that we know roughly what’s where, let’s put that to use. Let’s start with just getting some information on what profiles are installed in Apple Configurator. Here, we can run a SQL select to look at all the rows in the ZPROFILE table, by calling the sqlite3 command (in /usr/bin), using the SQL table as our first position and then putting our select query in quotes, which in this case is to select all (*) information from the ZPROFILE table:
sqlite3 ~/Library/Application Support/com.apple.configurator/AppleConfigurator.storedata 'SELECT * FROM ZPROFILE'
To export a profile from Apple Configurator’s database using sqlite3 (which means you can do this from a centralized location), use the sqlite3 command, selecting the database and then run a select for the ZPROFILE table, selecting the ZNAME record called Pretendco Deployment and then send the output to a file called test.mobileconfig:
sqlite3 ~/Library/Application Support/com.apple.configurator/AppleConfigurator.storedata 'SELECT * FROM ZPROFILE WHERE ZNAME = "Pretendco Deployment"' > test.mobileconfig
Strip the first line of that file out and you’ve got yourself a mobileconfig file.
To see all of your applications:
sqlite3 ~/Library/Application Support/com.apple.configurator/AppleConfigurator.storedata 'SELECT * FROM ZMOBILEAPPLICATION'
Or if that’s too much output (it is), then just look at the names of the apps:
sqlite3 ~/Library/Application Support/com.apple.configurator/AppleConfigurator.storedata 'SELECT ZNAME FROM ZMOBILEAPPLICATION'
These are just a few light queries. You could easily expand on this to export all of the profiles as mobileconfigs, dump a list of each iOS device that has each app installed, a list of which users have which devices, which users have which apps, which devices are running low on disk space, etc. Overall, the sqlite queries are similar in nature (or can be) to what we were doing in the scripting iPhone Configuration Utility article
I did awhile back; however, there are a lot more options here.
krypted March 28th, 2012
Posted In: iPhone, Mac OS X Server, Mass Deployment
Apple Configurator, developer, documents, iOS 5, iosdevicebackup, iPad, iphone configuration utility, ipsw, Lion, location, Open Directory, path, payload, profile, scripting, select where, sqlite3, user, ZMOBILEAPPLICATION, ZUSER, ZVERSION
One of my favorite tools for penetration testing is Nessus from Tenable Network Security. Nessus 5 is the latest release in the family of vulnerability scanners that is probably amongst the most prolific. Nessus 5 does discovery, configuration auditing, profiling, looks at patch management and performs vulnerability analysis on a variety of platforms. Nessus can also run on a Linux, Windows or Mac OS X and can be used to scan and keep track of vulnerabilities for practically any platform, including Mac OS X.
To install Nessus, go to the Nessus site
and click on the Download button, around the middle of the page. Agree to the download agreement and then choose the version that is right for you (Mac OS X in this case).
Download Nessus for Mac OS X
The software will then download and need to be installed. Once downloaded, open the Nessus dmg and extract it. Inside will be the Nessus 5 package installer.
The Nessus Installer pkg
Open the installer and click through the defaults to perform a basic installation.
Once done, you’ll have the Nessus Server Manager and Nessus Client.url in a Nessus folder in the Applications directory.
The Nessus Applications
Open the Nessus Server Manager and authenticate as an administrator when prompted. When you downloaded the software you would have been prompted for registration. Provide that information in the registration field. Then click on Update plugins to make sure all of the Nessus plugins are running the latest version. Finally, click on Manager Users… to create your users.
Nessus Server Configuration
At the list of Nessus users, click on the plus sign and create a new user, likely making the user an admin (I see few vulnerability scanning stations that have non-administrative users, which would just be for viewing reports and the such). Click Save to create the user and then close at the List of users screen.
Create Nessus Users
If the Nessus server isn’t started, click on Start Nessus Server. Then click on the Nessus Client.url file back where the Nessus Server manager was accessed. At the Nessus login screen, provide the username and password for the Nessus server that was previously created.
Authenticate to Nessus
Once authenticated, you will be placed in the Scans screen. Before we configure any scans, we’re first going to create a Policy (which defines how a scan operates for the most part). To do so, click on Policies and then click on the Add button. There are four policy tabs (aligned on the left sidebar). In the General pane, you will configure the name for the Policy, “Mac Servers” in this example. Then we’re going to check the boxes in the Scan section for Designate Hosts by their DNS Name, Log Scan Details to Server, Stop Host Scan on Disconnect and Avoid Sequential Scans. Then check the boxes in the Port Scanners section for TCP, SYN, SNMP, Netstat SSH and Ping Host. Leave the Port Scan Range set to default and the Performance options at their default values as well. These are useful when you’re done tinkerating to get better performance out of the system, but we’re not really there just yet.
Nessus' General Policy Settings
Click on the Next button to define any credentials you’ll use during scans. Initially, I’d leave this blank, although you can provide SMB information for up to 4 accounts to see what kind of access users have. You can also define Kerberos, SSH and various cleartext credentials as well. We’re going to skip that for now and click Next to define the Plugins.
Giving Nessus Credentials To Your Boxen
At the Plugins screen, we’re initially going to leave all of the plugins on. The reason for this is that many of the Lion Server services are similar to those of the various Unix and Linux variants and we can scan SMB with the Windows plugins. These can’t hurt, they might just waste a little time though. Clicking on a Family and then a plugin will show you what each does. Clicking on the green light for each will disable it.
Choosing Nessus Plugins
Click on Preferences and define any preferences that you need. Amongst the plugin preferences I usually enable network printer scanning, CGI scanning, Enable experimental scripts, set my Report verbosity to Verbose, provide any certificates needed and then hit Submit to create the new Policy.
Defining Nessus Options
Next, let’s click back on Scans in the navigation bar on the screen. As you can see here, I’ve created a few template scans, but we’re going to create a new one by clicking on the Add button.
Adding A Nessus Template
Provide a name for the scan and then choose the Policy you just created. Set the Type to Run Now (since we’re just testing) and put the IP address of a target into the Scan Targets field. You can also import a large set of targets using the Brows button and a csv file or use Schedule or Template rather than Run Now in the Type field to schedule scans or create a template scan. Click Launch to kick off the first scan.
Running a Manual Test Scan
Once started, click on the Reports button in the top nav bar to see the status of the scan.
Completed Nessus Scan
Once the scan is finished, click on the scan to see a list of vulnerabilities and open ports, sorted by the severity of issues. Here, double-click on the host.
Nessus Scan Results Overview
The Report screen then shows each service and the vulnerabilities found for that service. Click on one of the vulnerabilities to see what Nessus thinks is problematic with it.
Nessus' Service List
Now for the fun part. Each of the vulnerabilities listed will have CVEs attached.
Nessus Vulnerability Listing
By default, Nessus is just looking at the service banners to determine vulnerabilities. If you look up the CVE at CVE Details or PacketStorm you’ll see that it was patched a few months ago by most vendors. Now Nessus can get things wrong with Mac OS X. The issue is that Apple forks the code for many open source projects, not always updating version numbers on banners. Looking up or testing whether a vulnerability is still applicable can be tedious but would likely need to be done per service according to your internal security policies.
An easy way to test these vulnerabilities is to use Metasploit, a tool I’m long overdue to write an article on. Another way is to try and run the exploit against the host. Apple does a pretty good job of addressing CVEs in their security updates, so don’t waste a lot of time trying things if Apple has already patched them. I have found a really good tool for automatically attempting to exploit via msf + nessus to be Carlos Perez’ auto exploit tool, available on github
Finally, Nessus is a great tool for scripting. One of the big differences that throws off many an experienced Nessus operator off with the version for the Mac is the location of the Nessus binaries. They are in /Library/Nessus/run/bin. In here you’ll find nasal, nessus, nessus-fetch, nessuscmd etc. The command line control here is pretty awesome. Let’s run nessuscmd to scan a net mask of hosts (192.168.210.0/24):
sudo /Library/Nessus/run/bin/nessuscmd 192.168.210.0/24
There are tons of other options for nessuscmd, such as adding ssh keys, smb logins, scanner options, using a remote nessus server, etc. Or use the nessus binary to kick off scans using a nessus config file. The nessus.conf file is also stored in the /Library/Nessus/run/etc/nessus directory, worth looking into.
krypted February 23rd, 2012
Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment
Apache, commands, eve, Lion, lion security, lion server, Mac OS X, Mac OS X Security, nessus, nessuscmd, path, Policies, Security, security scanner, vulnerability scanning
When I install a new system that I am personally going to be using, one of the few tweaks I make is to configure the Finder to show me paths in the title bar. This just keeps me from the occasional Command-click on the folder name and keeps me abreast of where I am. Mostly it’s helpful in list or icon view as. To enable full paths
use defaults to write an _FXShowPosixPathInTitle key into com.apple.finder.plist. The key should be boolean and we’re setting it to true. After about 30 seconds new windows should show with the path in the title bar:
defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
I actually add this to my user template
at imaging time for my personal system workflow, so that I don’t even have to think about it… So I almost forgot how to do it. Luckily, a quick peak at my user template reminded me when I was building a new imaging environment for Lion… If you decide it isn’t for you, feel free to set it back by setting the key to NO:
defaults write com.apple.finder _FXShowPosixPathInTitle -bool NO
krypted July 27th, 2011
Posted In: Mac OS X
deployment, finder hacks, Lion, Mac OS X, path, profile, see path in title bar, title bar
There are two commands that can be really helpful when scripting operations that involve filenames and paths. The first of these is dirname: dirname can be used to return the directory portion of a path. The second is basename: basename can be used to output the file name portion of a path.
For our first example, let’s say that we have an output of /var/db/shadow/hash/850F62CD-966C-43A7-9C66-9F9E6799A955, which we know contains the encrypted password for a given user. To just see the UUID here would be done using the following extremely basic incantation of basename:
Basename can also be used to trim output. For example, let’s say we didn’t need the final portion of the above filename in our output. We could run basename using the -s option, followed by the string at the end that we do not want to see to output of just the first 4 sections:
basename -s -9F9E6799A955 /var/db/shadow/hash/850F62CD-966C-43A7-9C66-9F9E6799A955
The dirname command is even more basic. It outputs the directory portion of the file’s path. For example, based on the same string, the following would tell you what directory the UUID files with the passwords are stored in:
A great example of when this gets more useful is keying off of currently active data. For example, if we’re scripting a make operation, we can use the which command to get an output that just contains the path to the make binary:
We can then wrap that for expansion and grab just the place that the active make binary is stored:
dirname `which make`
This allows us to key other operations off the path of an object. A couple of notable example of this is home or homeDirectory paths and then breaking up data coming into a script via a positional parameter (e.g. $1).
krypted May 27th, 2011
Posted In: Mac OS X, Mass Deployment, Ubuntu, Unix
basename, directory, dirname, Linux, Mac OS X, path, scripting, separate path from filename, Ubuntu
Samba can be a PDC, allowing Windows clients to join a single line domain name and then access domain resources (such as roaming profiles) as though the domain were Windows NT-based. When you set this up the default behavior for Mac OS X Server based domains is to create a drive mapping for H: to the users profile path (as specified in the homeDirectory attribute) on the server. H: is kinda’ low for some computers with a lot of drives and it can also conflict with other drive mappings you may choose to use. Therefore you may find that in some cases you need to change the H:.
To do change the drive letter that the logon drive uses, look to the /var/db/smb.conf file. Here, you’ll notice a logon drive variable which is set (funny enough) to H:. Specify any letter of the alphabet that you’d like it to use (preferably higher than H:) and then save the changes to the file and restart the service. Now you should see a new drive letter assigned at your next login event. You can also change a number of other variables in these files, so it’s recommended to back the file up before making any changes.
krypted August 14th, 2009
Posted In: Mac OS X Server, Windows XP
/var/db/smb.conf, drive letter, H:, Mac OS X Server, mapping, path, profiles, smb.conf, windows clients
There are a number of reasons you might choose to change the location of your iPhoto library. Maybe you want to store pictures on a firewire drive, or maybe you want to store them on an iSCSI LUN, which I described how to work with recently
. Either way, there are two ways I typically see people go about changing the location that iPhoto uses to store data. The first is to actually create a symbolic link from ~/Pictures/iPhoto Library to the directory you would like to use. The second, which is a better option is to go ahead and edit the location that the iPhoto preferences set as the path to the library (you would replace /Volumes/VolumeName/Path with the actual path to your storage):
defaults write com.apple.iPhoto RootDirectory /Volumes/VolumeName/Path
Once you have defined a new location, if you want to revert back to storing photos in your home folder you can then use the following command
defaults write com.apple.iPhoto RootDirectory ~/Pictures/iPhoto Library
defaults delete com.apple.iPhoto RootDirectory
krypted April 26th, 2009
Posted In: Mac OS X
iPhoto, iPhoto Library, location, path, RootDirectory, ~/Pictures/iPhoto Library