terminal_worse

A fork of a-Shell 2.3.2 (full) with the worse_query sandbox escape, a native terminal plugin environment, and a small set of UX additions.

Built and tested on iPhone 18 Pro Max, iOS 27.0.1 (24A446), signed with a development provisioning profile. Bundle ID: com.apple.Terminal.

This is a personal security-research project. The repository does NOT contain the decrypted a-Shell IPA (it must be supplied locally) and does NOT contain the signing certificate or provisioning profile.

Features

  • Full a-Shell 2.3.2 app: Python, Perl, TeX, clang/LLVM, SSH, vim, etc.
  • worse_query app-group sandbox escape covering every path documented by the upstream project:
    • /var/containers/Data/System
    • /var/containers/Shared/SystemGroup/*
    • /var/mobile/Containers/Data/Application/*
    • /var/mobile/Containers/Data/InternalDaemon/*
    • /var/mobile/Containers/Data/PluginKitPlugin/*
    • /var/mobile/Containers/Shared/AppGroup/*
    • /var/mobile/Containers/Shared/AppGroup
  • Launch-time blocking progress UI, then auto-mount under ~/Documents/_sandbox/ and run cd _sandbox; ls.
  • App containers are exposed by bundle ID, with Documents/ Library/ tmp/ SystemData/ StoreKit/ and a _data link to the full container root.
  • keep_content is forced off: every launch starts a fresh terminal and does not restore the previous command history.
  • BadShell command set preserved. badshell is renamed to sbxhelp.
  • Built-in neofetch with live device data (OS/build, model, kernel, uptime, resolution, CPU/GPU, memory, disk, battery, thermal, locale, timezone, IP). It uses neofetch's compact Apple ASCII art, not a bash script.
  • Terminal-style app icon (generated by icon/make_icon.py).

Shell commands

sbxhelp                     help / mount overview
sbx_status [-v]             app group, mount state, active handles
sbx_remount                 re-run the full auto-mount
sbx_grant [-c] <path>       consume a sandbox extension
sbx_release <handle|path|all>
sbx_ls <path>
sbx_cat <file>
sbx_cp <src> <dst>
sbx_write [-a] <file> <text...>
sbx_rm [-r] <path>
sbx_hexdump [-n N] <file>
sbx_containers [root]
sbx_id <container>
sbx_sysgroups [filter]
sbx_probe
sbx_paths
bswelcome
neofetch

Native plugin environment

termenv creates an independent prefix at ~/Documents/.terminal and provides a native apt/dpkg compatible package front-end for Terminal-compatible .deb files (scripts or iOS/Darwin arm64 payloads).

termenv init
source ~/Documents/.terminal/etc/profile     # or: termenv on
apt update
apt install <package>
dpkg -i <file.deb>
dpkg -l
mkdeb <name> <version> <payload-dir> [arch]
plugin-run <command> [args...]

Default sources:

deb [trusted=yes] file://$PREFIX/repo ./
deb [trusted=yes] https://repo.procurs.us/ ./
deb [trusted=yes] https://repo.havoc.app/ ./

apt update downloads Packages.xz/.gz/plain indexes. Procursus/Havoc indexes may be unreachable from some networks; the local source still works.

Important limitations

  • Native Mach-O CLI binaries from Procursus/Havoc cannot run in a-Shell. ios_system's isRealCommand deliberately rejects Mach-O files, and a non-jailbroken app cannot execute unsigned external executables. Script plugins (#!/bin/sh, python, perl, lua) and WebAssembly plugins can run; use plugin-run for a clear diagnostic. Native binaries require a jailbreak or a Linux/emulator environment.
  • bash is a sh-compatibility launcher, not GNU bash. bash -c and simple scripts work; bash-specific arrays/[[ do not.
  • The Python package backend (pkgtool) is used when available. The package-install path is still being polished; apt update, package download, extraction, dpkg -l and the local hello sample are the current test targets.
  • apt does not verify GPG signatures; sources are [trusted=yes].

Repository layout

src/TerminalSBX.m        injected dylib: worse_query, UI, commands, neofetch
env/                     native plugin environment commands
icon/                    icon generator + compiled Assets.car
scripts/                 entitlements, signing/build helpers

Building

Requirements: macOS + Xcode 27, the decrypted a-Shell_2.3.2.ipa, a signing identity and provisioning profile with an app group.

  1. Extract Payload/a-Shell.app to work/Terminal.app.
  2. Rename the executable a-Shell to Terminal; set CFBundleIdentifier com.apple.Terminal, CFBundleName/CFBundleDisplayName Terminal, CFBundleExecutable Terminal, and AppGroupIdentifier to a group in the profile.
  3. Build src/TerminalSBX.m as Frameworks/TerminalSBX.dylib (scripts/build_dylib.sh).
  4. Copy env/* into Terminal.app/bin; copy icon/out/Assets.car and the three DisplayIcon*.png files.
  5. Add the sbx_*, sbxhelp, neofetch entries to commandDictionary.plist pointing at @executable_path/Frameworks/TerminalSBX.dylib.
  6. Inject a weak LC_LOAD_DYLIB for @executable_path/Frameworks/TerminalSBX.dylib with LIEF (scripts/inject_dylib.py).
  7. Re-sign every framework with the same team, then the app with scripts/ent.plist and the provisioning profile (scripts/sign_all.sh).
  8. Install with devicectl/Feather/TrollStore as appropriate for the signing profile.

The app in this repository is source-only; the signed IPA is a release asset and is not committed to Git.

Credits

  • a-Shell — Nicolas Holzschuch, BSD-2-Clause.
  • worse_query — Taj C / forcequitOS, GPL-3.0.
  • badshell — wormprojects.
  • pathleak — forcequitOS.
  • neofetch — Dylan Araps (ASCII art/field inspiration), MIT.
  • The a-Shell full IPA was supplied by the operator for local research.

All project-specific additions are released under GPL-3.0 (see LICENSE).