Compare commits

...

3 Commits

Author SHA1 Message Date
Nikolaos Tosis 2614d94c89
Merge 75f956de0b into 04b78a4d60 2024-03-06 08:24:17 -06:00
github-actions[bot] 04b78a4d60
Add new iOS versions and build numbers (#468)
Co-authored-by: DonnchaC <DonnchaC@users.noreply.github.com>
2024-03-06 10:16:08 +01:00
Nikolaos Tosis 75f956de0b
Create ios_GUI.py
initial version
2022-09-18 16:58:25 +02:00
2 changed files with 205 additions and 0 deletions

193
gui/ios_GUI.py Normal file
View File

@ -0,0 +1,193 @@
from tkinter import *
from tkinter.ttk import Treeview,Combobox,Style
from tkinter import filedialog,messagebox
import pip._internal as pip
import platform
import sys,os
import logging,requests
from rich.logging import RichHandler
#mvt module imports, if not exit install it
try:
from mvt.ios.decrypt import DecryptBackup
from mvt.ios.modules.backup import BACKUP_MODULES
from mvt.ios.modules.fs import FS_MODULES
from mvt.ios.modules.mixed import MIXED_MODULES
from mvt.common.module import run_module,save_timeline
from mvt.common.indicators import Indicators, IndicatorsFileBadFormat
except ImportError:
pip.main(['install', 'mvt'])
from mvt.ios.decrypt import DecryptBackup
from mvt.ios.modules.backup import BACKUP_MODULES
from mvt.ios.modules.fs import FS_MODULES
from mvt.ios.modules.mixed import MIXED_MODULES
from mvt.common.indicators import Indicators, IndicatorsFileBadFormat
from mvt.common.module import run_module,save_timeline
# Setup logging using Rich.
LOG_FORMAT = "[%(name)s] %(message)s"
logging.basicConfig(level="INFO", format=LOG_FORMAT, handlers=[
RichHandler(show_path=False, log_time_format="%X")])
log = logging.getLogger(__name__)
# If is windows, use the default path as default
backupFolder:str =''
if platform.system()=='Windows':
backupFolder = os.path.expanduser('~\Apple') + '\MobileSync\Backup'
elif platform.system()=='Darwin':
backupFolder = 'C:\\'
else:
sys.exit("Operating system is not compatible")
#use the correct slashes according to OS
decryptedFolder:str =''
resultsFolder:str =''
if platform.system()=='Windows':
decryptedFolder = 'C:/'
elif platform.system()=='Darwin':
decryptedFolder = 'C:\\'
else:
sys.exit("Operating system is not compatible")
#function to download automatic the STIX files
def dowload_STIX(output):
pegasus = 'https://raw.githubusercontent.com/AmnestyTech/investigations/master/2021-07-18_nso/pegasus.stix2'
predator = 'https://raw.githubusercontent.com/AmnestyTech/investigations/master/2021-12-16_cytrox/cytrox.stix2'
r1 = requests.get(pegasus, allow_redirects=False)
r2 = requests.get(predator, allow_redirects=False)
h = open(output + 'pegasus.stix2', 'wb').write(r1.content)
h = open(output +'cytrox.stix2', 'wb').write(r2.content)
return [output + 'pegasus.stix2',output +'cytrox.stix2']
def browseFileAction(event,obj, id):
global backupFolder,decryptedFolder,resultsFolder
searchPathDirectory = filedialog.askdirectory(title="select", initialdir=backupFolder)
#update the path in the label's text
obj["text"] = searchPathDirectory
#update the #Global variable
if id=="INPUT":
backupFolder = searchPathDirectory
else :
#set output and results folder
decryptedFolder = searchPathDirectory
if platform.system()=='Windows':
resultsFolder = decryptedFolder + '/Results/'
elif platform.system()=='Darwin':
resultsFolder = decryptedFolder + '\Results\\'
else:
sys.exit("Operating system is not compatible")
#use underscore to avoid conflict
def check_backup__(output, backup_path,iocs):
log.info("Checking iTunes backup located at: %s", backup_path)
if output and not os.path.exists(output):
try:
os.makedirs(output)
except Exception as e:
log.critical("Unable to create output folder %s: %s", output, e)
os.exit(1)
indicators = Indicators(log=log)
for ioc_path in iocs:
try:
indicators.parse_stix2(ioc_path)
except IndicatorsFileBadFormat as e:
log.critical(e)
os.exit(1)
log.info("Loaded a total of %d indicators", indicators.ioc_count)
timeline = []
timeline_detected = []
for backup_module in BACKUP_MODULES + MIXED_MODULES:
m = backup_module(base_folder=backup_path, output_folder=output, fast_mode=False,
log=logging.getLogger(backup_module.__module__))
m.is_backup = True
if iocs:
m.indicators = indicators
m.indicators.log = m.log
run_module(m)
timeline.extend(m.timeline)
timeline_detected.extend(m.timeline_detected)
if output:
if len(timeline) > 0:
save_timeline(timeline, os.path.join(output, "timeline.csv"))
if len(timeline_detected) > 0:
save_timeline(timeline_detected, os.path.join(output, "timeline_detected.csv"))
log.info("Checking completed")
def run(event,arg, id):
global backupFolder,decryptedFolder,resultsFolder
password = arg.get()
if len(password)==0:
messagebox.showerror("Password required", "Please enter first your backup password.")
return
backup = DecryptBackup(backupFolder, decryptedFolder)
backup.decrypt_with_password(password)
#start decryption
backup.process_backup()
l = dowload_STIX(resultsFolder)
#check the stored links against the STIX
check_backup__(resultsFolder,decryptedFolder,l)
app = Tk()
#Create first frame for some infos
frameInfo = LabelFrame(app, text="Info",pady=5)
frameInfo.grid(row=0, column=0,padx=5,sticky=W)
lblRootFolder = Label(frameInfo, text='Select backup folder: ',
font=('normal', 11),padx=10)
lblRootFolder.grid(row=0, column=0)
lblRootFolderName = Label(frameInfo, text=backupFolder,
font=('normal', 11),width=40,wraplength=280)
lblRootFolderName.grid(row=0, column=1)
browseButton = Button(frameInfo, text = 'Browse', width = 14)
browseButton.grid(row=0, column=2,pady=4)
outputFolder = Button(frameInfo, text='Browse', width=14)
outputFolder.grid(row=1, column=2,padx=4)
lblSessionStatus = Label(frameInfo, text='Browse decrypted path: ',
font=('normal', 11))
lblSessionStatus.grid(row=1, column=0,padx=10)
lblSessionStatusMessage = Label(frameInfo, text=decryptedFolder,
font=('normal', 11),width=40,wraplength=280)
lblSessionStatusMessage.grid(row=1, column=1)
labelEnterPassword = Label(frameInfo, text='Enter your backup password: ',
font=('normal', 11),padx=10)
labelEnterPassword.grid(row=3, column=0)
passwordEnrty = Entry(frameInfo, show="*", width=15)
passwordEnrty.grid(row=3, column=2,padx=4)
runButton = Button(frameInfo,text='Run analysis', width=14)
runButton.grid(row=4, column=0,padx=4)
# Create bind
#connect browse button with the action function.
browseButton.bind("<ButtonRelease-1>",lambda event, objToLabel=lblRootFolderName: browseFileAction(event,objToLabel, 'INPUT') )
outputFolder.bind("<ButtonRelease-1>",lambda event, objToLabel=lblSessionStatusMessage: browseFileAction(event,objToLabel, 'OUTPUT') )
runButton.bind("<ButtonRelease-1>",lambda event, objToLabel=passwordEnrty: run(event,objToLabel, 'buttonRelease1') )
#Create and call main window
app.title('Predator/Pegasus iOS scanner GUI')
app.geometry('720x150')
# Add Some Style
style = Style()
# Pick A Theme
style.theme_use('default')
# Main window
#add some action before closing window.
def on_closing():
app.destroy()
app.protocol("WM_DELETE_WINDOW",on_closing)
# Start program
app.mainloop()

View File

@ -887,6 +887,10 @@
"version": "15.8.1",
"build": "19H380"
},
{
"version": "15.8.2",
"build": "19H384"
},
{
"build": "20A362",
"version": "16.0"
@ -976,6 +980,10 @@
"version": "16.7.5",
"build": "20H307"
},
{
"version": "16.7.6",
"build": "20H320"
},
{
"version": "17.0",
"build": "21A327"
@ -1031,5 +1039,9 @@
{
"version": "17.3.1",
"build": "21D61"
},
{
"version": "17.4",
"build": "21E219"
}
]