Recently, I unpacked my Apple TV which I haven’t been using for a while and decided to jailbreak it. Sadly, even though I hadn’t used it, it was still plugged in and had auto-updated to the latest tvOS version (tvOS 26.4 at the time of writing), which is not jailbreakable (according to TheAppleWiki).

autoupdate.png

The last jailbreakable firmware is generally considered to be tvOS 26.0.1 (23J362) which is no longer being signed. While I saw some people jailbreaking on tvOS 26.1/26.2 via palera1n, it seemed experimental (and I can’t get back to this version anyway).

This guide details how I managed to get my Apple TV HD (AppleTV5,3) onto tvOS 18.3 and jailbreak it.

Full credit goes to hcbarry and the community for finding this method. The original technique can be found here.

Understanding Firmware Signing and OTA Updates

Before diving into the steps, it’s important to understand why we need this complex injection method instead of just “restoring” the device.

Apple “signs” firmware versions. If a version is signed, Apple’s servers authorize the installation. If a version is unsigned (the window has closed), you cannot install it, unless you have previously saved your specific device’s SHSH blobs (you can see that as tickets) for that version.

At the time of writing, tvOS 18.3 is still being signed, which means we can technically install it. However, Apple usually releases full IPSW restore files for major updates. For minor updates like 18.3, they often distribute them only as Over-The-Air (OTA) updates. signed.png

Even if the firmware is signed, you cannot use iTunes/Finder to “Restore” an IPSW that doesn’t exist publicly. Furthermore, the Apple TV’s OTA update mechanism is designed to show only the latest version available in the catalog. If Apple is currently signing 18.4, the OTA catalog will hide 18.3, even if 18.3 is still technically valid on the server.

This guide bypasses the catalog’s version restriction by injecting tvOS 18.3 OTA metadata directly into mobileassetd, allowing the device to download and install the specific signed version through the normal OTA pipeline.

Installing tvOS 18.3 on Apple TV HD via OTA catalog injection

Supported Device:

DeviceModelStarting version
Apple TV HDAppleTV5,3tvOS 13.4.8 (17M61)

Thanks to the community members in #tvos-jailbreaks on the r/jailbreak Discord for sharing the research and techniques that made this possible.

Not on tvOS 13.4.8?

This guide requires tvOS 13.4.8 (17M61) (which is the last major version that is still being signed) as the starting point. signed-2.png If your device is on a different version, restore to 13.4.8 first idevicerestore.

You can download the IPSW here:

wget "https://updates.cdn-apple.com/2020SummerSeed/fullrestores/061-92142/5EB0BEFA-C8BC-4FF4-949A-D37D8776EEF1/AppleTV5,3_13.4.8_17M61_Restore.ipsw"
brew install libirecovery
git clone https://github.com/libimobiledevice/idevicerestore.git
git checkout cc9c68e
./autogen.sh
make
./idevicerestore -e /AppleTV5,3_13.4.8_17M61_Restore.ipsw
Restore logs
idevicerestore 1.0.0-146-gcc9c68e
Found device in Normal mode
ECID: 1804032978682918
Identified device as j42dap, AppleTV5,3
Extracting BuildManifest from IPSW
Product Version: 13.4.8
Product Build: 17M61 Major: 17
Device supports Image4: true
Variant: Customer Erase Install (IPSW)
This restore will erase all device data.
################################ [ WARNING ] #################################
# You are about to perform an *ERASE* restore. ALL DATA on the target device #
# will be IRREVERSIBLY DESTROYED. If you want to update your device without  #
# erasing the user data, hit CTRL+C now and restart without -e or --erase    #
# command line switch.                                                       #
# If you want to continue with the ERASE, please type YES and press ENTER.   #
##############################################################################
> YES
Checking IPSW for required components...
All required components found in IPSW
Extracting filesystem from IPSW: 038-50861-064.dmg
[==================================================] 100.0%
Getting ApNonce in normal mode... 6f 77 f6 5e 45 c3 e5 a9 8d a1 5f bd f4 e2 4f eb e3 e6 c0 fe
Trying to fetch new SHSH blob
Getting SepNonce in normal mode... d4 a5 5e 0f 59 3e 25 dc 55 d5 57 72 95 b9 23 df 11 d9 96 0d
Request URL set to https://gs.apple.com/TSS/controller?action=2
Sending TSS request attempt 1... response successfully received
Received SHSH blobs
Entering recovery mode...
INFO: device serial number is DY3QM87GG9RM
Extracting iBEC.j42d.RELEASE.im4p (Firmware/dfu/iBEC.j42d.RELEASE.im4p)...
Personalizing IMG4 component iBEC...
Sending iBEC (747270 bytes)...
Recovery Mode Environment:
iBoot build-version=iBoot-5540.140.12
iBoot build-style=RELEASE
Sending RestoreLogo...
Extracting applelogo~appletv.im4p (Firmware/all_flash/applelogo~appletv.im4p)...
Personalizing IMG4 component RestoreLogo...
Sending RestoreLogo (9926 bytes)...
Extracting 038-50782-064.dmg.trustcache (Firmware/038-50782-064.dmg.trustcache)...
Personalizing IMG4 component RestoreTrustCache...
Sending RestoreTrustCache (8659 bytes)...
ramdisk-size=0x20000000
Extracting 038-50782-064.dmg (038-50782-064.dmg)...
Personalizing IMG4 component RestoreRamDisk...
Sending RestoreRamDisk (72815683 bytes)...
Extracting DeviceTree.j42dap.im4p (Firmware/all_flash/DeviceTree.j42dap.im4p)...
Personalizing IMG4 component RestoreDeviceTree...
Sending RestoreDeviceTree (98025 bytes)...
Extracting sep-firmware.j42d.RELEASE.im4p (Firmware/all_flash/sep-firmware.j42d.RELEASE.im4p)...
Personalizing IMG4 component RestoreSEP...
Sending RestoreSEP (1619201 bytes)...
Extracting kernelcache.release.j42d (kernelcache.release.j42d)...
Personalizing IMG4 component RestoreKernelCache...
Sending RestoreKernelCache (13546084 bytes)...
Waiting for device to enter restore mode...
About to restore device...
Connecting now...
Connected to com.apple.mobile.restored, version 15
Device 9045f3838ad2f180a3b91f073f05e01328057bff has successfully entered restore mode
Hardware Information:
BoardID: 52
ChipID: 28672
UniqueChipID: 1804032978682918
ProductionMode: true
Starting Reverse Proxy
ReverseProxy[Ctrl]: (status=1) Ready
Checkpoint 1621 complete with code 0
... [logs truncated for brevity] ...
Status: Restore Finished
ReverseProxy[Conn]: (status=6) Disconnected (out: 6113 / in: 8491)
...
Cleaning up...
DONE

Prerequisites

Apple TV HD (AppleTV5,3)

Step 1: Disconnect Apple TV from network

Turn off Wi-Fi or unplug the Ethernet cable on the Apple TV before proceeding. This prevents checkra1n from downloading and installing bootstrap components onto the root filesystem after jailbreak.

Step 2: Jailbreak (CLI mode, no bootstrap)

Apple TV HD: Connect via USB-C cable. To put in DFU: Press and hold the Menu and Play buttons until the LED starts flashing rapidly (10 seconds) then release both buttons.

Then run checkra1n in CLI mode on your Mac. This gives you SSH access without touching the root filesystem, critical for passing OTA pre-flight verification.

cd /Applications/checkra1n.app/Contents/MacOS
./checkra1n -c
Jailbreak logs
#
# Checkra1n beta 0.12.4
#
# Proudly written in nano
# (c) 2019-2021 Kim Jong Cracks
#
#========  Made by  =======
# argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV
# never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza
#======== Thanks to =======
# haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini
# Cellebrite (ih8sn0w, cjori, ronyrus et al.)
#==========================

 - [*]: Waiting for DFU devices
 - [*]: Exploiting
 - [*]: Checking if device is ready
 - [*]: Setting up the exploit (this is the heap spray)
 - [*]: Right before trigger (this is the real bug setup)
 - [*]: Entered download mode
 - [*]: Booting...
 - [*]: Uploading bootstrap...
 - [*]: All Done

Do not open the checkra1n loader app or install anything onto the Apple TV. A clean rootfs is required for pre.bom verification to pass.

Step 3: Set up USB SSH tunnel

iproxy 2222 44

Step 4: Install Frida

Extract the .deb file and transfer only the required binaries to /var (data partition, which is not scanned by pre.bom):

# Extract the deb
ar x frida_16.6.1_appletvos-arm64.deb
tar -xf data.tar.*
tree ./usr
./usr
├── lib
│   └── frida
│       └── frida-agent.dylib
└── sbin
    └── frida-server
# Transfer binaries
cat ./usr/sbin/frida-server | ssh -p 2222 root@localhost "cat > /var/frida-server"
cat ./usr/lib/frida/frida-agent.dylib | ssh -p 2222 root@localhost "cat > /var/frida-agent.dylib"

The root password is alpine by default.

SSH in and set up the agent:

ssh -p 2222 root@localhost

mkdir -p /usr/lib/frida
cp /var/frida-agent.dylib /usr/lib/frida/frida-agent.dylib
chmod 755 /usr/lib/frida/frida-agent.dylib
chmod 755 /var/frida-server

/var/frida-server &

Step 5: Attach Frida to mobileassetd and inject hook

From your Mac:

frida -U -n mobileassetd

Paste the hook for Apple TV HD (AppleTV5,3) into the Frida REPL. It intercepts the asset catalog response and replaces the tvOS entry for tvOS 13.4.8 with tvOS 18.3 OTA metadata, thus tricking the Apple TV into downloading and installing the 18.3 OTA package through the normal update process.

const cls = ObjC.classes.DownloadManager;
Interceptor.attach(
  cls["- massageXmlAndPersist:descriptor:assets:transformations:to:postedDate:receiptResults:assetSetId:"].implementation,
  {
    onEnter(args) {
      try {
        const assets = new ObjC.Object(args[4]);
        const count = assets.count();
        console.log("[CALLED] count: " + count);

        if (count <= 1) { console.log("[SKIP]"); return; }

        let target = null;
        for (let i = 0; i < count; i++) {
          const a = assets.objectAtIndex_(i);
          try {
            const p = a.objectForKey_("PrerequisiteBuild");
            if (p && p.toString() === "17M61") { target = a; break; }
          } catch(e) {}
        }

        if (!target) { console.log("[NO 17M61 found, skip]"); return; }

        const fake = ObjC.classes.NSMutableDictionary.dictionaryWithDictionary_(target);
        const NS = ObjC.classes.NSString;
        const set = (k, v) => fake.setObject_forKey_(NS.stringWithString_(v), NS.stringWithString_(k));

        set("__BaseURL",           "https://updates.cdn-apple.com/2025WinterFCS/patches/072-52345/25CD8DC5-A526-442E-AEC1-DFDB08F953CA/");
        set("__RelativePath",      "com_apple_MobileAsset_SoftwareUpdate/fb3c5639de7e6d4fb1eccba24d0c2e9a5bd22f7b.zip");
        set("_Measurement",        "+zxWOd5+bU+x7MuiTQwumlvSL3s=");
        set("_Measurement-SHA256", "gWrlgM0h8IhEMngUu7YqFZlFDYHs8TU5I4Sxh0vu+2c=");
        set("OSVersion",           "18.3");
        set("Build",               "22K557");
        fake.setObject_forKey_(
          ObjC.classes.NSNumber.numberWithLongLong_(3232557710),
          NS.stringWithString_("_DownloadSize")
        );

        assets.removeAllObjects();
        assets.addObject_(fake);
        console.log("[REPLACED] → 18.3");
      } catch(e) { console.log("err: " + e); }
    }
  }
);
console.log("Hooked");

Wait for Hooked to appear in the console.

Step 6: Clean up jailbreak traces from system partition

Required for pre.bom verification to pass. The Frida hook remains active since frida-server is running from /var.

ssh -p 2222 root@localhost

rm -rf /usr/lib/frida
rm -rf /System/Library/TVSystemMenuModules/checkra1n.bundle/

Step 7: Trigger the OTA update

Reconnect Apple TV to Wi-Fi, then navigate to:

Settings → System → Software Updates → Update Software

The Frida hook intercepts the asset catalog response and injects the tvOS 18.3 OTA package metadata. Download and installation proceed through the normal OTA pipeline.

Frida logs
     ____
    / _  |   Frida 16.7.0 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to iOS Device (id=9045f3838ad2f180a3b91f073f05e01328057bff)

[iOS Device::mobileassetd ]-> [PASTE SCRIPT HERE]
Hooked
[iOS Device::mobileassetd ]-> [CALLED] count: 62
[REPLACED] → 18.3

update-available.png

Once that’s done, the Apple TV will reboot and start the update process, and then reboot again into the new tvOS 18.3 system. done.png

Installing palera1n for Apple TV

Now that we are on tvOS 18.3, we can jailbreak using palera1n.

Source: https://ios.cfw.guide/installing-palera1n-atv-18-2/

  1. Plug your USB-C cable into the USB-C diagnostic port on the back of the device and the other end into your computer.
  2. Run palera1n -cf
  3. When ready, press Enter and follow the on-screen instructions to enter DFU mode.
  4. Once your device is done creating the fakeFS, run palera1n -f

Note for Apple TV HD: You might encounter an issue where the device gets stuck midway through this process in pongoOS. To work around this:

  • In the terminal window, press Control + C on your keyboard.
  • Rerun the command that you just ran.
Jailbreak logs
(base) noham@propulsion ~ % palera1n -cf
#
# palera1n: v2.2.1
#
# ========  Made by  =======
# Made by: Nick Chan, Ploosh, Khcrysalis, Mineek, staturnz, kok3shidoll, HAHALOSAH
# ======== Thanks to =======
# Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),
# checkra1n team (Siguza, axi0mx, littlelailo et al.),
# Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)
# ==========================

 - [04/08/26 20:23:58] <Info>: Waiting for devices
 - [04/08/26 20:23:58] <Info>: Entering recovery mode
 - [04/08/26 20:24:13] <Info>: Press Enter when ready for DFU mode

Hold menu + play button (0)
 - [04/08/26 20:24:58] <Warning>: Whoops, device did not enter DFU mode
 - [04/08/26 20:24:58] <Info>: Waiting for device to reconnect...
 - [04/08/26 20:25:00] <Info>: About to execute checkra1n
... [logs truncated] ...
 - [04/08/26 20:26:36] <Info>: Found PongoOS USB Device
 - [04/08/26 20:26:36] <Info>: Booting Kernel...
 - [04/08/26 20:26:36] <Info>: Please wait up to 10 minutes for the fakefs to be created.
 - [04/08/26 20:26:36] <Info>: Once the device reboots into recovery mode, run again without the -c (Create FakeFS) option to jailbreak.
(base) noham@propulsion ~ % palera1n -f
#
# palera1n: v2.2.1
#
# ========  Made by  =======
# Made by: Nick Chan, Ploosh, Khcrysalis, Mineek, staturnz, kok3shidoll, HAHALOSAH
# ======== Thanks to =======
# Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),
# checkra1n team (Siguza, axi0mx, littlelailo et al.),
# Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)
# ==========================

 - [04/08/26 20:32:24] <Info>: Waiting for devices
 - [04/08/26 20:32:26] <Info>: Press Enter when ready for DFU mode

Hold menu + play button (0)
 - [04/08/26 20:32:40] <Warning>: Whoops, device did not enter DFU mode
 - [04/08/26 20:32:40] <Info>: Waiting for device to reconnect...
 - [04/08/26 20:32:42] <Info>: About to execute checkra1n
... [logs truncated] ...
 - [04/08/26 20:33:14] <Info>: Found PongoOS USB Device
 - [04/08/26 20:33:14] <Info>: Booting Kernel...

pongoOS.jpeg

final.png

Installing PurePKG and Tweaks

Once that’s done you can install PurePKG using palera1n. Using PurePKG, you can install any .deb file on your Apple TV, including jailbreak tweaks.

For example, TrollDecrypt is a tweak that decrypts and dumps decrypted versions of apps installed on the Apple TV, which is useful for security research and reverse engineering.

trolldecrypt.png

To get started with my Apple TV hacking journey, I dumped a popular streaming app and activated the Pro version by creating a Theos tweak that hooks the license check and bypasses it.

Dumping a streaming app

player.png