Compare commits

..

10 Commits
master ... 3.x

Author SHA1 Message Date
AloneMonkey cf05061131 [bugfix] dlopen parameter problem. 2019-07-24 10:57:24 +08:00
AloneMonkey 81b42b7007 [bugfix] fix for frida 12.5 2019-05-09 19:51:04 +08:00
AloneMonkey e3f6245905 [feature] auto load all frameworks and dylibs. 2019-05-02 23:20:52 +08:00
Alone_Monkey d23ef04f58
change frida to frida-tools 2018-11-10 17:18:48 +08:00
AloneMonkey ba054b9bc1 Exit when something goes wrong 2018-10-11 22:03:30 +08:00
AloneMonkey 89021072c2 fix bug 2018-07-14 19:24:08 +08:00
Alone_Monkey b48276f391
Compatible with previous versions 2018-07-13 16:42:28 +08:00
Alone_Monkey 7a6b65c040
change type tether to usb 2018-07-13 09:27:37 +08:00
AloneMonkey 094ada1051 [fix] search python3 fron env 2018-03-31 10:37:21 +08:00
AloneMonkey 4598333a18 [fix] add python 3.x version 2018-03-19 11:04:02 +08:00
2 changed files with 20 additions and 60 deletions

View File

@ -1,13 +1,13 @@
# frida-ios-dump
Pull a decrypted IPA from a jailbroken device
## Usage
1. Install [frida](http://www.frida.re/) on device
2. `sudo pip install -r requirements.txt --upgrade`
3. Run usbmuxd/iproxy SSH forwarding over USB (Default 2222 -> 22). e.g. `iproxy 2222 22`
4. Run ./dump.py `Display name` or `Bundle identifier`
2. `sudo pip install -r requirements.txt --upgrade` (Python 2.7)
3. `sudo pip3 install -r requirements.txt --upgrade` (Python 3.x)
4. Run usbmuxd/iproxy SSH forwarding over USB (Default 2222 -> 22). e.g. `iproxy 2222 22`
5. Run ./dump.py `Display name` or `Bundle identifier`
For SSH/SCP make sure you have your public key added to the target device's ~/.ssh/authorized_keys file.
@ -40,11 +40,6 @@ Congratulations!!! You've got a decrypted IPA file.
Drag to [MonkeyDev](https://github.com/AloneMonkey/MonkeyDev), Happy hacking!
## Support
Python 2.x and 3.x
### issues
If the following error occurs:

63
dump.py
View File

@ -1,32 +1,27 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author : AloneMonkey
# blog: www.alonemonkey.com
from __future__ import print_function
from __future__ import unicode_literals
import sys
import codecs
import frida
import threading
import os
import shutil
import time
import argparse
import tempfile
import subprocess
import re
import paramiko
from paramiko import SSHClient
from scp import SCPClient
from tqdm import tqdm
import traceback
IS_PY2 = sys.version_info[0] < 3
if IS_PY2:
reload(sys)
sys.setdefaultencoding('utf8')
script_dir = os.path.dirname(os.path.realpath(__file__))
DUMP_JS = os.path.join(script_dir, 'dump.js')
@ -35,7 +30,6 @@ User = 'root'
Password = 'alpine'
Host = 'localhost'
Port = 2222
KeyFileName = None
TEMP_DIR = tempfile.gettempdir()
PAYLOAD_DIR = 'Payload'
@ -77,22 +71,19 @@ def generate_ipa(path, display_name):
print('Generating "{}"'.format(ipa_filename))
try:
app_name = file_dict['app']
for key, value in file_dict.items():
from_dir = os.path.join(path, key)
to_dir = os.path.join(path, app_name, value)
if key != 'app':
try:
os.rename(from_dir, to_dir)
except FileExistsError:
os.remove(to_dir)
os.rename(from_dir, to_dir)
shutil.move(from_dir, to_dir)
target_dir = './' + PAYLOAD_DIR
zip_args = ("7z", "a", "-r", f"{os.getcwd()}/{ipa_filename}.zip", "-w", f"{target_dir}", "-mem=AES256")
zip_args = ('zip', '-qr', os.path.join(os.getcwd(), ipa_filename), target_dir)
subprocess.check_call(zip_args, cwd=TEMP_DIR)
os.rename(f"{os.getcwd()}/{ipa_filename}.zip", f"{os.getcwd()}/{ipa_filename}")
os.system('rmdir /S /Q "{}"'.format(PAYLOAD_PATH))
shutil.rmtree(PAYLOAD_PATH)
except Exception as e:
print(f"{type(e)}: {e}")
print(e)
finished.set()
def on_message(message, data):
@ -100,11 +91,7 @@ def on_message(message, data):
last_sent = [0]
def progress(filename, size, sent):
baseName = os.path.basename(filename)
if IS_PY2 or isinstance(baseName, bytes):
t.desc = baseName.decode("utf-8")
else:
t.desc = baseName
t.desc = os.path.basename(filename).decode("utf-8")
t.total = size
t.update(sent - last_sent[0])
last_sent[0] = 0 if size == sent else sent
@ -123,12 +110,10 @@ def on_message(message, data):
chmod_dir = os.path.join(PAYLOAD_PATH, os.path.basename(dump_path))
chmod_args = ('chmod', '655', chmod_dir)
"""
try:
subprocess.check_call(chmod_args)
except subprocess.CalledProcessError as err:
print(err)
"""
index = origin_path.find('.app/')
file_dict[os.path.basename(dump_path)] = origin_path[index + 5:]
@ -143,12 +128,11 @@ def on_message(message, data):
chmod_dir = os.path.join(PAYLOAD_PATH, os.path.basename(app_path))
chmod_args = ('chmod', '755', chmod_dir)
"""
try:
subprocess.check_call(chmod_args)
except subprocess.CalledProcessError as err:
print(err)
"""
file_dict['app'] = os.path.basename(app_path)
if 'done' in payload:
@ -248,7 +232,7 @@ def create_dir(path):
path = path.strip()
path = path.rstrip('\\')
if os.path.exists(path):
os.system('rmdir /S /Q "{}"'.format(path))
shutil.rmtree(path)
try:
os.makedirs(path)
except os.error as err:
@ -298,13 +282,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(description='frida-ios-dump (by AloneMonkey v2.0)')
parser.add_argument('-l', '--list', dest='list_applications', action='store_true', help='List the installed apps')
parser.add_argument('-o', '--output', dest='output_ipa', help='Specify name of the decrypted IPA')
parser.add_argument('-H', '--host', dest='ssh_host', help='Specify SSH hostname')
parser.add_argument('-p', '--port', dest='ssh_port', help='Specify SSH port')
parser.add_argument('-u', '--user', dest='ssh_user', help='Specify SSH username')
parser.add_argument('-P', '--password', dest='ssh_password', help='Specify SSH password')
parser.add_argument('-K', '--key_filename', dest='ssh_key_filename', help='Specify SSH private key file path')
parser.add_argument('target', nargs='?', help='Bundle identifier or display name of the target app')
args = parser.parse_args()
exit_code = 0
@ -321,22 +299,11 @@ if __name__ == '__main__':
else:
name_or_bundleid = args.target
output_ipa = args.output_ipa
# update ssh args
if args.ssh_host:
Host = args.ssh_host
if args.ssh_port:
Port = int(args.ssh_port)
if args.ssh_user:
User = args.ssh_user
if args.ssh_password:
Password = args.ssh_password
if args.ssh_key_filename:
KeyFileName = args.ssh_key_filename
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(Host, port=Port, username=User, password=Password, key_filename=KeyFileName)
ssh.connect(Host, port=Port, username=User, password=Password)
create_dir(PAYLOAD_PATH)
(session, display_name, bundle_identifier) = open_target_app(device, name_or_bundleid)
@ -347,11 +314,9 @@ if __name__ == '__main__':
start_dump(session, output_ipa)
except paramiko.ssh_exception.NoValidConnectionsError as e:
print(e)
print('Try specifying -H/--hostname and/or -p/--port')
exit_code = 1
except paramiko.AuthenticationException as e:
print(e)
print('Try specifying -u/--username and/or -P/--password')
exit_code = 1
except Exception as e:
print('*** Caught exception: %s: %s' % (e.__class__, e))
@ -362,6 +327,6 @@ if __name__ == '__main__':
ssh.close()
if os.path.exists(PAYLOAD_PATH):
os.system('rmdir /S /Q "{}"'.format(PAYLOAD_PATH))
shutil.rmtree(PAYLOAD_PATH)
sys.exit(exit_code)