Skip to content

Instantly share code, notes, and snippets.

@Wowfunhappy
Last active March 13, 2025 13:47
Show Gist options
  • Save Wowfunhappy/ced9aa23ddaaef7075f6c234f685e01b to your computer and use it in GitHub Desktop.
Save Wowfunhappy/ced9aa23ddaaef7075f6c234f685e01b 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
@waterdragon78
Copy link

Can I use this in a script? How should I credit if so?

@Wowfunhappy
Copy link
Author

Wowfunhappy commented Jan 22, 2025

@waterdragon78 Absolutely!!! You don't need to give credit, but if you'd like to anyway, you can use the information at the top of the script.

My one request is that you do what you can to prevent the board serial number and rom in this script from getting banned by Apple. For example, please don't make multiple parallel requests to Apple's servers in an attempt to achieve faster download speeds. And, please don't use these identifiers for any purpose other than downloading Mavericks.

Thanks for helping make Mavericks accessible to more people!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment