Ejemplo n.º 1
0
    def __init__(self, file_path):
        Cmd.__init__(self)
        self.prompt = 'saam > '

        self.shortcuts.remove(('@', 'load'))
        self.shortcuts.append(('@', 'adb_cmd'))
        self.shortcuts.remove(('@@', '_relative_load'))
        self.shortcuts.append(('$', 'adb_shell_cmd'))
        self.shortcuts.append(('qc', 'quit_and_clean'))

        self.apk_path = file_path
        self.apk = APK(self.apk_path)
        self.apk_out = os.path.basename(file_path) + ".out"
        self.smali_files = None
        self.smali_dir = None
        self.adb = None
        self.smali_method_descs = []
        self.java_files = []

        vsmali_action = CmdLineApp.vsmali_parser.add_argument(
            'sfile', help='smali file path')
        setattr(vsmali_action, argparse_completer.ACTION_ARG_CHOICES,
                ('delimiter_complete', {
                    'delimiter': '/',
                    'match_against': self.smali_method_descs
                }))

        vjava_action = CmdLineApp.vjava_parser.add_argument(
            'jfile', help='java file path')
        setattr(vjava_action, argparse_completer.ACTION_ARG_CHOICES,
                ('delimiter_complete', {
                    'delimiter': '/',
                    'match_against': self.java_files
                }))
Ejemplo n.º 2
0
def retireve_info(file_in_check):

    proc = subprocess.Popen("{} d badging '{}'".format(AAPT, file_in_check), shell=True, stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    r = (proc.communicate()[0]).decode()

    items = re.compile("package: name='(.*?)' versionCode='(.*?)' versionName='(.*?)'").findall(r)
    try:
        pkg, vercode, vername = items[0]
    except:
        pkg = vercode = vername = ''

    try:
        appname = re.compile("application-label:'(.*?)'").findall(r)[0]
    except:
        appname = ''

    try:
        dn,cert = APK(file_in_check).get_certs('sha1')[0]
    except:
        dn, cert = '', ''

    cert = cert.lower()

    #info = [os.path.basename(apk), sha1, pkg, vername, appname, size]
    # log_writer(sha1, pkg, cert, dn, vername, appname)

    # db_data = {"sha1": None, "pkg": None, "cert": None, "dn": None, "vername": None, "appname": None}
    db_data = {"sha1": getSHA1(file_in_check), "pkg": pkg, "cert": cert, "dn": dn, "vername": vername, "appname": appname}
    globalDB.insert_one("apk_info", db_data)
Ejemplo n.º 3
0
def parse_apkfile(file: str) -> Manifest:
    '''
    Args:
        - file: filename

    Returns:
        Manifest(Class)
    '''
    return Manifest(APK(file))
Ejemplo n.º 4
0
 def test_kotlin_app(self):
     file_path = os.path.abspath(
         os.path.join(os.path.dirname(__file__), "..", 'data',
                      'kotlin-app.zip'))
     apk = APK(file_path)
     self.assertEqual([(
         'CN=Android Debug, O=Android, C=US',
         '299D8DE477962C781714EAAB76A90C287BB67123CD2909DE0F743838CAD264E4')
                       ], apk.get_certs('sha256'))
Ejemplo n.º 5
0
def parse_apkfile(file):
    '''
    Args:
        - file: filename or file object
    Returns:
        Manifest(Class)
    '''
    apk = APK(file)
    return Manifest(apk.get_org_manifest())
Ejemplo n.º 6
0
def main(args):
    if os.path.isfile(args.file):
        if args.T:
            t = Magic(args.file).get_type()
            if t != 'apk':
                return
            trees = APK(args.file).get_trees()
            nodes = trees.get(args.T, [])
            for node in nodes:
                APK.pretty_print(node)
        else:
            return

    if not os.path.isdir(args.file):
        return

    apks = []
    for root, _, files in os.walk(args.file):
        for f in files:
            path = os.path.join(root, f)
            t = Magic(path).get_type()
            if t != 'apk':
                continue
            apks.append(APK(path))

    if not apks:
        return

    ai = APK_Intersection(apks)
    if args.m:
        ai.intersect_manifest()

    if args.s:
        ai.intersect_dex_string()  # TODO 相同的字符串太多了,反编译删除干扰的数据

    if args.t:
        ai.intersect_dex_tree()

    if args.p:
        ai.intersect_apis()

    if args.r:
        ai.intersect_resources()
Ejemplo n.º 7
0
    def __init__(self, file_path):
        Cmd.__init__(self)
        self.prompt = 'saam > '

        self.shortcuts.remove(('@', 'load'))
        self.shortcuts.append(('@', 'adb_cmd'))
        self.shortcuts.remove(('@@', '_relative_load'))
        self.shortcuts.append(('$', 'adb_shell_cmd'))
        self.shortcuts.append(('qc', 'quit_and_clean'))

        self.apk_path = file_path
        self.apk = APK(self.apk_path)
        self.apk_out = os.path.basename(file_path) + ".out"
        self.smali_files = None
        self.smali_dir = None
        self.adb = None
Ejemplo n.º 8
0
def main(args):
    apk = APK(args.p)

    if args.m:
        import json
        if apk.get_manifest():
            print(json.dumps(apk.get_manifest(), indent=1))
        elif apk.get_org_manifest():
            print(apk.get_org_manifest())

    elif args.s:
        for item in apk.get_strings():
            print(binascii.unhexlify(item).decode(errors='ignore'))

    elif args.f:
        for item in apk.get_files():
            print(item)
Ejemplo n.º 9
0
    def test_youtube(self):
        file_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "..", 'data',
                         'youtube.zip'))
        apk = APK(file_path)

        # Check that the default (md5) is correct
        self.assertEqual([(
            'C=US, ST=CA, L=Mountain View, O=Google, Inc, OU=Google, Inc, CN=Unknown',
            'D046FC5D1FC3CD0E57C5444097CD5449')], apk.get_certs())

        # Check that sha1 is correct
        self.assertEqual([(
            'C=US, ST=CA, L=Mountain View, O=Google, Inc, OU=Google, Inc, CN=Unknown',
            '24BB24C05E47E0AEFA68A58A766179D9B613A600')],
                         apk.get_certs('sha1'))

        # Check that sha256 is correct
        self.assertEqual([(
            'C=US, ST=CA, L=Mountain View, O=Google, Inc, OU=Google, Inc, CN=Unknown',
            '3D7A1223019AA39D9EA0E3436AB7C0896BFB4FB679F4DE5FE7C23F326C8F994A')
                          ], apk.get_certs('sha256'))
Ejemplo n.º 10
0
def scan_apk(apk_path, rules, timeout):
    td = None
    try:
        with zipfile.ZipFile(apk_path, 'r') as zf:
            for name in zf.namelist():
                td = tempfile.mkdtemp()
                zf.extract(name, td)

                file_path = os.path.join(td, name)
                key_path = '{}!{}'.format(apk_path, name)
                match_dict = do_yara(file_path, rules, timeout)
                if len(match_dict) > 0:
                    print_matches(key_path, match_dict)

    except Exception as e:
        print(e)

    from apkutils import APK
    txt = APK(apk_path).get_org_manifest()
    match_dict = scan_manifest(txt, rules, timeout)
    if len(match_dict) > 0:
        key_path = '{}!{}'.format(apk_path, 'AndroidManifest.xml')
        print_matches(key_path, match_dict)
Ejemplo n.º 11
0
def main(apkPath):

    starttime = datetime.datetime.now()
    """
    :param apkPath: apk文件的最终路径
    :return: NULL
    """

    print("[?]Analyzing {}".format(apkPath))

    if "/" in apkPath:
        savePath = "./result/" + apkPath.split("/")[-1].split(".")[0]
    else:
        savePath = "./result/" + apkPath.split(".")[0]
    try:
        os.mkdir(savePath)
    except Exception as e:
        # print(e)
        pass

    if dex2jar(apkPath, savePath):
        print("[+]Dex2jar success!")

    # print(savePath)
    '''
    先判断这个安装包是否提取过,再开始处理。
    '''
    if len([
            lists for lists in os.listdir(savePath)
            if os.path.isfile(os.path.join(savePath, lists))
    ]) > 5:
        print(
            "[!]The information has been extracted to {}. Please delete it if you need to extract it again"
            .format(savePath))
    else:
        apk = APK(apkPath)

        #获取AndroidManifest.xml的字符串信息
        manifestInfo = getManifestInfo(apk)
        xml = open("{}/AndroidManifest.xml".format(savePath), "w")
        xml.write(manifestInfo)
        xml.close()

        #签名信息
        sign = getSignInfo(apk)

        print("[?]Extracting all strings in apk")

        stringList = getStrings(apk)

        try:
            urlList = []
            ipList = []
            hashlist = []
            forbidStrList = []
            accessKeyList = []

            for string in stringList:

                # 保存所有的字符串
                base = open("{}/strings.txt".format(savePath), "a")
                try:
                    base.write(str(string) + '\n')
                except Exception as e:
                    # print(e)
                    pass
                base.close()
                '''
                下面开始提取URLs
                '''
                # url = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', string)

                urlStrList = ["https://", "http://"]  # 提取的特征
                for urlStr in urlStrList:
                    if urlStr in string:
                        # print(string)
                        if string not in urlList:
                            u = open("{}/urls.txt".format(savePath), "a")
                            u.write(str(string) + '\n')
                            u.close()
                            urlList.append(string)
                '''
                判断是否包含IP
                '''
                p = re.compile(
                    '(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)'
                )
                if p.match(string):
                    ip = open("{}/ips.txt".format(savePath), "a")
                    ip.write(str(string) + '\n')
                    ip.close()
                    if string not in ipList:
                        ipList.append(string)
                '''
                下面开始提取可能是base64编码以及hash的值
                '''
                '''
                下面开始匹配32位长度和15长度的hash
                '''
                if len(string) == 32 or len(string) == 16:
                    if re.match(r'^[a-z0-9]{16,32}$', string):
                        if string not in hashlist:
                            hashlist.append(string)
                            hashs = open("{}/hash.txt".format(savePath), "a")
                            hashs.write(str(string) + '\n')
                            hashs.close()
                '''
                下面提取可能存在的敏感字符串
                '''
                # forbidStr = ["accessKey", "database","ssh","rdp","smb","mysql","sqlserver","oracle",
                #              "ftp","mongodb","memcached","postgresql","telnet","smtp","pop3","imap",
                #              "vnc","redis","admin","root","config","jdbc",".properties","aliyuncs",
                #              "oss"]  # 特征字典
                forbidStr = ['accesskey', 'aliyuncs']
                for forbid in forbidStr:
                    if forbid in string:
                        # print(string)
                        if string not in forbidStrList:
                            fb = open("{}/forbidStr.txt".format(savePath), "a")
                            try:
                                fb.write(str(string) + '\n')
                            except Exception as e:
                                print(e)
                                pass
                            fb.close()
                            forbidStrList.append(string)
                '''
                下面开始匹配AccessKey,自己测试发现:        
                AccessKeyId 约为24位
                AccessKeySecret 约为30位
                '''

                if str(string).isalnum():
                    if re.match(
                            r'^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).{24,24}$',
                            string):
                        if string not in accessKeyList:
                            accessKeyList.append(string)
                            ak = open("{}/accessKey.txt".format(savePath), "a")
                            if string.startswith("LTAI"):
                                ak.write(
                                    "=============AccessKeyId================")
                            ak.write("Id:{}\n".format(str(string)))
                            ak.close()

                    if re.match(
                            r'^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).{30,30}$',
                            string):
                        if string not in accessKeyList:
                            accessKeyList.append(string)
                            ak = open("{}/accessKey.txt".format(savePath), "a")
                            ak.write("Secret:{}\n".format(str(string)))
                            ak.close()
        except Exception as e:
            #print(e)
            pass

        print("""[*]Found:
        \tString:{}\tURL:{}
        \tIps:{}\tHash:{}\tForbidStr:{}
        \tMaybe it's accessKey:{}""".format(len(stringList), len(urlList),
                                            len(ipList), len(hashlist),
                                            len(forbidStrList),
                                            len(accessKeyList)))

    endtime = datetime.datetime.now()
    print("[+]Use time {}s\n".format((endtime - starttime).seconds))
Ejemplo n.º 12
0
import binascii
import os

from apkutils import APK

file_path = os.path.abspath(
    os.path.join(os.path.dirname(__file__), "..", 'data', 'test'))
apk = APK(file_path)

strs = apk.get_strings()  # the strings from all of classes\d*.dex
for item in strs:
    s = binascii.unhexlify(item).decode('utf-8', errors='ignore')
    if 'hello' in s:
        print(s)
Ejemplo n.º 13
0
 def setUp(self):
     file_path = os.path.abspath(
         os.path.join(os.path.dirname(__file__), "..", 'data',
                      'test_zip_fake_pwd'))
     self.apk = APK(file_path)
Ejemplo n.º 14
0
    exit(-1)

if not os.path.exists("./result"):
    os.mkdir("./result")

target_path = sys.argv[1]

ns = "{http://schemas.android.com/apk/res/android}"

safeAttr = lambda x, y: x.attrib[y] if y in x.attrib else ""

for item in glob(f"{target_path}/*.apk"):
    filename = Path(item).stem
    manifest_uuid = str(uuid.uuid4())

    apk = APK(item)
    root = ET.fromstring(apk.get_org_manifest())
    app = root.find("application")
    result = {}
    for child in list(app):
        if child.tag not in result:
            result[child.tag] = []

        name = safeAttr(child, f"{ns}name")
        enabled = safeAttr(child, f"{ns}enabled") != "false"
        exported = safeAttr(child, f"{ns}exported") == "true"
        permission = safeAttr(child, f"{ns}permission")
        read_permission = safeAttr(child, f"{ns}readpermission")
        write_permission = safeAttr(child, f"{ns}writepermission")

        intents = []
Ejemplo n.º 15
0
 def setUp(self):
     file_path = os.path.abspath(
         os.path.join(os.path.dirname(__file__), "..", 'data', 'i15.zip'))
     self.apk = APK(file_path)