Skip to content

Instantly share code, notes, and snippets.

@JamesHopbourn
Forked from Wowfunhappy/download-mavericks.sh
Created March 13, 2025 13:47
Show Gist options
  • Save JamesHopbourn/e3c9dbd265835eeb5ecfd79dc56d3257 to your computer and use it in GitHub Desktop.
Save JamesHopbourn/e3c9dbd265835eeb5ecfd79dc56d3257 to your computer and use it in GitHub Desktop.
Download a Mac OS X 10.9 Mavericks installer image Apple
#!/bin/bash
#!/bin/sh
# Download script written by Wowfunhappy. Last updated 2025/03/07.
# Thank you to Krackers, Jazzzny, and others for helping analyze Apple's download process and debug this script.
# Thank you to dosdude1 for donating identifiers from a broken Mac.
# Any mistakes are mine alone.
BOARD_SERIAL_NUMBER="C0243070168G3M91F"
BOARD_ID="Mac-3CBD00234E554E41"
ROM="003EE1E6AC14"
# Helper functions
save_create_bootable_installer_script() {
cat << 'EOF' > "$1"
#!/bin/sh
set -e
cd "`dirname "$0"`"
asr imagescan --source InstallMacOSXMavericks.dmg
did_find_volume="false"
while [ $did_find_volume == "false" ]
do
printf "Please enter the volume name of your USB flash drive: "
read target_volname
if [ ! -z $target_volname ] && df -l | grep -q "/Volumes/$target_volname"
then
did_find_volume=true
elif [ ! -z $target_volname ]
then
echo
echo "Could not find a volume named $target_volname. Found these volumes:"
df -l | awk -F'/Volumes/' '{print $2}' | grep -v '^$'
echo
fi
done
printf "WARNING: All data on $target_volname will be erased. Continue? (yes/no) "
read confirmation
if [ "$confirmation" != "y" ] && [ "$confirmation" != "yes" ]
then
echo "Exiting. No changes have been made."
exit 1
fi
disk_identifier=$(diskutil list /Volumes/"$target_volname" | head -n 1)
sudo diskutil partitionDisk $disk_identifier GPT jhfs+ "$target_volname" 100%
sudo asr restore --source InstallMacOSXMavericks.dmg --noprompt --target /Volumes/"$target_volname" --erase
EOF
chmod +x "$1"
}
hex_to_bin() {
printf "%s" "$1" | xxd -r -p
}
check_for_utility() {
if ! command -v "$1" > /dev/null
then
echo "Error: Required utility '$1' is not available on your system." 1>&2
exit 1
fi
}
# Start here!
set -e
check_for_utility "hdiutil"
check_for_utility "curl"
check_for_utility "openssl"
if ! openssl dgst -sha256 < /dev/null > /dev/null 2>&1
then
echo "Error: The version of OpenSSL on your system does not support SHA-256." 1>&2
exit 1
fi
# To retrieve the installation payload from Apple, we must provide:
# 1. A server ID, retrieved from osrecovery.apple.com.
# 2. A client ID, randomly generated.
# 3. The board serial number and matching board id of a Mavericks-era Mac.
# 4. A key, a SHA-256 hash derived from:
# - The aforementioned client id.
# - The aforementioned server id.
# - A ROM matching the aforementioned board serial number and board id.
# - The SHA-256 hash of the aforementioned board serial number and board id.
# 1. Retrieve the server ID from Apple.
SERVER_ID=$(curl -fs -c - http://osrecovery.apple.com/ | tail -1 | awk '{print $NF}')
# 2. Generate the client ID.
CLIENT_ID=$(dd if=/dev/urandom bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n' | tr '[:lower:]' '[:upper:]')
# 4. Generate the key.
{
hex_to_bin "$CLIENT_ID"
hex_to_bin "$(echo $SERVER_ID | awk -F'~' '{print $2}')"
hex_to_bin "$ROM"
printf "%s" "${BOARD_SERIAL_NUMBER}${BOARD_ID}" | iconv -t utf-8 | openssl dgst -sha256 -binary
printf '\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC'
} > key_info
# Hash key_info using SHA-256, then convert raw binary output to uppercase hex.
KEY=$(openssl dgst -sha256 -binary < key_info | od -An -tx1 | tr -d ' \n' | tr '[:lower:]' '[:upper:]')
rm key_info
# Finally, retrieve the installation payload, which contains the asset token needed to download InstallESD.dmg.
INSTALLATION_PAYLOAD=$(curl -fs 'http://osrecovery.apple.com/InstallationPayload/OSInstaller' -X POST \
-H 'Content-Type: text/plain' \
--cookie "session=$SERVER_ID" \
-d "cid=$CLIENT_ID
sn=$BOARD_SERIAL_NUMBER
bid=$BOARD_ID
k=$KEY")
ASSET_URL=$(echo "$INSTALLATION_PAYLOAD" | grep AU | awk -F': ' '{print $2}')
ASSET_TOKEN=$(echo "$INSTALLATION_PAYLOAD" | grep AT | awk -F': ' '{print $2}')
if [ "$ASSET_URL" != "http://oscdn.apple.com/content/downloads/33/62/031-10295/gho4r94w66f5v4ujm0sz7k1m0hua68i6oo/OSInstaller/InstallESD.dmg" ]
then
echo "Error: Server did not provide the Mavericks InstallESD URL." 1>&2
exit 1
fi
echo "Downloading InstallESD.dmg..."
curl --progress-bar "$ASSET_URL" -H "Cookie: AssetToken=$ASSET_TOKEN" > InstallESD.dmg
# Verify the checksum of InstallESD.dmg because it was downloaded over unencrypted HTTP.
echo "Verifying integrity of InstallESD.dmg..."
if [ $(openssl dgst -sha256 InstallESD.dmg | awk -F'= ' '{print $2}') != "c861fd59e82bf777496809a0d2a9b58f66691ee56738031f55874a3fe1d7c3ff" ]
then
rm InstallESD.dmg
echo "Error: Download failed (mismatched checksum)" 1>&2
exit 1
fi
echo "Building InstallMacOSXMavericks.dmg..."
# Inside InstallESD.dmg is another image, BaseSystem.dmg, which contains a minimal Mac OS X recovery environment.
# Additional data from InstallESD.dmg must be copied into BaseSystem.dmg to build a complete Mavericks installer.
# Ensure no volumes with these names are already mounted.
hdiutil detach "/Volumes/OS X Base System" 2> /dev/null && sleep 2 || true
hdiutil detach "/Volumes/OS X Install ESD" 2> /dev/null && sleep 2 || true
# Convert BaseSystem.dmg to a modifiable image with sufficient free space for the additional data.
hdiutil attach InstallESD.dmg -nobrowse
hdiutil convert -ov "/Volumes/OS X Install ESD/BaseSystem.dmg" -format UDSP -o "InstallMacOSXMavericks.sparseimage"
hdiutil resize -size 6550020096 "InstallMacOSXMavericks.sparseimage"
# Copy additional data into BaseSystem.
hdiutil attach "InstallMacOSXMavericks.sparseimage" -nobrowse
rm -rf "/Volumes/OS X Base System/System/Installation/Packages"
cp -R "/Volumes/OS X Install ESD/Packages" "/Volumes/OS X Base System/System/Installation/"
cp "/Volumes/OS X Install ESD/BaseSystem.chunklist" "/Volumes/OS X Base System/System/Installation/"
cp "/Volumes/OS X Install ESD/BaseSystem.dmg" "/Volumes/OS X Base System/System/Installation/"
hdiutil detach "/Volumes/OS X Base System"
hdiutil detach "/Volumes/OS X Install ESD"
# Pause before converting so hdiutil won't fail with `hdiutil: convert failed - Resource temporarily unavailable`
sleep 2
hdiutil convert -ov "InstallMacOSXMavericks.sparseimage" -format UDZO -o "InstallMacOSXMavericks.dmg"
rm InstallMacOSXMavericks.sparseimage
rm InstallESD.dmg
echo "InstallMacOSXMavericks.dmg successfully created."
if [ "$(uname)" = "Darwin" ]
then
save_create_bootable_installer_script "Create Bootable Installer.command"
open -R "InstallMacOSXMavericks.dmg"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment