#-*- coding: UTF-8 -*- # Coded by Orange@chroot.org import wx import os import sys import time import runpy import socket import shutil import gettext import threading import wx.lib.agw.pyprogress as PP from BeautifulSoup import BeautifulSoup # Set script PATH sys.path.append("./usbmuxd") sys.path.append("./scripts") from util.ramdiskclient import RamdiskToolClient from keystore.keybag import Keybag # set i18n _ = wx.GetTranslation # Hook debug window class LogWindow(wx.PyOnDemandOutputWindow): def __init__(self): wx.PyOnDemandOutputWindow.__init__(self, title = "Message Window") def write(self, text): if self.frame is None: # Bug Fix with Init self.frame fast... XD self.frame = "____" if not wx.Thread_IsMain(): wx.CallAfter(self.CreateOutputWindow, text) else: self.CreateOutputWindow(text) else: if not wx.Thread_IsMain(): wx.CallAfter(self.__write, text) else: self.__write(text) def __write(self, text): try: self.text.AppendText(text) except AttributeError: pass for item in self.triggers: if item in text: self.frame.Raise() break # hook print statement class HookStdOut(object): def __init__(self, *argv, **argd): object.__init__(self) def write(self, s): try: sys.__stdout__.write(s) except: pass class MyApp(wx.App): outputWindowClass = LogWindow def __init__(self, redirect=True): wx.App.__init__(self, redirect) class JB_Dialog(wx.Dialog): def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE,): pre = wx.PreDialog() pre.Create(parent, ID, title, pos, size, style) self.PostCreate(pre) # set description str label = wx.StaticText(self, -1, _("\nPlease select your decide type.")) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5) # set select bar self.l = wx.Choice(self, -1, (100, 50), choices=["Iphone 4 (GSM)", "Iphone 4 (CDMA)", "Iphone 3GS ", "Ipod Touch 3G", "Ipod Touch 4G", "Ipad 1"] ) self.l.SetSelection(0) sizer.Add(self.l, 2, wx.EXPAND|wx.ALL, 10) box = wx.BoxSizer(wx.HORIZONTAL) btnsizer = wx.StdDialogButtonSizer() # set OK button btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) # set CANCEL button btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.SetSizer(sizer) sizer.Fit(self) class BruteForce_Dialog(wx.Dialog): def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE,): pre = wx.PreDialog() pre.Create(parent, ID, title, pos, size, style) self.PostCreate(pre) # set description str sizer = wx.BoxSizer(wx.VERTICAL) # set select bar self.l = wx.Choice(self, -1, (100, 50), choices=[_("The password is empty."), _("I know the password."), _("I do not know the password.")] ) self.l.SetSelection(0) sizer.Add(self.l, 2, wx.EXPAND|wx.ALL, 10) box = wx.BoxSizer(wx.HORIZONTAL) btnsizer = wx.StdDialogButtonSizer() # set OK button btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) # set CANCEL button btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.SetSizer(sizer) sizer.Fit(self) class LangChoice(wx.Dialog): def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE,): pre = wx.PreDialog() pre.Create(parent, ID, title, pos, size, style) self.PostCreate(pre) sizer = wx.BoxSizer(wx.VERTICAL) # set select bar self.l = wx.Choice(self, -1, (100, 50), choices=["Chinese", "English", "Japanese"] ) self.l.SetSelection(0) sizer.Add(self.l, 2, wx.EXPAND|wx.ALL, 10) box = wx.BoxSizer(wx.HORIZONTAL) btnsizer = wx.StdDialogButtonSizer() # set OK button btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) # set CANCEL button btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.SetSizer(sizer) sizer.Fit(self) class main(wx.Frame): def __init__(self, parent, id, title, size): wx.Frame.__init__(self, parent, id, title, size = size) self._main() def CreateElement(self): panel = wx.Panel(self, -1, style=wx.RAISED_BORDER) self.option1 = wx.Button(panel, -1, _("Change language"), style=wx.NO_BORDER) self.option2 = wx.Button(panel, -1, _("Using SSH over USB, Setup Usbmux. (Optional)"), style=wx.NO_BORDER) self.option3 = wx.Button(panel, -1, _("Using JB Exploit to Load Forensic Ramdisk."), style=wx.NO_BORDER) self.option4 = wx.Button(panel, -1, _("Brute Force the Passcode."), style=wx.NO_BORDER) self.option5 = wx.Button(panel, -1, _("Export the Important Password Report from Keychain."), style=wx.NO_BORDER) self.option6 = wx.Button(panel, -1, _("Mirror IOS Data Partition."), style=wx.NO_BORDER) self.option7 = wx.Button(panel, -1, _("Decrypt IOS Data Pratition Image."), style=wx.NO_BORDER) self.option8 = wx.Button(panel, -1, _("Recover Deleted Files from Decrypted Image."), style=wx.NO_BORDER) self.option9 = wx.Button(panel, -1, _("Deeply Revocer Deleted Files from Decrypted Image."), style=wx.NO_BORDER) box = wx.BoxSizer(wx.VERTICAL) # dirty way to eval button for i in range(1, 10): eval("box.Add(self.option%d, 5, wx.EXPAND | wx.ALL, 4)" % i) panel.SetSizer(box) def OnShow(self, evt): value = wx.GetTextFromUser(_("\nPlease enter case number (12 digits)."), _("Message!"), "") if value: try: value = int(value) except: wx.MessageBox("Case number must be digit.", _("Error!"), style=wx.ICON_HAND) value = None if value: # do_lookup(value) pass def ChgLang(self, evt): dlg = LangChoice(self, -1, _("Change Language"), size=(350, 200)) dlg.CenterOnScreen() val = dlg.ShowModal() if val == wx.ID_OK: choice = dlg.l.CurrentSelection if choice == 0: mylocale.AddCatalog('cht') elif choice == 1: mylocale.AddCatalog('en') elif choice == 2: mylocale.AddCatalog('jp') dlg.Destroy() def JB(self, evt): dlg = JB_Dialog(self, -1, _("Using JB Exploit to Load Forensic Ramdisk"), size=(350, 200)) dlg.CenterOnScreen() val = dlg.ShowModal() if val == wx.ID_OK: choice = dlg.l.CurrentSelection if choice == 0: # Iphone 4 (GSM) i = "iPhone3,1_5.0_9A334_Restore.ipsw" r = "iPhone3,1_5.0_9A334_Restore.dmg" k = "iPhone3,1_5.0_9A334_Restore.patched" elif choice == 1: # Iphone 4 (CDMA) i = "iPhone3,3_5.0_9A334_Restore.ipsw" r = "iPhone3,3_5.0_9A334_Restore.dmg" k = "iPhone3,3_5.0_9A334_Restore.patched" elif choice == 2: # Iphone 3GS i = "iPhone2,1_5.0_9A334_Restore.ipsw" r = "iPhone2,1_5.0_9A334_Restore.dmg" k = "iPhone2,1_5.0_9A334_Restore.patched" elif choice == 3: # Ipod Touch 3G i = "iPod3,1_5.0_9A334_Restore.ipsw" r = "iPod3,1_5.0_9A334_Restore.dmg" k = "iPod3,1_5.0_9A334_Restore.patched" elif choice == 4: # Ipod Touch 4G i = "iPod4,1_5.0_9A334_Restore.ipsw" r = "iPod4,1_5.0_9A334_Restore.dmg" k = "iPod4,1_5.0_9A334_Restore.patched" elif choice == 5: # Ipad 1 i = "iPad1,1_5.0_9A334_Restore.ipsw" r = "iPad1,1_5.0_9A334_Restore.dmg" k = "iPad1,1_5.0_9A334_Restore.patched" # run redsn0w in order to JailBreak wx.MessageBox(_("Please click CANCEL button to reboot after JailBreak finish."), _("Message!")) os.system(".\\tools\\redsn0w.exe -i .\\dmg\\%s -r .\\dmg\\%s -k .\\dmg\\%s" % (i, r, k)) dlg.Destroy() def MountUSB(self, evt): if not CheckPort(2222): threading.Thread(target=self._MountUSB).start() def _MountUSB(self): # Run script sys.argv = [] sys.argv.append( "" ) sys.argv.append( "-t" ) sys.argv.append( "22:2222" ) sys.argv.append( "1999:1999" ) runpy.run_module("tcprelay", run_name="__main__", alter_sys=True, init_globals={"raw_input": msg}) def BruteForce(self, evt): # Check tcp relay work if not CheckPort(2222): self.MountUSB(None) threading.Thread(target=self._BruteForce).start() """ dlg = BruteForce_Dialog(self, -1, _("Message"), size=(350, 200)) dlg.CenterOnScreen() val = dlg.ShowModal() if val == wx.ID_OK: choice = dlg.l.CurrentSelection # Know password if choice == 0: threading.Thread(target=self._BruteForce).start() else: threading.Thread(target=self._BruteForce).start() dlg.Destroy() """ def _BruteForce(self): # Run script runpy.run_module("demo_bruteforce", run_name="__main__", alter_sys=True) filename = "%s.plist" % GetDi("dataVolumeUUID") if os.path.exists(filename): with open(filename, "a+") as fp: flag = False for i in fp.readlines(): if flag: pw = i flag = False break if i.find("passcode") != -1: flag = True if pw: pw = BeautifulSoup(pw) pw = pw.findAll("string")[0].string if pw == None: wx.MessageBox(_("There is no password") , _("Message!")) else: wx.MessageBox(_("The password is %s") % pw, ("Message!")) else: wx.MessageBox(_("Can not find password file"), _("Error!")) # Back to work direcytory os.chdir("../") def KeychainDeCrypt(self, evt): # Check tcp relay work # QQ strange bug QQ if not CheckPort(2222): self.MountUSB(None) threading.Thread(target=self._KeychainDeCrypt).start() def _KeychainDeCrypt(self): # Check plist and keychain if os.path.exists( "%s/%s.plist" % (GetDi("udid"), GetDi("dataVolumeUUID") ) ) and os.path.exists( "%s/keychain-2.db" % GetDi("udid") ): # Run script sys.argv = [] sys.argv.append( "" ) sys.argv.append( "-d") sys.argv.append( ".\\%s\\keychain-2.db" % GetDi("udid") ) sys.argv.append( ".\\%s\\%s.plist" % (GetDi("udid"), GetDi("dataVolumeUUID")) ) runpy.run_module("keychain_tool", run_name="__main__", alter_sys=True, init_globals={"raw_input": msg}) wx.MessageBox(_("The password report has been saved."), _("Message!")) else: wx.MessageBox(_("Please brute force the passcode first."), _("Message!")) def MirrorIOS(self, evt): # Check tcp relay work if not CheckPort(2222): self.MountUSB(None) wx.MessageBox(_("Please switch to the terminal window, and enter password ."), _("Notice")) tmp = {"flag": True} threading.Thread(target=self._MirrorIOS, args=(tmp,)).start() dlg = PP.PyProgress(None, -1, "Dialog", "Progress") while tmp["flag"]: wx.MilliSleep(250) mb = os.path.getsize( "%s/encrypted.img" % GetDi("udid") ) / (1000*1000) dlg.Refresh() dlg.UpdatePulse("%d MB" % mb) dlg.Destroy() if os.path.getsize( "%s/encrypted.img" % GetDi("udid") ) == 0: wx.MessageBox(_("Failed, May the password is incorrect."), _("Message")) else: wx.MessageBox(_("Mirroring finish, the file name is encrypted.img."), _("Message")) def _MirrorIOS(self, arg): class __(object): def __init__(self, *argv, **argd): object.__init__(self) def write(self, s): pass sys.stdout = __() cmd = "test -e /dev/rdisk0s2s1 && a='rdisk0s2s1';test -e /dev/rdisk0s1s2 && a='rdisk0s1s2';dd if=/dev/$a bs=8192;" os.system(".\\ssh\ssh.exe -p 2222 root@localhost \"%s\" | .\\ssh\\dd.exe of=%s/encrypted.img" % (cmd, GetDi("udid")) ) sys.stdout = HookStdOut() arg["flag"] = False def MirrorDecrypt(self, evt): # Check tcp relay work if not CheckPort(2222): self.MountUSB(None) os.chdir(GetDi("udid")) # Check image.img exists if not os.path.exists("encrypted.img") and not os.path.exists("decrypted.img"): global _ wx.MessageBox(_("Please Do Mirror Action First."), _("Message")) os.chdir("../") return None if not os.path.exists("backup_encrypted.img" ): def __(arg): shutil.copy("encrypted.img", "backup_encrypted.img") arg["flag"] = False # pass by reference so using a list tmp = {"flag": True} threading.Thread(target=__, args=(tmp,)).start() dlg = PP.PyProgress(None, -1, _("Dialog"), _("Please Watting Backup the Image File.")) while tmp["flag"]: wx.MilliSleep(250) progress = (os.path.getsize("backup_encrypted.img")*100.0) / os.path.getsize("encrypted.img") dlg.Refresh() dlg.UpdatePulse("%d %%" % progress) dlg.Destroy() os.chdir("../") threading.Thread(target=self._MirrorDecrypt).start() def _MirrorDecrypt(self): if os.path.exists("%s/encrypted.img" % GetDi("udid")): os.rename( "%s/encrypted.img" % GetDi("udid"), "%s/decrypted.img" % GetDi("udid") ) # Run script sys.argv = [] sys.argv.append( "" ) sys.argv.append( "%s/decrypted.img" % GetDi("udid") ) runpy.run_module("emf_decrypter", run_name="__main__", alter_sys=True, init_globals={"raw_input": msg}) wx.MessageBox(_("Finish IOS mirror decryption, original image file name is encrypted.img, decrypted file name is decryptde.img."), _("Message")) def MirrorUnDelete(self, evt): # Check tcp relay work if not CheckPort(2222): self.MountUSB(None) # Check image.img exists if not os.path.exists( "%s/decrypted.img" % GetDi("udid") ): global _ wx.MessageBox(_("Please Do Mirror Action First."), _("Message")) return None threading.Thread(target=self._MirrorUnDelete).start() def _MirrorUnDelete(self): # Run script sys.argv = [] sys.argv.append( "" ) sys.argv.append( "%s/decrypted.img" % GetDi("udid") ) runpy.run_module("emf_undelete", run_name="__main__", alter_sys=True, init_globals={"raw_input": msg}) wx.MessageBox(_("Recover files are under directory %s/%s ." % (os.getcwd(), GetDi("udid"))), _("Message")) def MirrorUnDeleteDeep(self, evt): # Check tcp relay work if not CheckPort(2222): self.MountUSB(None) # Check image.img exists if not os.path.exists( "%s/decrypted.img" % GetDi("udid") ): global _ wx.MessageBox(_("Please Do Mirror Action First."), _("Message")) return None threading.Thread(target=self._MirrorUnDeleteDeep).start() def _MirrorUnDeleteDeep(self): # Run script sys.argv = [] sys.argv.append( "" ) sys.argv.append( "%s/decrypted.img" % GetDi("udid") ) runpy.run_module("Undelete_deep", run_name="__main__", alter_sys=True) def _main(self): # Create Buttons & Texts self.CreateElement() # Binding events self.option1.Bind(wx.EVT_BUTTON, self.ChgLang) self.option2.Bind(wx.EVT_BUTTON, self.MountUSB) self.option3.Bind(wx.EVT_BUTTON, self.JB) self.option4.Bind(wx.EVT_BUTTON, self.BruteForce) self.option5.Bind(wx.EVT_BUTTON, self.KeychainDeCrypt) self.option6.Bind(wx.EVT_BUTTON, self.MirrorIOS) self.option7.Bind(wx.EVT_BUTTON, self.MirrorDecrypt) self.option8.Bind(wx.EVT_BUTTON, self.MirrorUnDelete) self.option9.Bind(wx.EVT_BUTTON, self.MirrorUnDeleteDeep) #self.Bind(wx.EVT_SHOW, self.OnShow) self.Centre() self.Show() def CheckPort(port=2222): ret = False s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind( ("127.0.0.1", port) ) s.close() except Exception, e: ret = True return ret def GetDi(key): client = RamdiskToolClient() di = client.getDeviceInfos() #udid or dataVolumeUUID return di[key] # Hook print statement sys.stdout = HookStdOut() # Hook raw_input() def msg(): wx.MessageBox(_("Plese enter OK to continue."), _("Message")) raw_input = msg if __name__ == "__main__": app = MyApp(redirect=True) # do i18n mylocale = wx.Locale() mylocale.AddCatalogLookupPathPrefix("./lang/") mylocale.AddCatalog('cht') frame = main(None, -1, _("IOS Forensic Tools for Wiindows"), (400, 350)) app.MainLoop()