Autarch/modules/android_recon.py

222 lines
7.8 KiB
Python
Raw Permalink Normal View History

"""
Android Device Reconnaissance - Extract device data, accounts, messages, history
"""
DESCRIPTION = "Android device reconnaissance (data extraction, accounts, logs)"
AUTHOR = "AUTARCH"
VERSION = "1.0"
CATEGORY = "offense"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
class AndroidRecon:
"""Interactive menu for Android device reconnaissance."""
def __init__(self):
from core.android_exploit import get_exploit_manager
from core.hardware import get_hardware_manager
self.mgr = get_exploit_manager()
self.hw = get_hardware_manager()
self.serial = None
def _select_device(self):
devices = self.hw.adb_devices()
if not devices:
print(" No ADB devices connected.")
return
if len(devices) == 1:
self.serial = devices[0]['serial']
print(f" Selected: {self.serial}")
return
print("\n Select device:")
for i, d in enumerate(devices, 1):
model = d.get('model', '')
print(f" {i}) {d['serial']} {model}")
try:
choice = int(input(" > ").strip())
if 1 <= choice <= len(devices):
self.serial = devices[choice - 1]['serial']
except (ValueError, EOFError, KeyboardInterrupt):
pass
def _ensure_device(self):
if not self.serial:
self._select_device()
return self.serial is not None
def show_menu(self):
print(f"\n{'='*50}")
print(" Device Reconnaissance")
print(f"{'='*50}")
print(f" Device: {self.serial or '(none)'}")
print()
print(" [1] Full Device Dump")
print(" [2] Installed Accounts")
print(" [3] WiFi Passwords [ROOT]")
print(" [4] Call Logs")
print(" [5] SMS Messages")
print(" [6] Contacts")
print(" [7] Browser History [ROOT]")
print(" [8] Saved Credentials [ROOT]")
print(" [9] Export Full Report")
print(" [s] Select Device")
print(" [0] Back")
print()
def device_dump(self):
if not self._ensure_device():
return
print(" Running full device dump...")
dump = self.mgr.full_device_dump(self.serial)
print(f"\n SELinux: {dump.get('selinux', 'unknown')}")
print(f" Kernel: {dump.get('kernel', 'unknown')}")
print(f" Fingerprint: {dump.get('fingerprint', 'unknown')}")
print(f" Packages: {dump.get('package_count', '?')}")
info = dump.get('device_info', {})
if info:
print(f"\n Device Info:")
for k, v in info.items():
print(f" {k:<20} {v}")
def accounts(self):
if not self._ensure_device():
return
result = self.mgr.get_accounts(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} accounts:")
for a in result['accounts']:
print(f" {a['name']} ({a['type']})")
def wifi_passwords(self):
if not self._ensure_device():
return
print(" Extracting WiFi passwords (requires root)...")
result = self.mgr.get_wifi_passwords(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} saved networks:")
for w in result['passwords']:
print(f" SSID: {w['ssid']}")
print(f" PSK: {w['password']}")
print()
def call_logs(self):
if not self._ensure_device():
return
result = self.mgr.extract_call_logs(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} call log entries:")
print(f" {'Number':<20} {'Type':<12} {'Duration'}")
print(f" {'-'*50}")
for c in result['calls'][:50]:
print(f" {c.get('number','?'):<20} {c.get('type_label','?'):<12} {c.get('duration','?')}s")
def sms_messages(self):
if not self._ensure_device():
return
result = self.mgr.extract_sms(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} SMS messages:")
for m in result['messages'][:30]:
print(f"\n [{m.get('type_label','?')}] {m.get('address','?')}")
body = m.get('body', '')
if len(body) > 100:
body = body[:100] + '...'
print(f" {body}")
def contacts(self):
if not self._ensure_device():
return
result = self.mgr.extract_contacts(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} contacts:")
print(f" {'Name':<25} {'Number'}")
print(f" {'-'*45}")
for c in result['contacts']:
print(f" {c.get('display_name','?'):<25} {c.get('number','?')}")
def browser_history(self):
if not self._ensure_device():
return
print(" Extracting browser history (requires root)...")
result = self.mgr.extract_browser_history(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} history entries:")
for h in result['history'][:30]:
title = h.get('title', '')[:50]
print(f" {title}")
print(f" {h['url']}")
def saved_credentials(self):
if not self._ensure_device():
return
print(" Extracting saved credentials (requires root)...")
result = self.mgr.extract_saved_credentials(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
print(f"\n Found {result['count']} saved credentials:")
for c in result['credentials']:
print(f" URL: {c['url']}")
print(f" User: {c['username']}")
print(f" Pass: {'[encrypted]' if c['password_encrypted'] else '[empty]'}")
print()
def export_report(self):
if not self._ensure_device():
return
print(" Generating full recon report...")
result = self.mgr.export_recon_report(self.serial)
if result['success']:
print(f" Report saved: {result['report_path']}")
print(f" Sections: {', '.join(result['sections'])}")
else:
print(f" Error: {result.get('error', 'Failed')}")
def run_interactive(self):
while True:
self.show_menu()
try:
choice = input(" Select > ").strip().lower()
except (EOFError, KeyboardInterrupt):
break
actions = {
'0': None,
'1': self.device_dump,
'2': self.accounts,
'3': self.wifi_passwords,
'4': self.call_logs,
'5': self.sms_messages,
'6': self.contacts,
'7': self.browser_history,
'8': self.saved_credentials,
'9': self.export_report,
's': self._select_device,
}
if choice == '0':
break
action = actions.get(choice)
if action:
action()
else:
print(" Invalid choice.")
def run():
m = AndroidRecon()
m.run_interactive()