Created
October 31, 2023 22:35
-
-
Save YungRaj/d12a5178f66483f104a1caf83973008a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, os, re, subprocess, select, plistlib, frida | |
def print_usage(): | |
print('python3 install_ios_app.py app_ids') | |
argv = sys.argv; | |
argc = len(sys.argv) | |
if argc < 2: | |
print_usage(); | |
env = os.environ.copy() | |
env['IPATOOL_EMAIL'] = '' | |
env['IPATOOL_PASSWORD'] = '' | |
env['IPATOOL_2FA_CODE'] = '' | |
command = ['ipatool','auth', 'login'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, env=env) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
for i in range(1, argc): | |
app_id = argv[i] | |
command = ['ipatool','search', app_id] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, env=env) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
bundle_id = None | |
print('Installing app with app id %s' %(app_id)) | |
for line in stream: | |
regex = re.compile(r'\b(?![A-Z])[\w-]+(?:\.[\w-]+)+\b') | |
result = regex.findall(line) | |
if result: | |
result = result[0].strip().split(' ') | |
if result is not None and len(result) != 0: | |
bundle_id = result[0] | |
else: | |
continue | |
if bundle_id is None: | |
print_usage() | |
print(bundle_id) | |
command = ['ipatool','purchase', '--bundle-identifier', bundle_id, '--device-family', 'iPhone'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, env=env) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
command = ['ipatool','download', '--bundle-identifier', bundle_id, '--device-family', 'iPhone'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, env=env) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
ipa_file = None | |
for line in stream: | |
if bundle_id in line and '.ipa' in line: | |
ipa_file = line[line.find(bundle_id):line.find('.ipa') + len('.ipa')] | |
if ipa_file is None: | |
print_usage() | |
print('ipa = %s' % (ipa_file)) | |
command = ['ideviceinstaller','-i', ipa_file] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
if error is not None: | |
exit(-1) | |
num_failures = 0 | |
complete = False | |
while(not complete and num_failures < 10): | |
env = os.environ.copy() | |
env['SSH_PORT'] = '2222' | |
env['SSH_USERNAME'] = 'root' | |
env['SSH_PASSWORD'] = 'ilhan123' | |
command = ['bagbak','-U', bundle_id] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) | |
stdout = [] | |
stderr = [] | |
while True: | |
reads = [process.stdout.fileno(), process.stderr.fileno()] | |
ret = select.select(reads, [], []) | |
for fd in ret[0]: | |
if fd == process.stdout.fileno(): | |
read = process.stdout.readline() | |
sys.stdout.write(read.decode("utf-8") ) | |
stdout.append(read.decode("utf-8") ) | |
if fd == process.stderr.fileno(): | |
read = process.stderr.readline() | |
sys.stderr.write(read.decode("utf-8") ) | |
stderr.append(read.decode("utf-8") ) | |
if process.poll() != None: | |
break | |
process.wait() | |
output, error = process.communicate() | |
output = "".join(stdout) | |
error = "".join(stderr) | |
stream = output.split('\n') | |
print(output) | |
print(error) | |
if 'Saved to' in output: | |
complete = True | |
else: | |
complete = False | |
num_failures += 1 | |
if(num_failures >= 10): | |
continue | |
localized_app_ipa = None | |
for line in stream: | |
if '.ipa' in line and 'Saved to': | |
localized_app_ipa = line.split(' ')[2] | |
break | |
if localized_app_ipa is None: | |
print_usage() | |
decrypt_folder = './dump/' + bundle_id | |
payload_folder = decrypt_folder + '/Payload' | |
command = ['unzip', localized_app_ipa, '-d', decrypt_folder] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
command = ['ls', '-1', payload_folder] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
for line in stream: | |
if '.app' in line: | |
localized_name = line[:line.find('.app')] | |
break | |
app_bundle = payload_folder + '/' + localized_name + '.app' | |
app_binary = app_bundle + '/' + localized_name | |
app_frameworks = app_bundle + '/' + 'Frameworks' | |
command = ['codesign', '-fs', '-', '--preserve-metadata=entitlements', app_binary, '--deep'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
command = ['ls', '-1', app_frameworks] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
stream = output.split('\n') | |
for line in stream: | |
to_sign = app_frameworks + '/' + line | |
command = ['codesign', '-fs', '-', '--preserve-metadata=entitlements', to_sign, '--deep'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
new_ipa = decrypt_folder + '/' + localized_name + '.ipa' | |
command = ['ditto', '-c', '-k', '--sequesterRsrc', '--keepParent', payload_folder, new_ipa] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') | |
command = ['rm', './*.ipa'] | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None) | |
output, error = process.communicate() | |
output = output.decode('utf-8') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment