Autarch/web/routes/iphone_exploit.py

400 lines
12 KiB
Python
Raw Permalink Normal View History

"""iPhone Exploitation routes - Local USB device access via libimobiledevice."""
import os
from flask import Blueprint, render_template, request, jsonify
from web.auth import login_required
iphone_exploit_bp = Blueprint('iphone_exploit', __name__, url_prefix='/iphone-exploit')
def _get_mgr():
from core.iphone_exploit import get_iphone_manager
return get_iphone_manager()
def _get_udid():
data = request.get_json(silent=True) or {}
udid = data.get('udid', '').strip()
if not udid:
return None, jsonify({'error': 'No UDID provided'})
return udid, None
@iphone_exploit_bp.route('/')
@login_required
def index():
mgr = _get_mgr()
status = mgr.get_status()
return render_template('iphone_exploit.html', status=status)
# ── Device Management ────────────────────────────────────────────
@iphone_exploit_bp.route('/devices', methods=['POST'])
@login_required
def list_devices():
return jsonify({'devices': _get_mgr().list_devices()})
@iphone_exploit_bp.route('/device-info', methods=['POST'])
@login_required
def device_info():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().device_info(udid))
@iphone_exploit_bp.route('/fingerprint', methods=['POST'])
@login_required
def fingerprint():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().full_fingerprint(udid))
@iphone_exploit_bp.route('/pair', methods=['POST'])
@login_required
def pair():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().pair_device(udid))
@iphone_exploit_bp.route('/unpair', methods=['POST'])
@login_required
def unpair():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().unpair_device(udid))
@iphone_exploit_bp.route('/validate-pair', methods=['POST'])
@login_required
def validate_pair():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().validate_pair(udid))
@iphone_exploit_bp.route('/get-name', methods=['POST'])
@login_required
def get_name():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().get_name(udid))
@iphone_exploit_bp.route('/set-name', methods=['POST'])
@login_required
def set_name():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
name = data.get('name', '').strip()
if not name:
return jsonify({'error': 'No name provided'})
return jsonify(_get_mgr().set_name(udid, name))
@iphone_exploit_bp.route('/restart', methods=['POST'])
@login_required
def restart():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().restart_device(udid))
@iphone_exploit_bp.route('/shutdown', methods=['POST'])
@login_required
def shutdown():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().shutdown_device(udid))
@iphone_exploit_bp.route('/sleep', methods=['POST'])
@login_required
def sleep_dev():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().sleep_device(udid))
# ── Capture ──────────────────────────────────────────────────────
@iphone_exploit_bp.route('/screenshot', methods=['POST'])
@login_required
def screenshot():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().screenshot(udid))
@iphone_exploit_bp.route('/syslog', methods=['POST'])
@login_required
def syslog():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
duration = int(data.get('duration', 5))
return jsonify(_get_mgr().syslog_dump(udid, duration=duration))
@iphone_exploit_bp.route('/syslog-grep', methods=['POST'])
@login_required
def syslog_grep():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
pattern = data.get('pattern', 'password|token|key|secret')
duration = int(data.get('duration', 5))
return jsonify(_get_mgr().syslog_grep(udid, pattern, duration=duration))
@iphone_exploit_bp.route('/crash-reports', methods=['POST'])
@login_required
def crash_reports():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().crash_reports(udid))
# ── Apps ─────────────────────────────────────────────────────────
@iphone_exploit_bp.route('/apps/list', methods=['POST'])
@login_required
def list_apps():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
app_type = data.get('type', 'user')
return jsonify(_get_mgr().list_apps(udid, app_type=app_type))
@iphone_exploit_bp.route('/apps/install', methods=['POST'])
@login_required
def install_app():
udid = request.form.get('udid', '').strip()
if not udid:
return jsonify({'error': 'No UDID provided'})
f = request.files.get('file')
if not f:
return jsonify({'error': 'No file uploaded'})
from core.paths import get_uploads_dir
upload_path = str(get_uploads_dir() / f.filename)
f.save(upload_path)
return jsonify(_get_mgr().install_app(udid, upload_path))
@iphone_exploit_bp.route('/apps/uninstall', methods=['POST'])
@login_required
def uninstall_app():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
bundle_id = data.get('bundle_id', '').strip()
if not bundle_id:
return jsonify({'error': 'No bundle_id provided'})
return jsonify(_get_mgr().uninstall_app(udid, bundle_id))
# ── Backup & Extraction ─────────────────────────────────────────
@iphone_exploit_bp.route('/backup/create', methods=['POST'])
@login_required
def backup_create():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
encrypted = data.get('encrypted', False)
password = data.get('password', '')
return jsonify(_get_mgr().create_backup(udid, encrypted=encrypted, password=password))
@iphone_exploit_bp.route('/backup/list', methods=['POST'])
@login_required
def backup_list():
return jsonify(_get_mgr().list_backups())
@iphone_exploit_bp.route('/backup/sms', methods=['POST'])
@login_required
def backup_sms():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
if not backup_path:
return jsonify({'error': 'No backup_path provided'})
return jsonify(_get_mgr().extract_backup_sms(backup_path))
@iphone_exploit_bp.route('/backup/contacts', methods=['POST'])
@login_required
def backup_contacts():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
if not backup_path:
return jsonify({'error': 'No backup_path provided'})
return jsonify(_get_mgr().extract_backup_contacts(backup_path))
@iphone_exploit_bp.route('/backup/calls', methods=['POST'])
@login_required
def backup_calls():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
if not backup_path:
return jsonify({'error': 'No backup_path provided'})
return jsonify(_get_mgr().extract_backup_call_log(backup_path))
@iphone_exploit_bp.route('/backup/notes', methods=['POST'])
@login_required
def backup_notes():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
if not backup_path:
return jsonify({'error': 'No backup_path provided'})
return jsonify(_get_mgr().extract_backup_notes(backup_path))
@iphone_exploit_bp.route('/backup/files', methods=['POST'])
@login_required
def backup_files():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
if not backup_path:
return jsonify({'error': 'No backup_path provided'})
domain = data.get('domain', '')
path_filter = data.get('path_filter', '')
return jsonify(_get_mgr().list_backup_files(backup_path, domain=domain, path_filter=path_filter))
@iphone_exploit_bp.route('/backup/extract-file', methods=['POST'])
@login_required
def backup_extract_file():
data = request.get_json(silent=True) or {}
backup_path = data.get('backup_path', '').strip()
file_hash = data.get('file_hash', '').strip()
if not backup_path or not file_hash:
return jsonify({'error': 'Missing backup_path or file_hash'})
output_name = data.get('output_name') or None
return jsonify(_get_mgr().extract_backup_file(backup_path, file_hash, output_name=output_name))
# ── Filesystem ───────────────────────────────────────────────────
@iphone_exploit_bp.route('/fs/mount', methods=['POST'])
@login_required
def fs_mount():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().mount_filesystem(udid))
@iphone_exploit_bp.route('/fs/mount-app', methods=['POST'])
@login_required
def fs_mount_app():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
bundle_id = data.get('bundle_id', '').strip()
if not bundle_id:
return jsonify({'error': 'No bundle_id provided'})
return jsonify(_get_mgr().mount_app_documents(udid, bundle_id))
@iphone_exploit_bp.route('/fs/unmount', methods=['POST'])
@login_required
def fs_unmount():
data = request.get_json(silent=True) or {}
mountpoint = data.get('mountpoint', '').strip()
if not mountpoint:
return jsonify({'error': 'No mountpoint provided'})
_get_mgr().unmount_filesystem(mountpoint)
return jsonify({'success': True, 'output': 'Unmounted'})
# ── Profiles ─────────────────────────────────────────────────────
@iphone_exploit_bp.route('/profiles/list', methods=['POST'])
@login_required
def profiles_list():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().list_profiles(udid))
@iphone_exploit_bp.route('/profiles/install', methods=['POST'])
@login_required
def profiles_install():
udid = request.form.get('udid', '').strip()
if not udid:
return jsonify({'error': 'No UDID provided'})
f = request.files.get('file')
if not f:
return jsonify({'error': 'No file uploaded'})
from core.paths import get_uploads_dir
upload_path = str(get_uploads_dir() / f.filename)
f.save(upload_path)
return jsonify(_get_mgr().install_profile(udid, upload_path))
@iphone_exploit_bp.route('/profiles/remove', methods=['POST'])
@login_required
def profiles_remove():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
profile_id = data.get('profile_id', '').strip()
if not profile_id:
return jsonify({'error': 'No profile_id provided'})
return jsonify(_get_mgr().remove_profile(udid, profile_id))
# ── Network ──────────────────────────────────────────────────────
@iphone_exploit_bp.route('/port-forward', methods=['POST'])
@login_required
def port_forward():
udid, err = _get_udid()
if err:
return err
data = request.get_json(silent=True) or {}
local_port = data.get('local_port')
device_port = data.get('device_port')
if not local_port or not device_port:
return jsonify({'error': 'Missing local_port or device_port'})
return jsonify(_get_mgr().port_forward(udid, int(local_port), int(device_port)))
# ── Recon ────────────────────────────────────────────────────────
@iphone_exploit_bp.route('/recon/export', methods=['POST'])
@login_required
def recon_export():
udid, err = _get_udid()
if err:
return err
return jsonify(_get_mgr().export_recon_report(udid))