code

    內容表格
    沒有標頭

    版本為 11:23, 28 Jul 2026

    到這個版本。

    返回到 版本存檔.

    查閱目前版本

    #-*- 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 subprocess

    import wx.lib.agw.pyprogress as PP
    from BeautifulSoup import BeautifulSoup

    # Set script PATH
    sys.path.append("./usbmuxd")
    sys.path.append("./scripts")
    sys.path.append("./")

    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 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!"))
                subprocess.call( "tools\\redsn0w.exe -i dmg\\%s -r dmg\\%s -k dmg\\%s" % (i, r, k) )
                #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" )
            #hookGlobal["sys.stdout"] = open( "a.txt", "w+" )
            runpy.run_module("tcprelay", run_name="__main__", alter_sys=True, init_globals=hookGlobal)


        def BruteForce(self, evt):
            # Check tcp relay work
            if not CheckPort(2222):
                self.MountUSB(None)

            threading.Thread(target=self._BruteForce).start()
            
        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("<key>passcode</key>") != -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")) )
                #hookGlobal["sys.stdout"] = open( ".\\%s\\password.txt" % GetDi("udid"), "w+" )
                runpy.run_module("keychain_tool", run_name="__main__", alter_sys=True, init_globals=hookGlobal)

                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 <alpine>."), _("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)
                try:
                    mb = os.path.getsize( "%s/encrypted.img" % GetDi("udid") ) / (1000*1000)
                except:
                    mb = 0
                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=hookGlobal)

            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=hookGlobal)

            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

    hookGlobal = {"raw_input": msg, "sys.stdout": HookStdOut()}

    if __name__ == "__main__":
        app = MyApp(redirect=True)

        # do i18n
        mylocale = wx.Locale()
        mylocale.AddCatalogLookupPathPrefix("./lang/")
        mylocale.AddCatalog('cht')

        frame = main(None, -1, _("OSSLab IOS  Forensic Tools for Windows"), (400, 350))
        app.MainLoop()

    Powered by MindTouch Core