Python攻防-APK批量化Pull与自动化反编译

news2024/11/20 13:43:57

文章目录

  • 前言
  • Pull APK
    • 根据包名列表
    • 根据手机路径
  • 逆向APK
    • 自动化反编译
    • findstr检索…
  • 总结

前言

日常工作过程中,经常会遇到发现新的攻击模式的情况下,需要全量排查手机上所有 APP 的代码是否存在该类代码缺陷。对于复杂的攻击模式而言,往往需要动用强大静态分析的工具(如 soot 框架或 Codeql),但对于简单的攻击模式而言(比如仅仅是定位某些关键词、关键函数),则通过快速检索即可解决。

但是问题来了,如何在没有 APP 源码的情况下,快速获得所有目标 APP 的代码并进行快速检索?答案当然是借助 jadx 工具对 APK 进行自动化反编译。这涉及两个需要解决的问题:

  1. 以 shell 权限(无需 root)批量从目标手机拉取 APK 文件;
  2. 将拉取到的多个 APK 文件批量、自动化地进行反编译并获得 java 文件;

本文将记录下如何通过编写自定义的 Python 脚本来解决上述场景遇到的测试需求和实现难点。

Pull APK

先来解决第一个问题:批量从目标手机拉取 APK 文件。

根据包名列表

以下代码是根据 package.txt 文件列出的包名,自动拉取对应的 apk 文件到本地指定路径:

def pullAPK_by_PackageList():
    """
    根据指定的包名列表,批量拉取手机中的APK文件到本地路径
    :return: null
    """
    pkgList = []
    print(Fore.BLUE + "[*]Start pull apk…")
    with open('packageList.txt', 'r', encoding='utf-8') as f:
        for line in f.readlines():
            packageName = line.strip('\n')  # 去除文本中的换行符
            pkgList.append(packageName)
            try:
                pathCmd = "adb shell pm path " + packageName
                result = os.popen(pathCmd).read().strip('\n')  # 去除末尾的换行符,"package:/system/priv-app/aaa.apk"
                pkgPath = result.split(":")[1]  # 截取返回结果中的路径,去除头部多余的"package:"
                pullCmd = "adb pull " + pkgPath + " D:/tmp/Tr0e/TestApk/" + packageName + ".apk"
                os.system(pullCmd)
                print(Fore.GREEN + "[+]Success pull: " + packageName)
            except Exception as e:
                print(Fore.RED + "[-]%s" % e)
                print(Fore.RED + "[-]Pull {0} fail, please check packageName.".format(packageName))
    print(Fore.BLUE + "[*]Done.Enjoy it!")

使用 Android 模拟器来做试验, package.txt 列出的想要 pull 的应用如下:

com.android.email
com.android.calendar
com.android.contacts

代码运行效果如下:
在这里插入图片描述

根据手机路径

以上的场景局限于在想要 pull 特定的应用列表且已知其 packageName,实际上要批量快速获取手机上所有 APK,那么应该 pull 特定的路径下的整个文件夹,比如:

pathList = ["system/priv-app", "system/app", "hw_product/app"]

代码如下所示:

def pullAPK_by_SystemPath():
    """
    根据手机的app path路径,批量拉取手机中的APK文件到本地路径
    :return: null
    """
    pathList = ["system/priv-app", "system/app"]
    print(Fore.BLUE + "[*]Start pull apk…")
    start = time.time()
    for path in pathList:
        pullCmd = "adb pull " + path + " D:/tmp/Tr0e/pullApk/" + path.replace("/", "_")
        os.system(pullCmd)
        print(Fore.GREEN + "[+]Success pull: " + path)
    end = time.time()
    print(Fore.BLUE + "[*]Done.Totally time is " + str(end - start) + "s.Enjoy it!")

代码运行效果如下所示:
在这里插入图片描述
在这里插入图片描述

以上便解决了批量拉取手机上的 APK 文件的问题。

逆向APK

接下来便可以对 pull 下来的 apk 文件进行自动化的反编译了,以便对 apk 文件的源码进行检索。

自动化反编译

反编译借助的是 jadx-1.4.5.zip 反编译神器,请自行下载并解压缩到本地文件夹:
在这里插入图片描述
批量反编译的代码如下所示:

apk_list = []  # 递归查询指定文件夹后获得的所有apk文件的路径列表

def apkReverse():
    """
    借助jadx工具,批量反编译指定文件夹下的所有APK(支持文件夹嵌套),输出到outputPath
    :return: null
    """
    apkPath = os.walk("D:/tmp/Android/TestApk/")
    toolPath = "D:/Security/Mobile/jadx/jadx-1.4.4/bin/jadx"
    outputPath = "D:/tmp/Android/Result/"
    find_apk("D:/tmp/Android/TestApk")
    apkTotalNum = len(apk_list)
    num = 1
    start = time.time()
    print(Fore.BLUE + "[*]Start reverse apk…")
    for path, dir_list, file_list in apkPath:  # 反编译apkPath文件夹下所有的apk文件
        for file_name in file_list:
            if file_name.endswith('.apk'):
                print(Fore.GREEN + "*****************************************")
                print("[" + str(num) + "/" + str(apkTotalNum) + "]" + "正在反编译的APK:" + file_name)
                path_apk = os.path.join(path, file_name)
                command = toolPath + " -d " + outputPath + file_name + " -j 4 " + path_apk
                os.system(command)
                num = num + 1
    end = time.time()
    print(Fore.GREEN + "[*]Done.Totally time is " + str(end - start) + "s.Enjoy it!")


def find_apk(file_path):
    """
    递归查询file_path文件夹下的apk文件
    :param file_path: 目标文件夹,如D:/tmp/Android,请留意最后不要加"/"
    :return: 目标文件夹下所有apk文件的列表
    """
    if os.path.isfile(file_path):
        if str(file_path).endswith(".apk"):
            apk_list.append(file_path)
    else:
        for file_ls in os.listdir(file_path):
            find_apk(str(file_path) + "/" + str(file_ls))

为了方便演示,指定待反编译的 APK 文件夹存放如下文件(可以看到,存在子文件夹、非 apk 类型的文件):
在这里插入图片描述在这里插入图片描述
运行脚本进行自动化反编译,效果如下:
在这里插入图片描述
可以看到,程序已经帮我们自动识别出目标文件夹下有哪些 apk 应用并进行了批量反编译,反编译出来的文件结果输出到指定的 outputPath 路径下。

findstr检索…

完成了 apk 文件的批量拉取和自动化反编译,接下来就可以借助 cmd 命令 findstr 在 Windows 设备上对反编译出来的 APP 代码和资源文件进行快速检索了。

比如在指定文件夹下,忽略大小写、递归搜索所有 java 文件下得到关键词:

findstr /I /s "public static" *.java

检索效果如下所示(实际上细心的你一定会发现我下图检索出来的文件夹下是反编译失败的结果……是的没错,jadx 并无法保证一定能反编译成功):
在这里插入图片描述

findstr命令参考教程:在Windows中使用Findstr命令搜索文本文件内容。

完整命令帮助如下:

Searches for strings in files.

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
        [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
        strings [[drive:][path]filename[ ...]]

  /B         Matches pattern if at the beginning of a line.
  /E         Matches pattern if at the end of a line.
  /L         Uses search strings literally.
  /R         Uses search strings as regular expressions.
  /S         Searches for matching files in the current directory and all
             subdirectories.
  /I         Specifies that the search is not to be case-sensitive.
  /X         Prints lines that match exactly.
  /V         Prints only lines that do not contain a match.
  /N         Prints the line number before each line that matches.
  /M         Prints only the filename if a file contains a match.
  /O         Prints character offset before each matching line.
  /P         Skip files with non-printable characters.
  /OFF[LINE] Do not skip files with offline attribute set.
  /A:attr    Specifies color attribute with two hex digits. See "color /?"
  /F:file    Reads file list from the specified file(/ stands for console).
  /C:string  Uses specified string as a literal search string.
  /G:file    Gets search strings from the specified file(/ stands for console).
  /D:dir     Search a semicolon delimited list of directories
  strings    Text to be searched for.
  [drive:][path]filename
             Specifies a file or files to search.

Use spaces to separate multiple search strings unless the argument is prefixed
with /C.  For example, 'FINDSTR "hello there" x.y' searches for "hello" or
"there" in file x.y.  'FINDSTR /C:"hello there" x.y' searches for
"hello there" in file x.y.

Regular expression quick reference:
  .        Wildcard: any character
  *        Repeat: zero or more occurrences of previous character or class
  ^        Line position: beginning of line
  $        Line position: end of line
  [class]  Character class: any one character in set
  [^class] Inverse class: any one character not in set
  [x-y]    Range: any characters within the specified range
  \x       Escape: literal use of metacharacter x
  \<xyz    Word position: beginning of word
  xyz\>    Word position: end of word

For full information on FINDSTR regular expressions refer to the online Command
Reference.

总结

工欲善其事,必先利其器。如何将重复的工作通过自动化脚本来完成,是每个安全工程师提高工作效率和漏洞捕获成功率必须面对的问题。同时脚本和工具需要在实战过程中不断改进和优化,最后给各位附上本文的完整代码:apkReverse.py。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MyBatis框架】动态SQL

MyBatis之动态SQL 目录MyBatis之动态SQL1. < if > 元素2. < where >3. < choose >,< when >,< otherwise >元素4. < trim >元素5. < set >元素6. < foreach >元素6.1 添加批量数据6.2 批量删除数据7. < SQL >元素8. 小结…

LVS负载均衡群集

企业群集应用 1. 群集的含义 1.1Cluster&#xff0c;群集&#xff0c;集群 2.1由多台主机构成&#xff0c;但对外&#xff0c;只表现为一个整体&#xff0c;只提供一个访问入口&#xff08;域名或ip地址&#xff09;&#xff0c; 相当于一台大型计算机 2.问题出现 互联网…

Sentinel的学习

1、Sentinel控制台的下载 下载地址&#xff1a;https://github.com/alibaba/Sentinel/releases/tag/1.8.3 2、Sentinel控制台的启动 java -jar sentinel-dashboard-1.8.3.jar3、访问 浏览器输入&#xff1a;localhost:8080 账号密码&#xff1a; sentinel/sentinel 4.sprin…

SARScape中用sentinel-1数据做SBAS-InSAR完整流程(1/2)

SARScape中用sentinel-1数据做SBAS-InSAR完整流程1 SABA-InSAR原理简述2 数据采集和预设2.1 SAR数据采集2.2 DEM数据下载与放置2.3 精密轨道数据下载与放置2.4 制作研究区范围矢量2.5 SARscape Preferences预设3 SAR数据预处理3.1 导入数据3.2 optional files设置3.3 参数设置4…

【Git】Git使用的三个场景总结 | 远程仓库到本地 | 本地获取git仓库 | 远程仓库与本地相连接

&#x1f4ad;&#x1f4ad; ✨&#xff1a; git使用的三个场景总结 | 远程仓库到本地 | 本地获取git仓库 | 远程仓库与本地相连接   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;&#xff1a;学习的过程就是不断接触错误&#xff0c;不断提升自己&#xff0c…

Linux 卸载zabbix图文教程

Linux 卸载zabbix图文教程前言1.停止zabbix服务2.卸载zabbix服务2.1查找zabbix所有被安装的rpm包2.2卸载zabbix服务2.3删除所有与zabbix相关的文件&#xff08;配置项等&#xff09;3.卸载数据库3.1查找mariadb所有被安装的rpm包&#xff0c;并删除3.2删除mysql相关配置文件4.卸…

Source Insight4.0中文注释乱码解决方案

一、Source Insight软件介绍 Source Insight是一个面向项目的编程编辑器、代码浏览器和分析器&#xff0c;可帮助您在工作和计划​​时分析代码&#xff0c;具有针对 C/C、C#、Java、Objective-C 等的内置动态分析&#xff0c;深受众多嵌入式软件开发者的喜爱。 二、中文乱码…

复旦-华盛顿大学EMBA 二十年20人丨徐欣:从外企转战民企的变身

复旦大学-华盛顿大学EMBA20周年校友系列访谈。      2008年堪称转折之年&#xff0c;中国举行北京奥运会向全世界展示“和而不同”的理念&#xff0c;入世7年让中国在贸易、金融领域与全球市场紧密相连&#xff0c;一大批最优秀的中国民营企业也加速踏上全球化之路。    …

Web APIs:PC 端网页特效--动画函数封装

动画原理 核心原理&#xff1a;通过定时器 setInterval() 不断移动盒子位置 实现步骤&#xff1a; 1. 获得盒子当前位置 2. 让盒子在当前位置加上1个移动距离 3. 利用定时器不断重复这个操作 4. 加一个结束定时器的条件 5. 注意此元素需要添加定位&#xff0c;才能使用e…

【C语言】三子棋小游戏

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f40c; 个人主页&#xff1a;蜗牛牛啊 &#x1f525; 系列专栏&#xff1a;初出茅庐C语言 ☀️ 学习格言&#xff1a;眼泪终究流不成海洋&#xff0c;人总要不断成长&am…

Selenium基础 — iframe表单操作

1、什么是iframe表单 实际上就是HTML页面中使用iframe/frame标签&#xff0c;是在当前页面中引用了其他页面的链接&#xff0c;真正的页面数据并没有出现在当前页面源码中&#xff0c;但是在浏览器中我们时看到的。简单理解可以使页面中开了一个窗口显示另一个页面。 我们在We…

谷粒商城-支付业务

目录 商城业务-支付-支付宝沙箱&代码 商城业务-支付-RSA、加密加签、密钥等 商城业务-支付-内网穿透 商城业务-订单服务-整合支付前需要注意的问题 商城业务-订单服务-整合支付 商城业务-订单服务-支付成功同步回调 商城业务-订单服务-订单列表页渲染完成 商城业务…

网络请求+基于Node.js的WebSocket

目录 前言 网络访问配置 1.配置流程 注意事项 使用限制 网络请求详情API wx.request请求数据API ​编辑 wx.uploadFile文件上传API wx.downloadFile文件下载API WebSocket会话API 基于Node.js的WebSocket 为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢&…

git命令记不住?可视化git操作平台Sourcetree入门教程

1、为什么要用Sourcetree 在应届生在参加实习或者工作的时候&#xff0c;往往需要配置各种各样的环境&#xff0c;git肯定是程序员必不可少的分布式版本控制系统&#xff0c;但刚出来工作时往往对git代码不熟悉&#xff0c;老是会忘掉一些命令&#xff0c;所以笔者在此推荐一个…

算法《第四版》笔记整理

算法第四版 先导例子&#xff1a;动态连通性 - 书中1.5 知识点&#xff1a;并查集-一种用于解决动态连通性问题的算法 描述&#xff1a;对于N个对象&#xff0c;有两种操作&#xff1a;1.连接两个对象 2.判断两个对象是否存在连接路径 如巨大的连通性问题&#xff1a; 在分析…

【力扣刷题】Day32——单调栈专题

文章目录单调栈1.每日温度2.下一个更大元素 I3.下一个更大元素II4. 接雨水5.柱状图中最大的矩形单调栈 单调栈基础知识回顾&#xff1a;单调栈与单调队列_塔塔开!!!的博客-CSDN博客_单调栈 单调队列 单调栈一般模板&#xff1a; int[] stk new int[N] //Stack<Integer>…

倒排索引-字符串相似匹配(结巴分词、中文转拼音)

工作中&#xff0c;遇到有两个不同的系统&#xff0c;两个系统中有相同的功能&#xff0c;维护一个主播的名称。现在准备将两个系统的主播合并到一起。因为主播名称可能由不同的人维护的&#xff0c;他们也不知道主播的真实姓名&#xff0c;比如一条小团团&#xff0c;可能维护…

香橙派3LTS部署ROS2阿克曼开源平台

1.系统镜像下载 这里我们需要安装ROS2的humble版本&#xff0c;需要ubuntu 22.04版本的系统。 香橙派镜像下载&#xff1a;http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-3-LTS.html 点击Ubuntu镜像&#xff0c;选择jamm…

【linux】进程概念详述

进程概念一、冯诺依曼系统二、操作系统2.1 OS层次图2.2 操作系统的意义2.2.1 系统调用与库函数的区别2.3 管理的理解三、进程3.1 进程的概念3.2 描述进程-PCB3.3 进程和程序3.4 PCB内容3.4.1 查看进程3.4.2 标识符3.4.3 状态3.4.4 程序计数器3.4.5 记账信息3.4.6 上下文信息❗️…

1.极限与连续-——“机器学习中的数学”

1.通过集合相等来讲解什么是映射关系 上面问的这个问题&#xff08;2N N2&#xff09;说明了什么&#xff1f; ——两个无穷集合&#xff0c;如果能找到一种对应关系&#xff08;映射关系&#xff09;&#xff0c;那么我们就可以说这两个集合是等价的。 数列的极限就是趋势 …