Jared Benedict
HomeGallery

documentation

Analysis of Apple's Mac OS X Software Update

Introduction

I got curious how the Software Update worked for about 10 minutes. I was wondering how hard it would be to set up a server on the local network which would provide updates for clients. So I decided to look. Below is what I found. I must note that I don't really know what I'm doing. So what is below could be wrong. The investigation was done on 16 April, 2004 with my PowerBook running Mac OS X 10.3.3, Software Update version 1.6.1.

Checking for updates

1.) Client: get request for: http://swscan.apple.com/scanningpoints/scanningpointX.xml

( cookie values: POD=us~en; higherEdSchool=1014940 )

view sample scanningpointX.xml (from 04/16/2004)

2.) Client: POSTs packages with versions of packages installed on the local client machine to:

http://swquery.apple.com/WebObjects/SoftwareUpdatesServer

view sample list of packages installed

3.) If there are packages to install, swquery responds with which packages they are. It includes where to download them from, and a description formatted with HTML. If there are no packages to install, the server responds with:

<!-- No updates -->

view sample of packages available for installation

Downloading Package

Client: get request for: http://a1036.g.akamai.net/5/1036/3093/1/verylongssessionidorsomething/iSightUpdater.tar

Installing Package

Not sure how this happens. I presume it basically uses the "installer" command (see below).

Configuring use of an Alternative Server

After looking around, it looks like the location of the server package list to download (http://swscan.apple.com/scanningpoints/scanningpointX.xml) is set in this binary:

/System/Library/PrivateFrameworks/SoftwareUpdate.framework/Versions/A/SoftwareUpdate

Note, that binary is symbolically linked in a couple places.

I've tried editing the url with a hex editor. I pointed it to a copy of the scanningpointX.xml file on my personal server. However, when I run software update it won't run. The command line version complains:

2004-04-16 18:06:51.362 softwareupdate[937] SoftwareUpdateCheck cannot be used with this configuration.
softwareupdate: Could not connect

SoftwareUpdateCheck is an executable located here:

/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdateCheck

Apparently it is run before the request is made because it doesn't even connect to my server when sniffing packets in ethereal.

I found the option: -ScanURL <url> while looking at SoftwareUpdateCheck in a hexeditor. When I use it on the command line, the command runs without complaint, but doesn't actually do any network check.

root# ./SoftwareUpdateCheck -ScanURL http://mysever.com/scanningpoints/scanningpointX.xml
2004-04-16 20:52:31.873 SoftwareUpdateCheck[548] Checking for updates

Software Update Application

GUI application located in: /System/Library/CoreServices

Pref plist located in: /Library/Preferences/com.apple.SoftwareUpdate.plist

Misc. Stuff

To run the softwareupdate command line app without getting any eula warnings etc. set the COMMAND_LINE_INSTALL environmental variable:

setenv COMMAND_LINE_INSTALL 1    (if using csh or tcsh)
COMMAND_LINE_INSTALL=1 export COMMAND_LINE_INSTALL    (if using bash or sh)

The "installer" command allows you install install packages and also allows the above environement variable.

See the installer man page.

On my Mac OS X 10.3.3 system, the installer version is 1.2.1. On my Mac OS X 10.2.8 system, the installer version is 1.1.0d2

It seem like it might just be easier to create a system for OS X clients to automatically download packages from an internal server (via rsync, ssh, curl, wget, etc) and use the installer command to do the installation. Getting only specific packages to specific clients in an efficient and secure mechanism requires more thought.

Resources

PhantomUpdate Exploit - details how, in an older version, Software Update could be tricked into downloading packages from another server.

MacOSXHints: A script to manage networked software updates - This hint was what first prompted my itch.