예제 #1
0
    def read_log(self, file):
        # clear the log in iphone
        Utils.cmd_block('cat /dev/null > /var/log/syslog')

        log_file = open(file)
        while 1:
            line = log_file.readline()
            self.check_log_line(line)
예제 #2
0
    def check(self):
        log_file = ['/var/log/syslog']

        # start check log sensitive data
        check = Checker(log_file, 'LOG')
        check.start()
        data.log_file_results = check.results
        Utils.printy_result('Log Check.', 1)
예제 #3
0
 def finish_dynamic_check(self):
     self.t_socket.join()
     data.dynamic_json = self.app_dynamic_info
     Utils.printy_result("Dynamic Check .", 1)
     self.analyse()
     IOS.storage_check()
     data.status ^= 0b0001
     return True
예제 #4
0
 def on(self):
     try:
         self.con = sqlite3.connect("task.db")
         self.c = self.con.cursor()
     except sqlite3.Error as e:
         # print e.args[0]
         data.logger.debug("Can't Connect to Database")
         Utils.shutdown()
예제 #5
0
def via_sftp(src):
    cmd = 'cp {} /tmp/temp.binary'.format(src)
    Utils.cmd_block(data.client, cmd)
    src = '/tmp/temp.binary'
    des = '{}/temp/{}/binary/'.format(
        os.path.abspath('.'), data.start_time) + data.metadata['bundle_id']
    Utils.sftp_get(config.mobile_ip, config.ssh_port, config.mobile_user,
                   config.mobile_password, src, des)
    return des
예제 #6
0
 def connect(connector):
     if connector == "u":
         thread.start_new_thread(tcprelay.main, (['-t', '22:2222'], ))
         time.sleep(5)
     while True:
         try:
             Utils.printy('Conneting..', 0)
             data.client = ssh.set_ssh_conn(config.mobile_ip, config.ssh_port, config.mobile_user, config.mobile_password)
             break
         except socket.error:
             time.sleep(5)
             Utils.printy_result('Operation timed out.', 0)
예제 #7
0
 def stand_alone_entrance(self):
     # self.start_dynamic_check()
     IOS.binary_check()
     # self.server_scan(','.join(String().get_url(data.strings))) # nessus
     self.start_static_analyse() # 静态引擎是独立的引擎,可生成独立的报告
     # self.check_status() # 动态检测timeout
     data.dynamic_json = self.app_dynamic_info
     self.analyse()
     IOS.storage_check()
     report_gen = Generator() # 生成报告
     report_gen.generate()
     Utils.printy("Analyze Done.", 4) # 分析结束
     self.clean()
예제 #8
0
 def __init__(self, ipa_path, bundle_id):
     if not data.logger:
         data.logger = logging.getLogger('root')
     self.status = 0
     self.need_connection = False
     Utils.build()
     pre_status = IOSs.prepare_for_basic_info(ipa_path, bundle_id)
     if pre_status == 4:
         self.status = 4
     elif pre_status == 5:
         self.status = 5
     self.t_static = static_analyze.static_analyzer()
     self.server = Nessus()
예제 #9
0
 def stand_alone_entrance(self):
     self.start_dynamic_check()
     IOSs.binary_check()
     self.server_scan(','.join(String().get_url(data.strings)))
     self.start_static_analyse()
     self.check_status()
     data.dynamic_json = self.app_dynamic_info
     self.analyse()
     IOSs.storage_check()
     report_gen = Generator()
     report_gen.generate()
     Utils.printy("Analyze Done.", 4)
     self.clean()
예제 #10
0
 def do_analyse(self):
     data.static_process_id = os.getpid()
     exec "from staticAnalyzer import StaticAnalyze"
     exec "from staticAnalyzer.ttypes import *"
     Utils.printy('Start static analysis', 0)
     time.sleep(1)
     try:
         transport = TSocket.TSocket(config.thrift_ip, config.thrift_port)
         transport = TTransport.TBufferedTransport(transport)
         protocol = TBinaryProtocol.TBinaryProtocol(transport)
         client = StaticAnalyze.Client(protocol)
         transport.open()
         while True:
             if client.connect() == "Connected":
                 Utils.printy_result("Connect to IDA Server", 1)
                 break
         report_dir = "{}/temp/{}/report".format(data.root, data.start_time)
         msg = client.analyze(data.static_file_path,
                              report_dir,
                              report_type='pdf')
         if msg == "Fail":
             Utils.printy_result("Static Analyse", 0)
         else:
             Utils.printy_result('Static Analyse.', 1)
             data.static_report = msg
         transport.close()
         data.status ^= 0b0010
     except Thrift.TException, ex:
         print "%s" % ex.message
예제 #11
0
def sql_check():
    try:
        files = get_files()
        if not files:
            Utils.printy("No SQL files found ", 2)
            return
        retrieved_files = Utils.get_dataprotection(files)
        data.local_file_protection.extend(retrieved_files)
        check = Checker(files, 'SQL')
        check.start()
        Utils.printy_result('Database Check.', 1)
        return check.results
    except Exception, e:
        data.logger.warn(e)
예제 #12
0
    def check(self):
        try:
            files = self.get_files()
            if not files:
                Utils.printy("No Plist files found ", 2)
                return
            # Add data protection class
            retrieved_files = Utils.get_dataprotection(files)
            data.local_file_protection.extend(retrieved_files)

            # start check plist sensitive data
            check = Checker(files, 'PLIST')
            check.start()
            data.plist_file_results = check.results
        except Exception, e:
            data.logger.warn(e)
예제 #13
0
def get_files():
    files = []
    dirs = [data.metadata['bundle_directory'], data.metadata['data_directory']]
    dirs_str = ' '.join(dirs)
    cmd = '{bin} {dirs_str} -type f -name "*.sqlite"'.format(
        bin=data.DEVICE_TOOLS['FIND'], dirs_str=dirs_str)
    temp = Utils.cmd_block(data.client, cmd).split("\n")
    cmd = '{bin} {dirs_str} -type f -name "*.db"'.format(
        bin=data.DEVICE_TOOLS['FIND'], dirs_str=dirs_str)
    temp.extend(Utils.cmd_block(data.client, cmd).split("\n"))

    for db in temp:
        if db != '':
            files.append(db)

    return files
예제 #14
0
 def crashed(self):
     cmd = 'find {} -type f | grep {}'.format(data.crash_report_folder,
                                              self.app)
     if Utils.cmd_block(data.client, cmd).split("\n")[0]:
         return True
     else:
         return False
예제 #15
0
 def __init__(self, ipa_path, bundle_id, connector, static_type=None):
     data.static_type = static_type
     if not data.logger:
         data.logger = logging.getLogger('root')
     self.status = 0  # 作为检测任务,与server.py中对应
     IOS.connect(connector)  # 与测试机建立连接
     Utils.build()  # 在测试机中建立文件夹,用于检测的中间文件存储
     pre_status = IOS.prepare_for_basic_info(ipa_path, bundle_id)
     if pre_status == 4:
         self.status = 4
     elif pre_status == 5:
         self.status = 5
     self.t_static = static_analyze.static_analyzer() # 静态分析入口 do_analyse
     self.app_dynamic_info = AppDynamicInfo(data.app_bundleID)
     self.t_socket = socketServer.SocketServerThread(self.app_dynamic_info)
     self.server = Nessus()
예제 #16
0
 def check_status(self):
     process_time = 0
     while True:
         time.sleep(10)
         process_time += 10
         status = data.status & 0b11
         if status == 0b11:
             break
         # dynamic not finished
         elif status == 0b10:
             if process_time >= 180:
                 self.t_socket.stop()
                 # self.t_socket.join()
                 Utils.printy_result("Stop Dynamic Analysis, Timeout", 0)
                 break
         else:
             continue
예제 #17
0
 def parse_plist(self, plist):
     """Given a plist file, copy it to temp folder, convert it to XML, and run plutil on it."""
     # Copy the plist
     plist_temp = self.build_temp_path_for_file(plist.strip("'"))
     plist_copy = Utils.escape_path(plist_temp)
     self.file_copy(plist, plist_copy)
     # Convert to xml
     cmd = '{plutil} -convert xml1 {plist}'.format(
         plutil=data.DEVICE_TOOLS['PLUTIL'], plist=plist_copy)
     Utils.cmd_block(self.client, cmd)
     # Cat the content
     cmd = 'cat {}'.format(plist_copy)
     out = Utils.cmd_block(self.client, cmd)
     # Parse it with plistlib
     out = str(''.join(out).encode('utf-8'))
     pl = plistlib.readPlistFromString(out)
     return pl
예제 #18
0
 def __run_otool(self, query, grep=None):
     """Run otool against a specific architecture."""
     cmd = '{bin} {query} {app}'.format(bin=data.DEVICE_TOOLS['OTOOL'],
                                        query=query,
                                        app=data.metadata['binary_path'])
     if grep:
         cmd = "%s | grep -Ei \"%s\"" % (cmd, grep)
     out = Utils.cmd_block(self.client, cmd).split("\n")
     return out
예제 #19
0
 def prepare_for_basic_info(ipa_path, bundle_id):
     # data.app_dict = Utils.ret_LastLaunch()  # set app_dict
     # if ipa_path:
     #     should_install.install_ipa_from_local(ipa_path)  # set bundleID
     # elif bundle_id:
     #     data.app_bundleID = bundle_id
     # else:
     #     should_install.ask_for_user_choose()
     #     Utils.getInstalledAppList()  # set bundle_ID
     # Metadata().get_metadata()
     # print data.app_bundleID
     # pre_clutch.clutch()
     if ipa_path:
         try:
             should_install.install_ipa_from_local(ipa_path)  # set bundleID
         except Exception, e:
             Utils.printy("Cannot install ipa ", 2)
             data.logger.debug(e)
             return 4
예제 #20
0
 def _detect_architectures(self, binary):
     """Use lipo to detect supported architectures."""
     # Run lipo
     cmd = '{lipo} -info {binary}'.format(lipo=data.DEVICE_TOOLS['LIPO'],
                                          binary=binary)
     out = Utils.cmd_block(self.client, cmd)
     # Parse output
     msg = out.strip()
     res = msg.rsplit(': ')[-1].split(' ')
     return res
예제 #21
0
 def start_server(self):
     HOST = config.socket_ip
     PORT = config.socket_port
     self.dynamic_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.dynamic_socket.bind((HOST, int(PORT)))
     self.dynamic_socket.listen(1)
     Utils.printy('Start server to receive data from application.', 0)
     while not self.stopped():
         conn, addr = self.dynamic_socket.accept()
         input_data = conn.recv(2048)
         input_data = input_data[0:-1]
         if input_data == ('DONE:' + data.app_bundleID):
             Utils.printy_result("Dynamic Check .", 1)
             self.dynamic_socket.close()
             break
         elif input_data == 'Timeout':
             self.dynamic_socket.close()
             break
         self.parse_json(self.app_info, input_data)
     data.status ^= 0b0001
예제 #22
0
 def paltform_entrance(self):
     self.start_dynamic_check()
     IOSs.binary_check()
     self.server_scan(','.join(String().get_url(data.strings)))
     self.start_static_analyse()
     # data.status ^= 0b0010
     self.check_status()
     data.dynamic_json = self.app_dynamic_info
     self.analyse()
     IOSs.storage_check()
     report_gen = Generator()
     report_gen.generate()
     Utils.printy("Analyze Done.", 4)
     # if self.finish_dynamic_check():
     #     self.analyse()
     #     IOS.storage_check()
     # if self.finish_static_analyse():
     #     report_gen = Generator()
     #     report_gen.generate()
     # if self.finish_server_scan():
     self.clean()
예제 #23
0
 def get_files(self):
     files = []
     dirs = [
         data.metadata['bundle_directory'], data.metadata['data_directory']
     ]
     dirs_str = ' '.join(dirs)
     cmd = '{bin} {dirs_str} -type f -name "*.plist"'.format(
         bin=data.DEVICE_TOOLS['FIND'], dirs_str=dirs_str)
     temp = Utils.cmd_block(self.client, cmd).split("\n")
     for f in temp:
         if f != '':
             files.append(f)
     return files
예제 #24
0
def dump_binary():
    try:
        target_doc_path = data.metadata['data_directory'] + '/Documents'
        target_doc_file = target_doc_path + '/dumpdecrypted.dylib'
        Utils.sftp_put(ip=config.mobile_ip,
                       port=config.ssh_port,
                       username=config.mobile_user,
                       password=config.mobile_password,
                       remote_path=target_doc_file,
                       local_file='./tools/dumpdecrypted.dylib')

        target_bin_path = data.metadata['binary_path']
        dump_cmd = 'DYLD_INSERT_LIBRARIES={} {}'.format(
            target_doc_file, target_bin_path)
        Utils.cmd_block(data.client, dump_cmd)
        # get decrypted file from iphone
        remote_file = './{}.decrypted'.format(data.metadata['binary_name'])
        data.static_file_path = bin_get.via_sftp(remote_file)

        return True
    except Exception:
        return False
예제 #25
0
 def dump(self):
     try:
         cmd = './keychain_dumper'
         out = Utils.cmd_block(self.client, cmd)
         lines = out.split('\n')
         for line in lines:
             if line.startswith('Keychain Data:') and not '(null)' in line:
                 content = line[15:]
                 if content:
                     self.all_keychain_values.append(content)
         self.filter()
     except Exception, e:
         data.logger.warn(e)
예제 #26
0
def ask_for_user_choose():
    Utils.printy('[1]: I have installed the app .', 1)
    Utils.printy('[2]: I have the ipa file local to install.', 1)
    while True:
        user_choose_input = raw_input(clint.textui.colored.yellow("> >> >>> Enter your choice please [1/2]: > "))
        if user_choose_input == '1':
            Utils.getInstalledAppList()
            break
        elif user_choose_input == '2':
            if install_ipa_from_local(""):
                break
            else:
                continue
        else:
            Utils.printy('Invalid input!', 2)
예제 #27
0
    def prepare_for_basic_info(ipa_path, bundle_id):
        # data.app_dict = Utils.ret_LastLaunch()  # set app_dict
        # if ipa_path:
        #     should_install.install_ipa_from_local(ipa_path)  # set bundleID
        # elif bundle_id:
        #     data.app_bundleID = bundle_id
        # else:
        #     should_install.ask_for_user_choose()
        #     Utils.getInstalledAppList()  # set bundle_ID
        # Metadata().get_metadata()
        # print data.app_bundleID
        # pre_clutch.clutch()

        # data.app_dict = Utils.ret_last_launch()   !!! NOT SUPPORTED BY iOS9 ANYMORE
        if not data.app_dict:
            data.app_dict = Utils.ret_last_launch_9()  # 获取当前已安装应用列表
        if ipa_path:  # 来自于平台
            try:
                should_install.install_ipa_from_local(ipa_path)  # set bundleID
            except Exception, e:
                Utils.printy("Cannot install ipa ", 2)
                data.logger.debug(e)
                return 4  # 安装失败
예제 #28
0
 def get(self):
     cmd = '{bin} -L {app}'.format(bin=data.DEVICE_TOOLS['OTOOL'],
                                   app=data.metadata['binary_path'])
     out = Utils.cmd_block(self.client, cmd).split("\n")
     if out:
         try:
             del out[0]
             for i in out:
                 i = i.strip('\t')
                 if len(i) > 0:
                     data.shared_lib.append(i)
             # print "--------------------shared_library-------------------"
             return True
         except AttributeError:
             return False
     else:
         return False
예제 #29
0
 def fuzz(self):
     total_count = len(self.fuzz_inputs)
     count = 0
     for url in self.fuzz_inputs:
         count += 1
         # print '[{}/{}]fuzzing...[{}]'.format(count, total_count, url)
         time.sleep(1)
         self.delete_old_reports()
         Utils.openurl(url)
         time.sleep(2)
         Utils.kill_by_name(self.app)
         self.results[url] = self.crashed()
     Utils.printy_result('Fuzz', True)
     data.fuzz_result = self.results
예제 #30
0
def install_ipa_from_local(ipa_path):
    if ipa_path:  # 从平台下发的任务,经由这个方法,ipa_path有值
        ipa = zipfile.ZipFile(ipa_path)
        pat = re.compile("Payload[/\\\][\w.]+[/\\\]Info.plist")
        for name in ipa.namelist():
            if pat.search(name):
                plist_path = name
                break
                # plist_path = ipa.extract(name)
                # plist = plistlib.readPlist(plist_path)
                # data.app_bundleID = plistlib.readPlist(plist_path)["CFBundleIdentifier"]
                # print data.app_bundleID

    else:  # 从单机版入口,ipa_path为空,需要实时要求用户输入
        while True:
            ipa_path = raw_input(clint.textui.colored.yellow("> >> >>> Input the Path: > ")).strip()
            if not os.path.exists(ipa_path):
                Utils.printy_result('No such file ', 0)
            elif not ipa_path.endswith("ipa"):
                Utils.printy_result('Not ipa file ', 0)
            else:
                break

    # sftp to iPhone
    Utils.sftp_put(config.mobile_ip, config.ssh_port, config.mobile_user, config.mobile_password,
                   '/tmp/detect/temp.ipa', ipa_path)
    if ipa_path:
        ipa = zipfile.ZipFile(ipa_path)
        pat = re.compile("Payload[/\\\][\w.]+[/\\\]Info.plist")
        for name in ipa.namelist():
            if pat.search(name):
                break
        plist_path = ipa.extract(name)
        tmp = plist_path + '.tmp'
        data.app_bundleID = commands.getstatusoutput(
            'plutil -extract CFBundleIdentifier xml1 {} -o {}; plutil -p {}'.
            format(plist_path, tmp, tmp))[1].strip('"')
        Utils.cmd_block(data.client, 'ipainstaller {}'.format('/tmp/detect/temp.ipa'))
        return True