getipa 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- getipa-1.0.1/LICENSE +21 -0
- getipa-1.0.1/PKG-INFO +175 -0
- getipa-1.0.1/README.md +163 -0
- getipa-1.0.1/getipa.egg-info/PKG-INFO +175 -0
- getipa-1.0.1/getipa.egg-info/SOURCES.txt +13 -0
- getipa-1.0.1/getipa.egg-info/dependency_links.txt +1 -0
- getipa-1.0.1/getipa.egg-info/entry_points.txt +2 -0
- getipa-1.0.1/getipa.egg-info/top_level.txt +1 -0
- getipa-1.0.1/getipa_cli/__init__.py +1 -0
- getipa-1.0.1/getipa_cli/__main__.py +3 -0
- getipa-1.0.1/getipa_cli/cli.py +610 -0
- getipa-1.0.1/getipa_cli/npm/package-lock.json +559 -0
- getipa-1.0.1/getipa_cli/npm/package.json +10 -0
- getipa-1.0.1/pyproject.toml +25 -0
- getipa-1.0.1/setup.cfg +4 -0
getipa-1.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rudranetra India Private Limited (https://rudranetra.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
getipa-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getipa
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Pull an app from a jailbroken iPhone over SSH and package it as an IPA (decrypted via bagbak)
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://rudranetra.com/tools
|
|
7
|
+
Project-URL: Source, https://github.com/RansomWhisker/getIPA
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
# getIPA
|
|
14
|
+
|
|
15
|
+
**Pull an app off your own jailbroken iPhone and package it as an `.ipa` — in one command.**
|
|
16
|
+
|
|
17
|
+
`getipa` connects to your device over SSH, lists your recently installed App Store apps (system apps filtered out), and builds a ready-to-use IPA. It automates the manual `ssh` → `cd` → `cp` → `zip` → `scp` routine, and flags the one thing that routine silently gets wrong: FairPlay encryption.
|
|
18
|
+
|
|
19
|
+
> A tool by [**rudranetra.com**](https://rudranetra.com) · more at [rudranetra.com/tools](https://rudranetra.com/tools)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- **Interactive** – just run `getipa`; it asks for username, device IP and password, then shows your apps.
|
|
26
|
+
- **Recent first** – apps sorted by install/update time; system apps (`com.apple.*`) excluded by default.
|
|
27
|
+
- **One-shot or scripted** – flags and environment variables for automation.
|
|
28
|
+
- **Built-in app report** – permissions, entitlements, ATS settings, URL schemes, frameworks and encryption status, for a fresh extraction or any local IPA.
|
|
29
|
+
- **Encrypted *or* decrypted – your choice** – `--decrypted` / `--encrypted` / auto. Decryption is done by [`bagbak`](https://github.com/ChiChou/bagbak), which is **bundled** (installed by `./install.sh`).
|
|
30
|
+
- **Hardened against a hostile device** – treats everything coming back from the phone as untrusted (see [Security](#security)).
|
|
31
|
+
- **Zero dependencies** – Python 3.8+ standard library and your system `ssh`.
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
| Where | What |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Computer | macOS or Linux, Python 3.8+, OpenSSH client (8.4+ for password login) |
|
|
38
|
+
| iPhone | Jailbroken, with OpenSSH running (`tar` is included on standard jailbreaks) |
|
|
39
|
+
| For decrypted IPAs | Node.js + npm on the computer (bundles `bagbak`), and `frida-server` running on the iPhone |
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
**With pipx (recommended):**
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
pipx install git+https://github.com/RansomWhisker/getIPA
|
|
47
|
+
getipa --install-bagbak # one-time: fetches the pinned bagbak (needs Node.js/npm) for decrypted dumps
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`--install-bagbak` runs `npm ci` against the lockfile shipped in the package and installs into `~/.local/share/getipa` — nothing is installed globally. Skip it if you only want encrypted copies.
|
|
51
|
+
|
|
52
|
+
**From a clone:**
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
git clone https://github.com/RansomWhisker/getIPA.git
|
|
56
|
+
cd getIPA
|
|
57
|
+
./install.sh # links getipa into ~/.local/bin AND installs the bundled bagbak
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`install.sh` does the same pinned `npm ci` (see `getipa_cli/npm/package-lock.json`) inside the clone. Skip it with `SKIP_BAGBAK=1 ./install.sh`.
|
|
61
|
+
|
|
62
|
+
**For decrypted IPAs you also need `frida-server` on the iPhone:** install it from your jailbreak's package manager (Sileo / Zebra — add the Frida repo `https://build.frida.re` if it isn't listed), make sure it's running, and keep its version in step with the Frida version `bagbak` bundles. If `getipa --decrypted` fails, this is the first thing to check.
|
|
63
|
+
|
|
64
|
+
> If the bundled install fails, it is almost always Frida's native module not downloading (network reset) or lacking a prebuilt binary for your Node version. Re-run `./install.sh`, or switch to Node 20/22 LTS (`nvm install 22`).
|
|
65
|
+
|
|
66
|
+
Make sure `~/.local/bin` is on your `PATH` (the installer tells you if it isn't).
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### Interactive
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
getipa
|
|
74
|
+
```
|
|
75
|
+
```
|
|
76
|
+
Username [root]: root
|
|
77
|
+
Device IP (just the last number works, e.g. 9 = 192.168.1.9): 9
|
|
78
|
+
[*] Using 192.168.1.9
|
|
79
|
+
Password (blank = use SSH key/prompt):
|
|
80
|
+
|
|
81
|
+
Recently installed apps (newest first):
|
|
82
|
+
1. 2026-11-04 18:22 com.example.app 2.4.1 Example
|
|
83
|
+
2. ...
|
|
84
|
+
Pick a number (or Enter to quit): 1
|
|
85
|
+
[+] Wrote ipas/com.example.app_2.4.1.ipa
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Shorthand: typing just `9` means `192.168.1.9`, and `0.5` means `192.168.0.5` (works for `--host` too). Full IPs and hostnames are used as typed.
|
|
89
|
+
|
|
90
|
+
### Flags
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
getipa --host 192.168.1.9 --list # list only
|
|
94
|
+
getipa --host 192.168.1.9 -b com.example.app # by bundle ID or name substring
|
|
95
|
+
getipa --host 127.0.0.1 --port 2222 --list # USB via `iproxy 2222 22`
|
|
96
|
+
getipa --host 192.168.1.9 --key ~/.ssh/id_ed25519 -n 25
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
| Option | Description |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `--host`, `--port`, `--user` | Connection details (defaults: port `22`, user `root`) |
|
|
102
|
+
| `--key PATH` | SSH private key (recommended over passwords) |
|
|
103
|
+
| `--list` | List apps and exit |
|
|
104
|
+
| `-n N` / `--all` | Show the N most recent apps (default 10) / everything |
|
|
105
|
+
| `-b`, `--bundle-id` | Extract an app by bundle ID or name |
|
|
106
|
+
| `--info` | Print the app report after extracting |
|
|
107
|
+
| `--info-file IPA` | Print the report for a local `.ipa` and exit (no device needed) |
|
|
108
|
+
| `--decrypted` / `--encrypted` | Require a decrypted IPA (via bagbak) / take the raw encrypted copy only. Same as `--mode decrypted\|encrypted`. Default `auto`. |
|
|
109
|
+
| `--include-system` | Include `com.apple.*` apps |
|
|
110
|
+
| `-o DIR` | Output directory (default `./ipas`) |
|
|
111
|
+
| `--frida-host` | Let `bagbak` reach `frida-server` over the network |
|
|
112
|
+
|
|
113
|
+
Environment defaults: `GETIPA_HOST`, `GETIPA_PORT`, `GETIPA_USER`, `SSH_PASSWORD`.
|
|
114
|
+
|
|
115
|
+
### App report
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
getipa --info-file ./ipas/com.example.app_2.4.1.ipa # offline, any IPA
|
|
119
|
+
getipa -b com.example.app --info # extract + report
|
|
120
|
+
```
|
|
121
|
+
```
|
|
122
|
+
== Example (com.example.app) ==
|
|
123
|
+
Version 2.4.1 (build 301)
|
|
124
|
+
Min iOS 15.0
|
|
125
|
+
Encrypted YES (FairPlay, cryptid=1)
|
|
126
|
+
ATS customised: {NSAllowsArbitraryLoads} <-- insecure
|
|
127
|
+
Permissions 2
|
|
128
|
+
NSCameraUsageDescription: Scan codes
|
|
129
|
+
Entitlements 2
|
|
130
|
+
aps-environment: production
|
|
131
|
+
Frameworks 1
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## About encryption
|
|
135
|
+
|
|
136
|
+
Apps installed from the App Store are **FairPlay-encrypted on disk**. A plain file copy gives you an IPA whose main binary can't be disassembled. getIPA lets you choose:
|
|
137
|
+
|
|
138
|
+
| Mode | What you get |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `--decrypted` | A decrypted IPA from the running app, via bagbak. Fails with a clear message if bagbak or frida-server is missing. |
|
|
141
|
+
| `--encrypted` | The raw copy, named `*_encrypted.ipa`. Fast; fine for inspecting resources, `Info.plist`, entitlements. |
|
|
142
|
+
| *auto* (default) | Copies the app; if its binary is encrypted it switches to bagbak, and falls back to the raw copy (with a warning) if that fails. |
|
|
143
|
+
|
|
144
|
+
In interactive mode, `getipa` asks which one you want after you pick an app.
|
|
145
|
+
|
|
146
|
+
## Security
|
|
147
|
+
|
|
148
|
+
`getipa` talks to a device you may not fully trust (jailbroken phones run lots of third-party code), so it validates what comes back:
|
|
149
|
+
|
|
150
|
+
- Usernames/hosts are validated so they can't be parsed as `ssh` options (no `-oProxyCommand=…` tricks).
|
|
151
|
+
- All remote paths are shell-quoted and restricted to the app-container directories.
|
|
152
|
+
- The tar stream from the device is extracted defensively: no path traversal, symlinks/hardlinks/devices skipped, permissions normalised.
|
|
153
|
+
- Device-supplied names are sanitised before being printed or used in filenames or the `bagbak` command line.
|
|
154
|
+
- One SSH connection is opened (control socket in a private `0700` directory) and reused; passwords go to `ssh` via a short-lived `SSH_ASKPASS` helper — never on the command line, never written to disk.
|
|
155
|
+
- No telemetry. At runtime the only network traffic is your SSH connection (and Frida, if you ask for a decrypted dump). The bundled `bagbak` is pinned to an exact version with a lockfile; `install.sh` is the only step that downloads anything.
|
|
156
|
+
|
|
157
|
+
Good hygiene on your side: **change the default `alpine` password**, prefer SSH keys, and only run this on a trusted network. Found a vulnerability? See [SECURITY.md](SECURITY.md).
|
|
158
|
+
|
|
159
|
+
## Responsible use
|
|
160
|
+
|
|
161
|
+
For use **only on devices you own and apps you are authorized to analyze** — your own apps, security research, interoperability, and personal backup, where the law permits. Don't use it to pirate software or circumvent licensing. You are responsible for complying with applicable laws and the terms of the software you handle.
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
| Symptom | Fix |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `UNIX authentication refused` | Wrong password/user. Try `--user mobile` on rootless jailbreaks. |
|
|
168
|
+
| `Too many authentication failures` | Wait a minute / restart OpenSSH on the device; use `--key`. |
|
|
169
|
+
| Decrypting fails | Is `frida-server` running on the iPhone? Is its version compatible with bagbak's Frida? Try `--encrypted` for a raw copy. |
|
|
170
|
+
| No apps listed | App may live outside `/var/containers/Bundle/Application` (e.g. TrollStore apps). |
|
|
171
|
+
| `iTunesMetadata.plist not found` | Normal on many rootless setups; the IPA is still valid. |
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
[MIT](LICENSE) © Rudranetra India Private Limited — [rudranetra.com](https://rudranetra.com)
|
getipa-1.0.1/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# getIPA
|
|
2
|
+
|
|
3
|
+
**Pull an app off your own jailbroken iPhone and package it as an `.ipa` — in one command.**
|
|
4
|
+
|
|
5
|
+
`getipa` connects to your device over SSH, lists your recently installed App Store apps (system apps filtered out), and builds a ready-to-use IPA. It automates the manual `ssh` → `cd` → `cp` → `zip` → `scp` routine, and flags the one thing that routine silently gets wrong: FairPlay encryption.
|
|
6
|
+
|
|
7
|
+
> A tool by [**rudranetra.com**](https://rudranetra.com) · more at [rudranetra.com/tools](https://rudranetra.com/tools)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Interactive** – just run `getipa`; it asks for username, device IP and password, then shows your apps.
|
|
14
|
+
- **Recent first** – apps sorted by install/update time; system apps (`com.apple.*`) excluded by default.
|
|
15
|
+
- **One-shot or scripted** – flags and environment variables for automation.
|
|
16
|
+
- **Built-in app report** – permissions, entitlements, ATS settings, URL schemes, frameworks and encryption status, for a fresh extraction or any local IPA.
|
|
17
|
+
- **Encrypted *or* decrypted – your choice** – `--decrypted` / `--encrypted` / auto. Decryption is done by [`bagbak`](https://github.com/ChiChou/bagbak), which is **bundled** (installed by `./install.sh`).
|
|
18
|
+
- **Hardened against a hostile device** – treats everything coming back from the phone as untrusted (see [Security](#security)).
|
|
19
|
+
- **Zero dependencies** – Python 3.8+ standard library and your system `ssh`.
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
| Where | What |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Computer | macOS or Linux, Python 3.8+, OpenSSH client (8.4+ for password login) |
|
|
26
|
+
| iPhone | Jailbroken, with OpenSSH running (`tar` is included on standard jailbreaks) |
|
|
27
|
+
| For decrypted IPAs | Node.js + npm on the computer (bundles `bagbak`), and `frida-server` running on the iPhone |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
**With pipx (recommended):**
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pipx install git+https://github.com/RansomWhisker/getIPA
|
|
35
|
+
getipa --install-bagbak # one-time: fetches the pinned bagbak (needs Node.js/npm) for decrypted dumps
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`--install-bagbak` runs `npm ci` against the lockfile shipped in the package and installs into `~/.local/share/getipa` — nothing is installed globally. Skip it if you only want encrypted copies.
|
|
39
|
+
|
|
40
|
+
**From a clone:**
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
git clone https://github.com/RansomWhisker/getIPA.git
|
|
44
|
+
cd getIPA
|
|
45
|
+
./install.sh # links getipa into ~/.local/bin AND installs the bundled bagbak
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`install.sh` does the same pinned `npm ci` (see `getipa_cli/npm/package-lock.json`) inside the clone. Skip it with `SKIP_BAGBAK=1 ./install.sh`.
|
|
49
|
+
|
|
50
|
+
**For decrypted IPAs you also need `frida-server` on the iPhone:** install it from your jailbreak's package manager (Sileo / Zebra — add the Frida repo `https://build.frida.re` if it isn't listed), make sure it's running, and keep its version in step with the Frida version `bagbak` bundles. If `getipa --decrypted` fails, this is the first thing to check.
|
|
51
|
+
|
|
52
|
+
> If the bundled install fails, it is almost always Frida's native module not downloading (network reset) or lacking a prebuilt binary for your Node version. Re-run `./install.sh`, or switch to Node 20/22 LTS (`nvm install 22`).
|
|
53
|
+
|
|
54
|
+
Make sure `~/.local/bin` is on your `PATH` (the installer tells you if it isn't).
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### Interactive
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
getipa
|
|
62
|
+
```
|
|
63
|
+
```
|
|
64
|
+
Username [root]: root
|
|
65
|
+
Device IP (just the last number works, e.g. 9 = 192.168.1.9): 9
|
|
66
|
+
[*] Using 192.168.1.9
|
|
67
|
+
Password (blank = use SSH key/prompt):
|
|
68
|
+
|
|
69
|
+
Recently installed apps (newest first):
|
|
70
|
+
1. 2026-11-04 18:22 com.example.app 2.4.1 Example
|
|
71
|
+
2. ...
|
|
72
|
+
Pick a number (or Enter to quit): 1
|
|
73
|
+
[+] Wrote ipas/com.example.app_2.4.1.ipa
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Shorthand: typing just `9` means `192.168.1.9`, and `0.5` means `192.168.0.5` (works for `--host` too). Full IPs and hostnames are used as typed.
|
|
77
|
+
|
|
78
|
+
### Flags
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
getipa --host 192.168.1.9 --list # list only
|
|
82
|
+
getipa --host 192.168.1.9 -b com.example.app # by bundle ID or name substring
|
|
83
|
+
getipa --host 127.0.0.1 --port 2222 --list # USB via `iproxy 2222 22`
|
|
84
|
+
getipa --host 192.168.1.9 --key ~/.ssh/id_ed25519 -n 25
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Option | Description |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `--host`, `--port`, `--user` | Connection details (defaults: port `22`, user `root`) |
|
|
90
|
+
| `--key PATH` | SSH private key (recommended over passwords) |
|
|
91
|
+
| `--list` | List apps and exit |
|
|
92
|
+
| `-n N` / `--all` | Show the N most recent apps (default 10) / everything |
|
|
93
|
+
| `-b`, `--bundle-id` | Extract an app by bundle ID or name |
|
|
94
|
+
| `--info` | Print the app report after extracting |
|
|
95
|
+
| `--info-file IPA` | Print the report for a local `.ipa` and exit (no device needed) |
|
|
96
|
+
| `--decrypted` / `--encrypted` | Require a decrypted IPA (via bagbak) / take the raw encrypted copy only. Same as `--mode decrypted\|encrypted`. Default `auto`. |
|
|
97
|
+
| `--include-system` | Include `com.apple.*` apps |
|
|
98
|
+
| `-o DIR` | Output directory (default `./ipas`) |
|
|
99
|
+
| `--frida-host` | Let `bagbak` reach `frida-server` over the network |
|
|
100
|
+
|
|
101
|
+
Environment defaults: `GETIPA_HOST`, `GETIPA_PORT`, `GETIPA_USER`, `SSH_PASSWORD`.
|
|
102
|
+
|
|
103
|
+
### App report
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
getipa --info-file ./ipas/com.example.app_2.4.1.ipa # offline, any IPA
|
|
107
|
+
getipa -b com.example.app --info # extract + report
|
|
108
|
+
```
|
|
109
|
+
```
|
|
110
|
+
== Example (com.example.app) ==
|
|
111
|
+
Version 2.4.1 (build 301)
|
|
112
|
+
Min iOS 15.0
|
|
113
|
+
Encrypted YES (FairPlay, cryptid=1)
|
|
114
|
+
ATS customised: {NSAllowsArbitraryLoads} <-- insecure
|
|
115
|
+
Permissions 2
|
|
116
|
+
NSCameraUsageDescription: Scan codes
|
|
117
|
+
Entitlements 2
|
|
118
|
+
aps-environment: production
|
|
119
|
+
Frameworks 1
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## About encryption
|
|
123
|
+
|
|
124
|
+
Apps installed from the App Store are **FairPlay-encrypted on disk**. A plain file copy gives you an IPA whose main binary can't be disassembled. getIPA lets you choose:
|
|
125
|
+
|
|
126
|
+
| Mode | What you get |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `--decrypted` | A decrypted IPA from the running app, via bagbak. Fails with a clear message if bagbak or frida-server is missing. |
|
|
129
|
+
| `--encrypted` | The raw copy, named `*_encrypted.ipa`. Fast; fine for inspecting resources, `Info.plist`, entitlements. |
|
|
130
|
+
| *auto* (default) | Copies the app; if its binary is encrypted it switches to bagbak, and falls back to the raw copy (with a warning) if that fails. |
|
|
131
|
+
|
|
132
|
+
In interactive mode, `getipa` asks which one you want after you pick an app.
|
|
133
|
+
|
|
134
|
+
## Security
|
|
135
|
+
|
|
136
|
+
`getipa` talks to a device you may not fully trust (jailbroken phones run lots of third-party code), so it validates what comes back:
|
|
137
|
+
|
|
138
|
+
- Usernames/hosts are validated so they can't be parsed as `ssh` options (no `-oProxyCommand=…` tricks).
|
|
139
|
+
- All remote paths are shell-quoted and restricted to the app-container directories.
|
|
140
|
+
- The tar stream from the device is extracted defensively: no path traversal, symlinks/hardlinks/devices skipped, permissions normalised.
|
|
141
|
+
- Device-supplied names are sanitised before being printed or used in filenames or the `bagbak` command line.
|
|
142
|
+
- One SSH connection is opened (control socket in a private `0700` directory) and reused; passwords go to `ssh` via a short-lived `SSH_ASKPASS` helper — never on the command line, never written to disk.
|
|
143
|
+
- No telemetry. At runtime the only network traffic is your SSH connection (and Frida, if you ask for a decrypted dump). The bundled `bagbak` is pinned to an exact version with a lockfile; `install.sh` is the only step that downloads anything.
|
|
144
|
+
|
|
145
|
+
Good hygiene on your side: **change the default `alpine` password**, prefer SSH keys, and only run this on a trusted network. Found a vulnerability? See [SECURITY.md](SECURITY.md).
|
|
146
|
+
|
|
147
|
+
## Responsible use
|
|
148
|
+
|
|
149
|
+
For use **only on devices you own and apps you are authorized to analyze** — your own apps, security research, interoperability, and personal backup, where the law permits. Don't use it to pirate software or circumvent licensing. You are responsible for complying with applicable laws and the terms of the software you handle.
|
|
150
|
+
|
|
151
|
+
## Troubleshooting
|
|
152
|
+
|
|
153
|
+
| Symptom | Fix |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `UNIX authentication refused` | Wrong password/user. Try `--user mobile` on rootless jailbreaks. |
|
|
156
|
+
| `Too many authentication failures` | Wait a minute / restart OpenSSH on the device; use `--key`. |
|
|
157
|
+
| Decrypting fails | Is `frida-server` running on the iPhone? Is its version compatible with bagbak's Frida? Try `--encrypted` for a raw copy. |
|
|
158
|
+
| No apps listed | App may live outside `/var/containers/Bundle/Application` (e.g. TrollStore apps). |
|
|
159
|
+
| `iTunesMetadata.plist not found` | Normal on many rootless setups; the IPA is still valid. |
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
[MIT](LICENSE) © Rudranetra India Private Limited — [rudranetra.com](https://rudranetra.com)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getipa
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Pull an app from a jailbroken iPhone over SSH and package it as an IPA (decrypted via bagbak)
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://rudranetra.com/tools
|
|
7
|
+
Project-URL: Source, https://github.com/RansomWhisker/getIPA
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
# getIPA
|
|
14
|
+
|
|
15
|
+
**Pull an app off your own jailbroken iPhone and package it as an `.ipa` — in one command.**
|
|
16
|
+
|
|
17
|
+
`getipa` connects to your device over SSH, lists your recently installed App Store apps (system apps filtered out), and builds a ready-to-use IPA. It automates the manual `ssh` → `cd` → `cp` → `zip` → `scp` routine, and flags the one thing that routine silently gets wrong: FairPlay encryption.
|
|
18
|
+
|
|
19
|
+
> A tool by [**rudranetra.com**](https://rudranetra.com) · more at [rudranetra.com/tools](https://rudranetra.com/tools)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- **Interactive** – just run `getipa`; it asks for username, device IP and password, then shows your apps.
|
|
26
|
+
- **Recent first** – apps sorted by install/update time; system apps (`com.apple.*`) excluded by default.
|
|
27
|
+
- **One-shot or scripted** – flags and environment variables for automation.
|
|
28
|
+
- **Built-in app report** – permissions, entitlements, ATS settings, URL schemes, frameworks and encryption status, for a fresh extraction or any local IPA.
|
|
29
|
+
- **Encrypted *or* decrypted – your choice** – `--decrypted` / `--encrypted` / auto. Decryption is done by [`bagbak`](https://github.com/ChiChou/bagbak), which is **bundled** (installed by `./install.sh`).
|
|
30
|
+
- **Hardened against a hostile device** – treats everything coming back from the phone as untrusted (see [Security](#security)).
|
|
31
|
+
- **Zero dependencies** – Python 3.8+ standard library and your system `ssh`.
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
| Where | What |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Computer | macOS or Linux, Python 3.8+, OpenSSH client (8.4+ for password login) |
|
|
38
|
+
| iPhone | Jailbroken, with OpenSSH running (`tar` is included on standard jailbreaks) |
|
|
39
|
+
| For decrypted IPAs | Node.js + npm on the computer (bundles `bagbak`), and `frida-server` running on the iPhone |
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
**With pipx (recommended):**
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
pipx install git+https://github.com/RansomWhisker/getIPA
|
|
47
|
+
getipa --install-bagbak # one-time: fetches the pinned bagbak (needs Node.js/npm) for decrypted dumps
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`--install-bagbak` runs `npm ci` against the lockfile shipped in the package and installs into `~/.local/share/getipa` — nothing is installed globally. Skip it if you only want encrypted copies.
|
|
51
|
+
|
|
52
|
+
**From a clone:**
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
git clone https://github.com/RansomWhisker/getIPA.git
|
|
56
|
+
cd getIPA
|
|
57
|
+
./install.sh # links getipa into ~/.local/bin AND installs the bundled bagbak
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`install.sh` does the same pinned `npm ci` (see `getipa_cli/npm/package-lock.json`) inside the clone. Skip it with `SKIP_BAGBAK=1 ./install.sh`.
|
|
61
|
+
|
|
62
|
+
**For decrypted IPAs you also need `frida-server` on the iPhone:** install it from your jailbreak's package manager (Sileo / Zebra — add the Frida repo `https://build.frida.re` if it isn't listed), make sure it's running, and keep its version in step with the Frida version `bagbak` bundles. If `getipa --decrypted` fails, this is the first thing to check.
|
|
63
|
+
|
|
64
|
+
> If the bundled install fails, it is almost always Frida's native module not downloading (network reset) or lacking a prebuilt binary for your Node version. Re-run `./install.sh`, or switch to Node 20/22 LTS (`nvm install 22`).
|
|
65
|
+
|
|
66
|
+
Make sure `~/.local/bin` is on your `PATH` (the installer tells you if it isn't).
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### Interactive
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
getipa
|
|
74
|
+
```
|
|
75
|
+
```
|
|
76
|
+
Username [root]: root
|
|
77
|
+
Device IP (just the last number works, e.g. 9 = 192.168.1.9): 9
|
|
78
|
+
[*] Using 192.168.1.9
|
|
79
|
+
Password (blank = use SSH key/prompt):
|
|
80
|
+
|
|
81
|
+
Recently installed apps (newest first):
|
|
82
|
+
1. 2026-11-04 18:22 com.example.app 2.4.1 Example
|
|
83
|
+
2. ...
|
|
84
|
+
Pick a number (or Enter to quit): 1
|
|
85
|
+
[+] Wrote ipas/com.example.app_2.4.1.ipa
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Shorthand: typing just `9` means `192.168.1.9`, and `0.5` means `192.168.0.5` (works for `--host` too). Full IPs and hostnames are used as typed.
|
|
89
|
+
|
|
90
|
+
### Flags
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
getipa --host 192.168.1.9 --list # list only
|
|
94
|
+
getipa --host 192.168.1.9 -b com.example.app # by bundle ID or name substring
|
|
95
|
+
getipa --host 127.0.0.1 --port 2222 --list # USB via `iproxy 2222 22`
|
|
96
|
+
getipa --host 192.168.1.9 --key ~/.ssh/id_ed25519 -n 25
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
| Option | Description |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `--host`, `--port`, `--user` | Connection details (defaults: port `22`, user `root`) |
|
|
102
|
+
| `--key PATH` | SSH private key (recommended over passwords) |
|
|
103
|
+
| `--list` | List apps and exit |
|
|
104
|
+
| `-n N` / `--all` | Show the N most recent apps (default 10) / everything |
|
|
105
|
+
| `-b`, `--bundle-id` | Extract an app by bundle ID or name |
|
|
106
|
+
| `--info` | Print the app report after extracting |
|
|
107
|
+
| `--info-file IPA` | Print the report for a local `.ipa` and exit (no device needed) |
|
|
108
|
+
| `--decrypted` / `--encrypted` | Require a decrypted IPA (via bagbak) / take the raw encrypted copy only. Same as `--mode decrypted\|encrypted`. Default `auto`. |
|
|
109
|
+
| `--include-system` | Include `com.apple.*` apps |
|
|
110
|
+
| `-o DIR` | Output directory (default `./ipas`) |
|
|
111
|
+
| `--frida-host` | Let `bagbak` reach `frida-server` over the network |
|
|
112
|
+
|
|
113
|
+
Environment defaults: `GETIPA_HOST`, `GETIPA_PORT`, `GETIPA_USER`, `SSH_PASSWORD`.
|
|
114
|
+
|
|
115
|
+
### App report
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
getipa --info-file ./ipas/com.example.app_2.4.1.ipa # offline, any IPA
|
|
119
|
+
getipa -b com.example.app --info # extract + report
|
|
120
|
+
```
|
|
121
|
+
```
|
|
122
|
+
== Example (com.example.app) ==
|
|
123
|
+
Version 2.4.1 (build 301)
|
|
124
|
+
Min iOS 15.0
|
|
125
|
+
Encrypted YES (FairPlay, cryptid=1)
|
|
126
|
+
ATS customised: {NSAllowsArbitraryLoads} <-- insecure
|
|
127
|
+
Permissions 2
|
|
128
|
+
NSCameraUsageDescription: Scan codes
|
|
129
|
+
Entitlements 2
|
|
130
|
+
aps-environment: production
|
|
131
|
+
Frameworks 1
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## About encryption
|
|
135
|
+
|
|
136
|
+
Apps installed from the App Store are **FairPlay-encrypted on disk**. A plain file copy gives you an IPA whose main binary can't be disassembled. getIPA lets you choose:
|
|
137
|
+
|
|
138
|
+
| Mode | What you get |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `--decrypted` | A decrypted IPA from the running app, via bagbak. Fails with a clear message if bagbak or frida-server is missing. |
|
|
141
|
+
| `--encrypted` | The raw copy, named `*_encrypted.ipa`. Fast; fine for inspecting resources, `Info.plist`, entitlements. |
|
|
142
|
+
| *auto* (default) | Copies the app; if its binary is encrypted it switches to bagbak, and falls back to the raw copy (with a warning) if that fails. |
|
|
143
|
+
|
|
144
|
+
In interactive mode, `getipa` asks which one you want after you pick an app.
|
|
145
|
+
|
|
146
|
+
## Security
|
|
147
|
+
|
|
148
|
+
`getipa` talks to a device you may not fully trust (jailbroken phones run lots of third-party code), so it validates what comes back:
|
|
149
|
+
|
|
150
|
+
- Usernames/hosts are validated so they can't be parsed as `ssh` options (no `-oProxyCommand=…` tricks).
|
|
151
|
+
- All remote paths are shell-quoted and restricted to the app-container directories.
|
|
152
|
+
- The tar stream from the device is extracted defensively: no path traversal, symlinks/hardlinks/devices skipped, permissions normalised.
|
|
153
|
+
- Device-supplied names are sanitised before being printed or used in filenames or the `bagbak` command line.
|
|
154
|
+
- One SSH connection is opened (control socket in a private `0700` directory) and reused; passwords go to `ssh` via a short-lived `SSH_ASKPASS` helper — never on the command line, never written to disk.
|
|
155
|
+
- No telemetry. At runtime the only network traffic is your SSH connection (and Frida, if you ask for a decrypted dump). The bundled `bagbak` is pinned to an exact version with a lockfile; `install.sh` is the only step that downloads anything.
|
|
156
|
+
|
|
157
|
+
Good hygiene on your side: **change the default `alpine` password**, prefer SSH keys, and only run this on a trusted network. Found a vulnerability? See [SECURITY.md](SECURITY.md).
|
|
158
|
+
|
|
159
|
+
## Responsible use
|
|
160
|
+
|
|
161
|
+
For use **only on devices you own and apps you are authorized to analyze** — your own apps, security research, interoperability, and personal backup, where the law permits. Don't use it to pirate software or circumvent licensing. You are responsible for complying with applicable laws and the terms of the software you handle.
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
| Symptom | Fix |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `UNIX authentication refused` | Wrong password/user. Try `--user mobile` on rootless jailbreaks. |
|
|
168
|
+
| `Too many authentication failures` | Wait a minute / restart OpenSSH on the device; use `--key`. |
|
|
169
|
+
| Decrypting fails | Is `frida-server` running on the iPhone? Is its version compatible with bagbak's Frida? Try `--encrypted` for a raw copy. |
|
|
170
|
+
| No apps listed | App may live outside `/var/containers/Bundle/Application` (e.g. TrollStore apps). |
|
|
171
|
+
| `iTunesMetadata.plist not found` | Normal on many rootless setups; the IPA is still valid. |
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
[MIT](LICENSE) © Rudranetra India Private Limited — [rudranetra.com](https://rudranetra.com)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
getipa.egg-info/PKG-INFO
|
|
5
|
+
getipa.egg-info/SOURCES.txt
|
|
6
|
+
getipa.egg-info/dependency_links.txt
|
|
7
|
+
getipa.egg-info/entry_points.txt
|
|
8
|
+
getipa.egg-info/top_level.txt
|
|
9
|
+
getipa_cli/__init__.py
|
|
10
|
+
getipa_cli/__main__.py
|
|
11
|
+
getipa_cli/cli.py
|
|
12
|
+
getipa_cli/npm/package-lock.json
|
|
13
|
+
getipa_cli/npm/package.json
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
getipa_cli
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.1"
|