女同 t p [翻译]OWASP 安卓测试指南(v1.2 - 14 May 2020)节选-外文翻译-看雪-安全社区|安全招聘|kanxue.com
原文连结:平台轮廓https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05a-platform-overviewAndroid 基础安全测试https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05b-basic-security_testingAndroid 反逆向驻扎https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05j-testing-resiliency-against-reverse-engineering女同 t p
本节从架构的角度先容Android平台。 照看了以下五个重要领域:
Android 是谷歌基于 Linux 开发的开源平台,它充任出动操作系统(OS)。如今,该平台是多样当代手艺的基础,如手机、平板电脑、可衣服手艺、电视和其他"智能"开荒。典型的 Android 版块具有一系列预装("内置")的应用程序,并援救通过 Google Play 商店和其他市集装配第三方应用。
Android 的软件栈由几个不同的层构成。每层都界说了接口并提供特定的就业。
Android 软件栈
在最低层,Android 是基于 Linux 内核的变种。 在内核之上,硬件抽象层(HAL)界说了用于与内置硬件组件进行交互的模范接口。几种HAL 的罢了打包在了分享库模块中,Android 系统需要时就会调用。这是允许应用程序与开荒的硬件进行交互的基础,举例女同 t p,它允许一个内置的电话应用程序使用开荒的麦克风和扬声器。
Android 应用程序平时使用 Java 编写并编译为 与传统的 Java 字节码有些不同的 Dalvik 字节码。起始将 Java 代码编译为 .class 文献,然后使用 dx 器具将 JVM 字节码诊疗为 Dalvik 的 .dex 神态,这么就创建了 Dalvik 字节码。
Java vs Dalvik
面前版块的安卓在 Android 运行时(ART)上推论此字节码。ART 是安卓原始运行时 Dalvik 杜撰机的后继者。 Dalvik 和 ART 之间的重要区别在于字节码的推论步地。
在Dalvik中,字节码在推论时诊疗为机器码,这一过程称为即时(JIT)编译。JIT编译会对性能产生不利的影响:每次推论应用程序时都必须进行编译。为了提高性能,ART 引入了提前(AOT)编译。顾名念念义,应用会在初次推论之前进行预编译。预编译的机器代码会用于扫数后续的推论。AOT 将性能提高了两倍,同期诽谤了功耗。
Android 应用程序不可平直拜谒硬件资源,而况每个应用程序都运行在我方的沙盒中。这允许对资源和应用程序进行精准的戒指:举例,崩溃的应用程序不会影响开荒上运行的其他应用程序。同期,Android 运行时会戒指分拨给应用程序的最大系统资源数量,防护任何一个应用程序驾驭过多的资源。
尽管 Android 操作系统是基于 Linux,但它并不像其他类 Unix 系统那样罢了用户帐户。在 Android 中 Linux 内查对应用沙盒的多用户援救:除了少数的例外,每个应用程序都像运行在一个单独的 Linux 用户下,灵验地与其他应用和操作系统的剩余部分烦扰。
文献 system / core / include / private / android_filesystem_config.h(_r6/xref/system/core/include/private/android_filesystem_config.h)包含了一个系统进程分拨的预界说用户和组的列表。装配其他应用程序时,会添上它们的 UID(userID)。更多详细信息,参阅 Bin Chen 对于 Android 沙箱的博客著作(https://pierrchen.blogspot.com/2016/09/an-walk-through-of-android-uidgid-based.html)。
举例,Android 7.0(API 品级24)界说了以下系统用户:
安卓从 Android 2.3.4(API 品级10)滥觞援救开荒加密,而后发生了一些大的变化。Google 强制扫数的开荒运行 Android 6.0(API 品级23)或援救存储加密的更高版块,有些低端开荒被豁免,因为这会严重影响性能。鄙人面各节中,你不错找到商量开荒加密过火算法的信息。
Android 5.0(API 品级 21)及更高版块援救全盘加密。这种加密使用用户开荒密码保护的单个密钥来加密妥协密 userdata 分区。面前这种加密已被弃用,并以为应尽可能使用基于文献的加密。全盘加密具有一些症结,举例,如果用户未输入解锁密码,则重启后将无法接听电话或莫得操作警报。
Android 7.0(API 品级24)援救基于文献的加密。基于文献的加密允许使用不同的密钥对不同的文献进行加密,以便不错逍遥解密它们。援救这种加密步地的开荒也援救 Direct Boot 模式,Direct Boot 模式下开荒不错在用户未解锁开荒时拜谒警报或援手就业等能。
AES 在大多数当代 Android 开荒上用于存储加密。现实上,AES 照旧成为一种庸碌使用的算法,最新的处理器罢了存专用的指示集来提供硬件加快加密与解密操作,举例带有 Cryptography Extensions 的 ARMv8 或具有AES-NI 彭胀的 x86。但是,并非扫数开荒都能实时使用 AES 进行存储加密。尤其是运行Android Go 的低端开荒。这些开荒平时使用低端处理器,举例 ARM Cortex-A7,它们莫得硬件加快的 AES。
Adiantum 是由 Google 的 Paul Crowley 和 Eric Biggers 遐想的密码结构,用于填补那些不不错至少 50 MiB/s 速率运行 AES 的开荒的空缺。Adiantum 仅依赖于加法、移位旋转和异或,扫数处理器都援救这些操作,与使用 AES 比拟,低端处理器的加密速率是 AES 的4倍,解密速率是 AES 的5倍。
Adiantum是一种新的密码,但只须 ChaCha12 和 AES-256 被以为是安全的,它等于安全的。它的遐想者莫得创建任何新的加密基元,而是依赖于其他知名的、经过深刻研究的基元来创建一个新性能的算法。
Adiantum 适用于 Android 9(API 品级 28)和更高版块。Linux 内核5.0及更高版块援救该功能,而内核4.19、4.14 和4.9需要修补。Android 不向应用程序开发东谈主员提供使用 Adiantum 的API。这个加密将由 ROM 开发东谈主员或开荒供应商但愿在不铁心低端开荒性能的情况下提供全磁盘加密时沟通并实施。在撰写本文时,尚无群众密码库罢了此加密可在 Android 应用程序上使用。应该防范的是,AES 在具有 AES指示集的开荒上运行得更快,在这种情况下热烈不建议使用 Adiantum。
Android 包含许多不同的功能,试图使坏心应用程序更难潜逃出沙盒。由于应用程序在您的开荒上灵验地运行代码,很进军的极少等于,即使应用程序自己不确切但也不错安全地推论。以下各节解释了哪些缓解门径不错防护应用程序滥用间隙。需要防范的是,操作系统从来都不是 100% 安全的,即使选拔了这些缓解门径,新的间隙也仍会依期被发现。
安全强化的 Linux(SELinux)使用强制拜谒戒指(MAC)系统来进一步锁定哪些进程不错拜谒哪些资源。每个资源都有一个标签,其式样是 user:role:type:mls_level,它界说了哪些用户不错对其推论哪种类型的操作。举例,一个进程可能只可读取文献,而另一个进程不错裁剪或删除该文献。这么,通过使用最小特权原则,易受障碍的进程更难通过权限提高或内网漫游被间隙愚弄。
商量更多信息,请拜谒 Android 安全网站(https://source.android.com/security/selinux)。
自 Android 4.1(API 品级 15)以来,地址立时化(ASLR)就已成为 Android 的一部分,它是防护缓冲区溢出障碍的模范保护门径,这么不错确保将应用程序和操作系统都加载到立时的内存地址,从而很难获取特定的内存区域或库的正确地址。在 Android 8.0(API 品级26)中,也为内核罢了了这种保护(KASLR)。仅当不错将应用程序加载到内存中的立时位置时才不错使用ASLR保护,这由应用程序的位置无关可推论文献(PIE)标志指示。从 Android 5.0(API 品级 21)滥觞,不再援救未启用 PIE 的原生库。终末,数据推论保护(DEP)不错防护代码在堆栈和堆上推论,这也不错用来防护缓冲区溢露马脚。
商量更多信息,请拜谒 Android 开发者博客(https://android-developers.googleblog.com/2016/07/protecting-android-with-more-linux.html)。
Android 应用程序不错包含用C或C ++编写的本机代码。这些编译的二进制文献不错通过 Java 腹地接口(JNI)绑定与 Android 运行时通讯,也不错通过系统调用与 OS 通讯。某些系统调用没用被罢了,或者不应由普通应用程序调用。由于这些系统调用平直与内核通讯,因此它们是间隙愚弄开发东谈主员的主要场地。在 Android 8(API 品级26)上,Android 引入了对扫数基于 Zygote 的进程(即用户应用程序)的 Secure Computing(SECCOMP)过滤器的援救, 这些过滤器将可用的系统调用限定为 bionic 公开的系统调用。
商量更多信息,请拜谒 Android 开发者博客(https://android-developers.googleblog.com/2017/07/seccomp-filter-in-android-o.html)。
Android 应用程序通过与提供高等 Java API 的抽象层即 Android 框架层与系统就业进行交互,这些就业大多数是通过通例的 Java 方法来调用的,并诊疗为对在后台运行的系统就业的 IPC 调用。系统就业的实例有:
框架层还提供了常见的安全功能,举例加密。
每个新的 Android 版块都会转变API范例。重要的间隙树立和安全补丁平时也适用于早期的版块,在撰写本文时,援救的最旧的 Android 版块是 Android 8.1(API 品级27),面前的 Android 版块是Android 10(API 品级29)。
值得防范的API版块:
Android 愚弄 Linux 用户管束来烦扰应用程序。但 这种方法不同于传统 Linux 环境下多个应用程序常由合并用户运行的用户管束用法。安卓为每个 Android 应用程序创建了一个唯独的 UID,并在单独的进程中运行该应用程序。因此,每个应用程序只可拜谒我方的资源,此保护由 Linux 内核强制推论。
平时,为应用程序分拨的 UID 在10000和99999之间。Android 应用程序会根据他们的 UID 收到一个用户名。举例,UID 为10188的应用程序收到用户名u0_a188。 如果授予了应用程序恳求的权限,则会将相应的组 ID 添加到该应用程序的进程中。举例,底下的应用程序的用户 ID 是10188,它属于组 ID 3003(inet),该组与 android.permission.INTERNET 权限干系。id 敕令的输出如下所示。
组ID和权限之间的关系鄙人面的文献中界说:
frameworks/base/data/etc/platform.xml(_r6/xref/frameworks/base/data/etc/platform.xml)
应用程序在 Android 的应用沙盒中推论,应用沙盒不错将应用程序的数据和代码推论与开荒上的其他应用程序烦扰,这种烦扰增多了一个安全层。
新应用程序装配后会创建一个根据该应用程序包定名的新目次,在以下旅途:/data/data/[package-name]。此目次保存了应用程序的数据。Linux 目次权限会被设立,以便只可使用应用程序的唯独 UID 来读取和写入目次。
Sandbox
咱们不错通过检验 /data/data 文献夹中的文献系统权限来说明这极少。举例,咱们不错看到 Google Chrome 和 Calendar 都分拨了一个目次,并在不同的用户帐户下运行:
但愿我方的应用程序都使用一个分享沙盒的开发东谈主员不错避让沙盒。当两个应用使用调换的文凭进行签名并显式分享调换的用户 ID(在它们的 AndroidManifest.xml 文献中包含 sharedUserId)时,每个应用都不错拜谒对方的数据目次。请参阅以下示例,在 NFC 应用中罢了此宗旨:
Zygote 进程在 Android 开动化时期启动。 Zygote 是用于启动应用程序的系统就业。Zygote 进程是一个包含应用程序需要的扫数中枢库的“基本”进程,其中。启动后,Zygote 大开套接字 /dev/socket/zygote 并监听来自腹地客户端的联结。给与到联结后,它将派生一个新进程,然后该进程将加载并推论应用专用代码。
在 Android 中,应用程序进程的生涯期由操作系统戒指。当启动应用程序组件而况该应用程序尚未运行任何其他组件时,一个新的 Linux 进程会被创建。当不再需要进程或需要回收内存以运行更进军的应用程序时,Android 可能杀死该进程。 进程是否杀死主要和用户与进程交互的景况商量。平时,进程可能处于四种景况之一。
前台进程(举例,在屏幕顶部运行的行动或正在运行的播送给与器)
可见进程是用户阻滞到的进程,因此隔断该过程将对用户体验产生显着的负面影响。一个例子是运行一个用户在屏幕上可见但在前台不可见的行动。
就业进程是托管使用 startService 方法启动的就业的进程。尽管这些进程对用户来说不是平直看到的,但是它们平时是用户怜惜的事情(举例,后台相聚数据的上传或下载),因此,除非莫得弥漫的内存来保留扫数前台和可见进程,系统将永恒保持这些进程运行。
缓存进程是面前不需要的进程,因此系统不错在需要内存杀死它。应用程序必须罢了对多个事件作念出反应的回调方法。举例,在初次创建应用进程时会调用 onCreate 处理程序,其他回调方法包括 onLowMemory,onTrimMemory 和 onConfigurationChanged。
Android 应用程序能以两种式样发布:AAndroid Package Kit(APK)文献或Android App Bundle(.aab)。Android App Bundle 提供了应用程序需要的扫数资源,但推迟了 APK 的生成及向 Google Play 的签名。App Bundles 是经过签名的二进制文献,包含有应用程序的代码在几个模块中。基本模块包含应用程序的中枢,不错通过多样包含应用程序的新的功能的模块进行彭胀,这在 app bundle 开发者文档(https://developer.android.com/guide/app-bundle)中有进一步的说明。如果您有一个Android App Bundle,最好使用 Google 的bundletool(https://developer.android.com/studio/command-line/bundletool)敕令行器具来构建未签名的APK,以便使用 APK 上的现存器具。你不错通过运行以下敕令从 AAB 文献创建 APK:
如果你想创建已签名的 APK,准备部署到测试开荒,请使用:
咱们建议你同期测试带有和不带有附加模块的 APK,以便了了附加模块是否引入和(或)树立了基本模块的安全问题。
每个应用程序都有一个 Android Manifest 文献,该文献以二进制 XML 神态镶嵌内容。这个文献的模范称呼是 AndroidManifest.xml,它位于应用程序的 Android Package Kit(APK)文献的根目次中。
Manifest 文献描画了应用程序的结构、的组件(行动、就业、内容提供者和 intent 给与者)和恳求的权限。它还包含通用的应用程序的元数据,比如应用程序的图标、版块号和主题。该文献可能会列出其他信息,比如兼容的 API(最小、场地和最大的SDK版块)和不错装配的存储类型(外部或里面)(https://developer.android.com/guide/topics/data/install-location.html)。
底下是一个清单文献的示例,包括包名(惯例是反向的URL,但任何字符串都不错经受)。它还列出了应用程序版块,干系 SDK,需要的权限,给出了内容提供者,使用 intent 过滤器的播送给与器和应用程序过火行动的描画:
可用清单选项的齐备列表在官方 Android Manifest file 文档(https://developer.android.com/guide/topics/manifest/manifest-intro.html)中。
Android 应用程序由几个高等组件构成。主要构成有:
扫数这些元素都是由 Android 操作系统以 API 中预界说类的式样提供的。
Activity 构成了应用程序的可见部分。每个页面都有一个行动,是以一个有三个不同页面的应用程序会罢了三个不同的行动。行动通过袭取 Activity 类来声明,包含扫数用户界面元素:碎屑、视图和布局。
每个行动都需要在 Android 清单中使用以下语法声明:
未在清单文献中声明的行动不会被骄贵,试图启动它们将激勉特别。
和应用程序一样,行动也有我方的生命周期,而况需要监视系统的变化来处理它们。行动不错处于以下景况:行动、暂停、住手和不行动,这些景况由 Android 操作系统管束。对应的, 行动不错罢了以下事件管束器:
应用程序不错不显式地罢了合有的事件管束器,在这种情况下会选拔默许的操作。平时,至少 onCreate 管束器会被应用程序开发东谈主者重写,这是大多数用户界面组件声明和开动化的步地。当资源(如相聚联结或数据库联结)必须显式开释,或者当应用程序关闭时必须推论特定操作时,onDestroy 可能被重写。
Fragment 暗示行动中的一个步履或用户界面的一部分。Android 在 Honeycomb 3.0 版块 (API 品级11)中引入了碎屑。
碎屑用于封装界面的各个部分,以促进可重用性和适当不同屏幕大小。碎屑是自治的实体,它们包含了扫数需要的组件(它们有我方的布局、按钮等等)。关联词,它们必须与行动集成才能灵验:碎屑不可单独存在。它们有我方的生命周期,与罢了它们的行动的生命周期干系联。
因为碎屑有我方的生命周期,是以碎屑类包含不错重新界说和袭取的事件管束器。这些事件管束器包括 onAttach、onCreate、onStart、onDestroy 和 onDetach。其他一些例子,读者应该参考 Android Fragment 范例(https://developer.android.com/guide/components/fragments)以获取更多细节。
通过袭取 Android 提供的 Fragment 类,不错莽撞罢了碎屑:
Java 示例:
Kotlin 示例:
碎屑不需要在清单文献中声明,因为它们依赖于行动。
为了管束碎屑,行动不错使用碎屑管束器 (FragmentManager 类)。这个类使得查找、添加、删除和替换干系的碎屑变得很容易。
碎屑管束器不错通过以下步地创建:
Java 示例:
Kotlin 示例:
碎屑不一定有用户界面,它们不错成为管束和应用程序用户界面干系的后台操作的一种便捷而高效的步地。一个片断不错被声明为持久的,这么即使行动被浮松,系统仍然保持它的景况不变。
咱们照旧了解到,每个 Android 进程都有我方的沙箱地址空间。进程间通讯机制允许应用程序安全地交换信号和数据。Android 的 IPC 不依赖默许的 Linux IPC 器具,而是基于 Binder,即 OpenBinder 的自界说罢了。大多数 Android 系统就业和扫数高等 IPC 就业都依赖 Binder。
Binder 这个词有好多不同的含义,包括:
Binder 驱动程序:内核级驱动程序
Binder 合同:用于与 Binder 驱动程序通讯的基于 ioctl 的初级合同
IBinder 接口:Binder 对象罢了的界说致密的步履
Binder 对象:IBinder 接口的通用罢了
Binder 就业:Binder 对象的罢了;举例,位置就业和传感器就业
Binder 客户端:使用 Binder 就业的对象
Binder 框架包括客户机-就业器通讯模子。为了使用 IPC,应用程序在代理对象中调用 IPC方法。代理对象透明地将调用参数打包并将事务发送到 Binder 就业器,Binder 就业器罢了为一个字符驱动程序(/dev/Binder)。就业器持有一个线程池,用于处理传入恳求并将讯息传递给场地对象。从客户端应用程序的角度来看,扫数这些都像是一个通例的方法调用,但艰深的使命都是由 Binder 框架完成的。
Binder 轮廓
Binder 轮廓图片来源:Android Binder by Thorsten Schreiber(https://www.nds.ruhr-uni-bochum.de/media/attachments/files/2011/10/main.pdf)
允许其他应用程序绑定的就业称为绑定就业,这些就业必须向客户机提供IBinder接口。开发东谈主员使用 Android 接口描画符话语(AIDL)为费力就业编写接口。
Servicemanager 是一个系统看管进程,它管束系统就业的注册和查找。它爱护扫数注册就业的称呼/Binder对列表。使用 addService 添加就业,使用 android.os.ServiceManager 中的静态方法 getService 通过称呼获取就业:
Java 示例:
Kotlin 示例:
你不错通过 service list 敕令查询系统就业的列表。
Intent 讯息传递是建立在 Binder 之上的异步通讯框架。此框架允许点对点和发布-订阅讯息传递。Intent是一个讯息传递对象,不错用来恳求另一个应用组件的动作。Intent 以几种步地促进组件间的通讯,底下是三个基本用例:
开启行动行动暗示应用程序中的一个界面。你不错通过将 intent 传递给 startActivity 来启动行动的一个新的实例。Intent 描画了行动并佩戴必要的数据。
开启就业就业是在后台推论操作的组件,莫得用户界面。在 Android 5.0(API 品级21)及更高版块中,你不错使用 JobScheduler 启动就业。
传递播送播送是任何应用程序都能给与到的信息。系统为系统事件传递播送,包括系统素养和充电开动化。你不错通过传递 intent 给 sendBroadcast 或 sendOrderedBroadcast,来将一个播送传递给其他应用程序。
Intent 有两种类型。显式 intent 通过将要启动的组件定名(完全放手类名)。举例:
Java 示例:
Kotlin 示例:
隐式 intent 被发送给操作系统,以对一组给定的数据(底下示例中的OWASP网站的URL)推论一个给定的操作,由系统决定哪个应用程序或类将推论相应的就业。举例:
Java 示例:
Kotlin 示例:
Intent 过滤器是 Android Manifest 文献中的一个抒发式,它指定组件想要给与的 intent 类型。举例,通过为行动声明一个 intent 过滤器,你就不错让其他的应用以某种 intent 平直启动你的行动。一样地,如果莫得为行动声明任何 intent 过滤器,行动只可被一个显式 intent 启动。
Android 使用 intent 向应用程序播送讯息(如回电或短信)、进军的电源信息(如电板电量不及)和相聚变化(如联结中断)。额外的数据不错添加到 intent(通过 putExtra/getExtras)。
底下是操作系统发送的 intent 的一个苟简列表。扫数常量都在 Intent 类中界说,扫数这个词列表在官方的 Android 文档中:
为了提高安全性和奥秘性,腹地播送管束器用于在应用程序中发送和给与 intent,而不可将 intent 发送到操作系统的其他部分。这对于确保明锐和独到数据不会离开应用程序的畛域(举例地舆位置数据)极度有用。
播送给与器是允许应用程序给与来自其他应用程序和系统自己的见知的组件。有了它们,应用程序不错对事件(里面的、由其他应用程序发起的或者由操作系统发起的)作出反应,它们平时用于更新用户界面、启动就业、更新内容和创建用户见知。
有两种方法不错让系统知谈一个播送给与器。一种方法是在 Android Manifest 文献中声明它,清单中应该指定播送给与器和 intent 过滤器之间的关联,以指示给与器要监听的动作。
一个播送给与器与 intent 过滤器在清单中的声明例子:
请防范,在本例中,播送给与器不包括 android:exported 属性。因为至少界说了一个过滤器,是以默许值将被设立为“true”。如果莫得任何过滤器,它将被设立为“false”。
另一种方法是在代码中动态创建给与器,给与器不错使用方法 Context.registerReceiver 注册。
一个动态注册播送给与器的例子:
Java 示例:
Kotlin 例子:
需要防范的是,当一个 intent 被发出时,系统会自动启动一个带有干系已注册给与器的应用程序。
根据播送轮廓(https://developer.android.com/guide/components/broadcasts),如果不是专门针对应用程序,播送会被以为是“隐式的”。在给与到一个的隐式播送后,Android 会列出扫数在其过滤器中注册了特定动作的应用程序。如果有多个应用程序注册了调换的操作,Android 会辅导用户从可用的应用程序列表中进行弃取。
播送给与器的一个兴致功能是不错对它们进行优先级排序;通过这种步地,intent 将根据优先级被传递给扫数授权的给与者。优先级不错通过清单中的 android:priority 属性来分拨,也不错通过 IntentFilter.setPriority 方法编程分拨。但是请防范,具有调换优先级的给与者将以率性章程运行(https://developer.android.com/guide/components/broadcasts.html#sending-broadcasts)。
如果你的应用不应该跨应用程序发送播送,不错使用腹地播送管束器(LocalBroadcastManager)。它们不错用来确保只给与来自里面应用程序的 intent,而来自其他应用程序的 intent 将被丢弃。这对于提高应用程序的安全性和效果极度有用,因为不波及进程间通讯。但是请防范 LocalBroadcastManager 类已不推选使用(https://developer.android.com/reference/androidx/localbroadcastmanager/content/LocalBroadcastManager.html),谷歌建议使用 LiveData (https://developer.android.com/reference/androidx/lifecycle/LiveData.html)等替代方法。
商量播送给与器的更多安全留隐衷项,请参见安全留隐衷项和最好作念法(https://developer.android.com/guide/components/broadcasts.html#security-and-best-practices)。
根据后台优化(https://developer.android.com/topic/performance/background-optimization),针对 Android 7.0(API 品级24)或更高的应用不再给与 CONNECTIVITY_ACTION 播送,除非使用 Context.registerReceiver() 注册播送给与器。系统也不再发送 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 播送。
根据后台推论限定(https://developer.android.com/about/versions/oreo/background.html#broadcasts),针对Android 8.0(API 品级26)及以上的应用,在隐式播送例外情况中列出的以外(https://developer.android.com/guide/components/broadcast-exceptions),不可在其清单中注册隐式播送给与器。在运行时通过调用 Context.registerReceiver 创建播送给与器不受此限定的影响。
根据系统播送发生的转变,从Android 9(API 品级28)滥觞,NETWORK_STATE_CHANGED_ACTION 播送不再接登第户的位置信息或个东谈主身份信息。
Android 使用 SQLite 来不时化存储数据:与 Linux 一样,数据存储在文献中。SQLite 是一种轻量级、高效的开源关统统据存储手艺,不需要太多的处理能力,这使得它极度适持机使用。SQLite 有包含特定类(Cursor, ContentValues, SQLiteOpenHelper, ContentProvider, ContentResolver 等等)的齐备可用 API 。SQLite 不动作单独的进程运行的,它是应用程序的一部分。默许情况下,属于给定应用程序的数据库只可由该应用程序拜谒。但是,内容提供者提供了一种很棒的来抽象数据源机制(包括数据库和平面文献),它们还提供了一种模范而灵验的机制来在应用(包括腹地应用)之间分享数据。要让其他应用程序拜谒内容提供者,需要在分享它的应用程序的清单文献中显式地声明内容提供者。只须莫得声明内容提供者,它们就不会被导出,只可由创建它们的应用程序调用。
内容提供者通过 URI 寻址决议罢了的:它们都使用了 content:// 模子。不管源的类型是什么(SQLite数据库、平面文献等),寻址决议都是调换的,因此对源进行了抽象,并为开发东谈主员提供了唯独的决议。内容提供者提供了扫数通例的数据库操作:创建、读取、更新、删除。这意味着任安在清单文献中领有适当权限的应用程序都不错操作其他应用程序的数据。
就业是 Android OS 的组件(基于 Service 类),它们在后台推论任务(数据处理、启动 intent 和见知等),而不提供用户界面。就业是用来历久运行进程的,它们的系统优先级低于行动应用程序,而高于不行动应用程序。因此,当系统需要资源时,它们不太可能被杀死,而况不错将它们配置为在有弥漫的可用资源时自动重启,这使得就业极度妥贴运行后台任务。请防范,就业和行动一样,都是在主应用程序线程中推论的。就业不会创建我方的线程,也不会在单独的进程中运行,除非另行指定。
由于 Android 应用程序是装配在沙箱中,率先无法拜谒用户信息和系统组件(比如录像头和麦克风),Android 为应用程序不错恳求的特定任务提供了一套预界说的权限。举例,如果你想让你的应用程序使用手机的录像头,你必须恳求 android.permission.CAMERA 权限。在Android 6.0(API 品级23)之前,应用程序恳求的扫数权限都在装配时授予。从 API 品级23滥觞,用户只可在应用程序推论时期甘心一些权限恳求。
Android 的权限是根据其提供的保护级别进行排序的,分为四种不同的类别:
Normal:较低的保护级别。 它使应用程序不错拜谒烦扰的应用程序级功能,而对其他应用程序、用户或系统的风险最小。它是在应用装配过程中授予的,而况是默许的保护级别。举例:android.permission.INTERNET
Dangerous:此权限允许应用程序推论可能影响用户阴私或用户开荒正常运行的操作。装配时期可能不会授予此级别的权限,用户必须决定应用程序是否应该有这个权限。举例:android.permission.RECORD_AUDIO
Signature:只须在恳求应用程序与声明该权限的应用程序使用调换的文凭签名时,才会授予此权限。如果签名匹配,则自动授予权限。举例:android.permission.ACCESS_MOCK_LOCATION
SystemOrSignature:此权限仅授予系统映像中镶嵌的应用程序或使用与声明该权限的应用调换的文凭进行签名的应用程序。举例:android.permission.ACCESS_DOWNLOAD_MANAGER
应用程序不错通过在其清单中包含 `
<uses-permission />` 标签来恳求正常、危急和签名保护级别的权限。底下的例子是一个恳求读取短信权限的 AndroidManifest.xml 示例:
应用程序不错向系统上装配的其他应用程序公开功能和内容。为了限定对我方组件的拜谒,不错使用任何 Android 的预界说权限(https://developer.android.com/reference/android/Manifest.permission.html)或界说我方的权限,使用元素 <permission> 声明一个新的权限。底下的例子展示了一个应用程序的权限声明:
上头的代码界说了一个新的权限 com.permissions.sample.ACCESS_USER_INFO,其保护级别为 Signature。任何受此权限保护的组件只可由调换开发者文凭签名的应用程序拜谒。
Android组件的强制权限
Android 组件不错使用权限机制来保护它们的接口。不错通过在 AndroidManifest.xml 中的相应组件标签中添加属性 android:permission 来在行动、就业和播送给与器使用强制权限。
内容提供者有一些不同,它们援救一组单独的权限,使用内容 URI 来读取,写入和拜谒内容提供者。
一朝应用程序奏凯开发,下一步等于发布分享给其他东谈主。关联词,应用程序不可浮浅地添加到商店并分享,它们必须起始签名,该加密签名动作应用程序开发者摈弃的可考证标记。它识别应用程序的作家,并确保应用程序自率先发布以来莫得被修自新。
在开发过程中,应用程序使用自动生成的文凭进行签名,此文凭内容上是不安全的而况仅用于调试。大多数商店不经受这种文凭进行发布,因此,必须创建具有更安全的特质的文凭。当一个应用程序装配在 Android 开荒上时,包管束器会确保它是用包含在相应 APK 中的文凭进行的签名。如果文凭的公钥与用于开荒上任何其他 APK 签名的密钥相匹配,那么新的 APK 可能与已存在的 APK 分享一个 UID。这促进了来自单个供应商的应用程序之间的交互,或者,指定的安全权限 对 Signature 保护级别来说是可能的,这将限定对使用调换密钥签名的应用程序的拜谒。
Android 援救三种应用签名决议。从 Android 9(API level 28)滥觞,APK 不错通过 APK 签名决议 v3 、APK 签名决议 v2 或 JAR 签名(v1 决议)进行考证。对于 Android 7.0 (API 品级24)及以上版块,不错通过 APK 签名决议 v2 或 JAR 签名(v1决议)对 APK 进行考证。为了向后兼容,APK 不错使用多种签名决议进行签名,以使应用程序在较新的和较旧的 SDK 版块上都运行。旧的平台会忽略 v2 签名,只考证 v1 签名(https://source.android.com/security/apksigning/)。
应用程序签名的原始版块将签名的 APK 罢了为模范的签名 JAR,它必须包含 META-INF/MANIFEST.MF 中的扫数条件,扫数文献都必须使用一个群众文凭签名,这个决议不保护 APK 的某些部分,比如 ZIP 元数据。该决议的症结是 APK 考证者在应用签名之前需要对不确切的数据结构进行处理,而况考证者会丢弃数据结构不包含的数据。此外,APK 考证者必须解压扫数压缩文献,这需要多数的时辰和内存。
在 APK 签名决议中,对齐备的 APK 进行哈希和签名,然后创建一个 APK 签名分块并插入到 APK 中。在考证时期,v2 决议查验扫数这个词 APK 文献的签名。这种式样的 APK 考证速率更快,而况提供了更全面的防删改保护。你不错鄙人面看到 v2 决议的 APK 签名考证过程(https://source.android.com/security/apksigning/v2#verification)。
apk 签名考证过程 v2 决议
v3 APK 签名块神态与 v2相 同。v3 将商量受援救的 SDK 版块和 proof-of-rotation 结构的信息添加到 APK 签名分块中。在 Android 9(API 品级28)及以上版块中,不错根据APK签名决议 v3、v2 或 v1 决议对 APK 进行考证。旧的平台会忽略 v3 签名尝测考证 v2 签名,然后考证v1签名。
签名数据部分中的 proof-of-rotation 属性包含一个单链表,其中每个节点都包含用于为之前版块的应用签名的签名文凭。为了罢了向后兼容性,系统会让每个节点中的文凭为列表中的下一个文凭签名,从而为每个新密钥提供字据来证明它应该像旧密钥一样确切。单独对 APK 签名照旧不可能了,因为 proof-of-rotation 结构必须使用旧的签名文凭来对新的文凭集签名,而不是一个一个地对它们签名。你不错鄙人面看到APK签名 v3 决议考证过程。(https://source.android.com/security/apksigning/v3)
apk 签名考证过程 v3 决议
Android 使用群众/独到文凭来签名 Android 应用程序(.apk文献)。文凭包含了多数的信息,就安全性而言,密钥是是最进军的信息类型。群众文凭包含用户的公钥,独到文凭包含用户的私钥。群众文凭和独到文凭是连结的。文凭是唯独的不可重壮盛成,请防范,如果一个文凭丢失了它就无法复原,因此更新任何使用该文凭签名的应用程序将变得不可能。应用程序创建者不错重用可用密钥存储库中现存的独到/群众密钥对,也不错生成新的密钥对。在 Android SDK 中,使用 keytool 敕令生成一个新的密钥对。底下的敕令创建一个密钥长度为2048位、过期时辰为7300天即20年的 RSA 密钥对。生成的密钥对存储在面前目次中的文献 'myKeyStore.jks' 中):
安全地存储你的密钥并确保它在扫数这个词生命周期中保持玄妙性是极其进军的。任何获取密钥拜谒权限的东谈主都不错将你无法戒指的内容(从而添加不安全的特质或使用基于签名的权限拜谒分享内容)更新到你的应用程序中。用户对应用程序过火开发者的信任完全基于这些文凭,因此,文凭保护和安全管束对于声誉和客户去留至关进军,密钥永远不可与其他个东谈主分享。密钥存储在不错用密码保护的二进制文献中,这么的文献被称为密钥存储库。密钥存储库的密码应该是厚实的,而况只须密钥创建者知谈。因此,密钥平时存储在开发东谈主员对其拜谒受限的专用构建机器上。Android 文凭的灵验期必须向上干系应用程序(包括更新版块的应用程序),举例,Google Play 要求文凭至少在2033年10月22日之前保持灵验。
签名过程的场地是将应用程引言件(.apk)与开发东谈主员的公钥关联起来。为了罢了这极少,开发东谈主员缠绵 APK 文献的哈希,并用他们我方的私钥加密它。第三方不错使用作家的公钥解密加密的哈希来考证应用程序的真实性(举例,应用程序照实来自宣称是发起者的用户),考证它与 APK 文献的真实哈希匹配。
许多集成开发环境(IDE)集成了应用程序签名过程让用户更容易使用。请防范,有些 IDE 在配置文献中以明文存储私钥,请仔细查验,以防其他东谈主大要拜谒这些文献并在必要时删除这些信息。通过 Android SDK(API 品级24及以上)提供的“apksigner”器具,不错从敕令行中对应用程序进行签名。它位于 [SDK-Path]/build-tools/[version]。对于 API 24.0.2 及以下版块,不错使用”jarsigner“,它是 Java JDK 的一部分。扫数这个词过程的细节不错在 Android 官方文档中找到,底下给出了一个例子来说明这极少。
在这个示例中,一个未签名的应用程序(“myUnsignedApp.apk”)将使用来自开发东谈主员密钥存储库“myKeyStore.jks”(位于面前目次中)的私钥进行签名。该应用程序将成为名为“ mySignedApp.apk”的已签名应用程序,并准备发布到商店。
在发布之前,应该永恒使用 zipalign 器具来对皆 APK 文献。这个器具在 APK 中对皆扫数未压缩的数据(如图像、原始文献和4字节畛域),这有助于在应用程序运行时鼎新内存管束。
在使用 apksigner 签名 APK 文献之前,必须使用 Zipalign。
因为 Android 生态系统是绽开的,是以不错在职何地方(你我方的网站,任何商店等等)发布应用程序。关联词,Google Play 是最知名、最受信任和最受接待的商店,Google 自己就提供这种就业。亚马逊应用商店是 Kindle 开荒的默许确切的商店。如果用户想要从不受信任的来源装配第三方应用程序,他们必须在开荒安全设立中明确允许这么作念。
安卓开荒上不错通过多种渠谈装配应用:腹地USB、Goolgle 官方应用商店(Google Play Store)或其他商店。
鉴于其他供应商可能会在应用程序真实发布前对其进行审查和批准,谷歌只会扫描已知的坏心软件签名,这将裁减发布过程的滥觞到公开应用程序可用性之间的时辰。
发布一个应用程序极度浮浅,主要操作是使签名 APK 文献可下载。在 Google Play 上,发布从创建账号滥觞,然后通过专用界面发布应用程序。详细信息不错在 Android 官方文档(https://developer.android.com/distribute/best-practices/launch)中找到。
Android 应用程序障碍面由应用程序的扫数组件构成,包括发布应用程序和援救其功能所需的援救材料。Android应用程序可能容易受到障碍如果不这么作念:
通过 IPC 通讯或 URL 决议考证扫数输入,见:通过 IPC 测试明锐功能闪现测试自界说URL决议
考证用户在输入字段中的扫数输入。
考证在 WebView 中加载的内容,见:在 Webview 中测试 JavaScript 推论测试 WebView 合同处理程序细目是否通过 Webview 公开 Java 对象
安全地与后端就业器通讯,不然易在就业器和出动应用程序之间受到中间东谈主障碍测试相聚通讯安卓相聚 API
安全存储扫数腹地数据,不从存储中加载不确切的数据,参见:Android 上的数据存储
保护我方免受环境浮松,如重新打包或其他腹地障碍,见:Android反逆向驻扎
到面前为止,你应该对 Android 应用程序的结构和部署步地有了基本的了解。在本章中,咱们将照看怎么建立一个安全测试环境,并描画您将使用的基本测试经过。本章是背面章节中照看的更详细的测试方法的基础。您不错在险些扫数运行 Windows、Linux 或 Mac OS 的机器上设立一个功能齐备的测试环境。
至少,你需要 Android Studio(附带 Android SDK)平台器具、一个模拟器和一个应用程序来管束多样 SDK 版块和框架组件。Android Studio 还附带了一个用于创建模拟器映像的 Android 杜撰开荒(AVD)管束器应用程序。确保你的系统上装配了最新的 SDK 器具和平台器具包。
此外,如果你盘算推算使用包含原生库的应用程序,你可能想要通过装配 Android NDK来完成主机设立(这在“Android 上的删改和逆向工程”一章中也会提到)。
通过 Android Studio 来管束腹地的 Android SDK 装配。在 Android Studio 中创建一个空式样并弃取 Tools -> SDK Manager 来大开 SDK Manager GUI。SDK Platform 选项卡上不错装配多个 API 品级的 SDK。最近的 API 品级为:
扫数 Android 代号、版块号和 API 品级的轮廓不错在 Android 开发者文档中找到。
已装配的 SDK 位于以下旅途:
Windows:
MacOS:
防范:在 Linux 上,你需要弃取一个SDK目次,/opt、/srv 和 /usr/local 是常见的弃取。
Android NDK 包含原生编译器和器具链的预编译版块。GCC 和 Clang 编译器在传统上都得到了援救,但是对 GCC 的积极援救在 NDK第14版落幕了。开荒体绑缚构和主机操作系统决定适当的版块,预编译的器具链在 NDK 的 toolchains 目次中,每种架构包含一个相应的子目次。
除了弃取正确的体绑缚构之外,你还需要为想要场地 Native API 品级指定正确的 sysroot。sysroot 是一个包含场地系统头文献和库的目次。Native API 因 Android API 品级的不同而不同。每个Android API 品级的 sysroot 目次都不错在 $NDK/platforms/ 中找到。每个API级别目次都包含多样 CPU 和体绑缚构的子目次。
设立编译系统的一种可能是将编译器旅途和必要的标记导出为环境变量。不外,为了让事情变得更浮浅,NDK 允许你创建一个所谓的逍遥器具链,这是一个临时的器具链,包含了所需的设立。
要建立一个逍遥的器具链,需要下载 NDK 最新的褂讪版块。解压缩 ZIP 文献,切换到 NDK 根目次,运行以下敕令:
这将在 /tmp/android-7-toolchain 目次中为Android 7.0(API 品级24)创建一个逍遥的器具链。为了便捷,不错导出一个指向器具链目次的环境变量(咱们将在示例中使用它)。运行以下敕令或将它添加到 .bash_profile 中或其他启动剧本:
为了进行动态分析,你需要一个 Android 开荒来运行场地应用程序。原则上,你不错在莫得真实的 Android 开荒的情况下进行测试,而况只使用模拟器。关联词,应用程序在模拟器上推论得相配慢,模拟器可能不会给出真实的结果。在真实的开荒上进行测试不错使过程愈加顺畅,环境也愈加真实。另一方面,模拟器允许你莽撞地转变 SDK 版块或创建多个开荒。下表列出了每种方法的优症结。
险些任何物理开荒都不错用于测试,但是有一些需要沟通的事项。起始,开荒需要 root,平时通过间隙愚弄或未锁定的素养加载程序来完成此操作。 间隙愚弄并不老是可用的,而况素养加载程序可能被永恒锁定,或者只须在运营商合同隔断后才能被解锁。
最好候选开荒是为开发者打造的旗舰 Google pixel 开荒。这些开荒平时都带有未锁定的素养加载程序、开源的固件、内核、在线电台和官方操作系统源代码。开发者社区更可爱 Google 开荒,因为该操作系统最接近 android 开源式样。 这些开荒平时具有最长的援救窗口,具有2年的 OS 更新和1年的安全更新。
另外,Google 的 Android One 式样包含的开荒将会得到一样的援救窗口(2年的操作系统更新,1年的安全更新),而况有接近原生的教育。天然它率先是一个针对低端开荒的式样,但该式样照旧发展到包括中端和高端智高东谈主机,其中许多都得到了 modding 社区的积极援救。
LineageOS式样援救的开荒亦然测试开荒的很好的候选开荒。他们有一个活跃的社区,易于校服的刷机和 root 说明,而况平时不错通过 Lineage 装配快速获取最新的 Android 版块。在 OEM 住手发布更新后很长一段时辰里,LineageOS 还陆续援救新的 Android 版块。
当使用 Android 物理开荒时,你需要启用开发者模式和开荒上的 USB 调试,以便使用 ADB 调试接口。自 Android 4.2(API 品级16)以来,手机设立菜单中开发者选项默许是荫藏的,要激活它,点击对于手机中的版块号部分七次。请防范,版块号字段的位置因开荒略有不同。举例,在LG手机上,它是 About phone -> Software information。一朝你这么作念了,开发者选项将骄贵在设立菜单的底部。一朝开发者选项被激活,你不错使用 USB 调试开关启用调试。
存在多种模拟器,它们各有优症结:
免费模拟器:
Android 杜撰机开荒(AVD)- 官方的Android模拟器,与Android Studio一谈发布。
Android X86 - 安卓代码库的 X86 接口
贸易模拟器:
Genymotion - 具有许多特质的陶冶仿模拟器,不错动作腹地和基于云的惩办决议,提供非贸易使用的免费版块。
Corellium - 通过基于云或腹地的惩办决议提供自界说开荒杜撰化。
天然有其他一些免费的 Android 模拟器,但咱们推选使用 AVD,因为它提供了与其他模拟器比拟更妥贴测试应用程序的增强功能。在本指南的其余部分中,咱们将使用官方的 AVD 来推论测试。
AVD 援救一些硬件仿真,如 GPS、SMS 和融会传感器。
你不错使用 Android Studio 中的 AVD 管束器启动 Android 杜撰开荒(AVD),也不错在敕令行中使用 android 敕令启动 AVD 管束器,在 Android SDK 的 tools 目次中不错找到:
不错使用一些器具和 VM 在模拟器环境中测试应用程序:
Rooting(举例,修改 OS 以便你不错动作 root 用户运行敕令)建议在真实开荒上进行测试。这使你大要完全戒指操作系统,并允许您绕过应用程序沙盒之类的限定。这些特权又允许你更容易地使用代码注入和函数 hook 等手艺。
防范,root 是有风险的,在你陆续之前,需要弄清三个主要后果。Root 可产生以下负面影响:
你不应该 root 一个存储着私东谈主信息的个东谈主开荒,咱们建议购买一个低廉的专用测试开荒。许多老的开荒,比如谷歌的 Nexus 系列,都不错运行最新的 Android 版块,用来测试极度好。
你需要明白,root 你的开荒最终是你我方的决定,OWASP 不会对任何损坏负责。如果你不细目,在滥觞 root 过程之前应该寻求大家的建议。
现实上,任何 Android 手机都不错 root。Android OS(在内核级是 Linux OS 的演化)的贸易版块针对出动全国进行了优化。这些版块中,一些特质被删除或禁用了,举例,非特权用户不错成为 root 用户(领有提高的特权)。Root 手机意味着允许用户成为 root 用户,举例,添加一个名为 su 的模范 Linux 可推论文献,可用于转变为另一个用户帐户。
要 root 一个出动开荒,起始解锁它的启动素养程序,解锁的过程取决于开荒制造商。关联词,出于现实的原因,root 某些出动开荒要比其他开荒更受接待,尤其是在安全测试方面:Google 开发的,Samsung、LG 和 Motorola 等公司制造的开荒最受接待,尤其是因为它们被许多开发东谈主员使用。当素养加载程序被解锁时,开荒保证不会失效,谷歌提供了许多器具来援救 root。XDA 论坛上发布了精选的扫数主流品牌开荒的 root 指南。
Magisk(“Magic Mask”)是一种 root 你的 Android 开荒的方法,它的特殊性在于对系统进行修改的步地。当其他的 root 器具改变系统分区上的现实数据时,Magisk 不会(它被称为“systemless“)。这么就不错荫藏对 root 明锐的应用程序(举例银行或游戏)的修改,而况在 root 的情况下允许使用官方的 Android OTA 升级
你不错通过阅读 GitHub 上的官方文档来闇练 Magisk。如果您莫得装配 Magisk,不错在文档中找到装配说明。如果你使用负责的 Android 版块并策动升级,Magisk 在 GitHub 上提供了一个教程。
此外,开发东谈主员不错使用 Magisk 的庞杂功能创建自界说模块,并将它们提交到官方的 Magisk 模块库,提交的模块不错装配在 Magisk 管束器应用程序中。知名的 Xposed 框架的 systemless 版块(适用于高达27的 SDK 版块)是这些可装配模块之一。
Root 检测方法的一个详细列表在“在 Android 上测试反逆向驻扎”一章中被提议。
对于典型的出动应用程序安全性编译版块,你平时但愿测试一个禁用 root 检测的调试版块编译。如果这么的编译无法用于测试,你不错使用多样方法禁用 root 检测,这将在本书背面先容。
本指南中使用了许多器具和框架来评估 Android 应用程序的安全性。鄙人一节中,你将了解更多一些敕令和兴致的使用案例,请参阅官方文档了解商量下列器具的装配说明:
APK Extractor:不需要 root 即可索求 APK 的应用程序。
Frida server:Frida 的就业器,适用于开发东谈主员、逆向工程东谈主员和安全研究东谈主员的动态器具套件。商量更多信息见底下的 Frida 部分。
Drozer代理:drozer 的代理,该框架使您不错搜索应用程序和开荒中的安全间隙。商量更多信息见底下的 Drozer 部分。
Busybox:Busybox 将多个常见的 Unix 实用程序组合成一个小的可推论文献。平时,所包含的实用程序比其功能皆全的同类程序 GNU 具有更少的弃取,但足以在袖珍或镶嵌式系统上提供齐备的环境。Busybox 不错装配在 root 开荒上,通过从 Google Play 商店不错下载 Busybox 应用程序。你也不错平直从 Busybox 网站下载二进制文献。下载后,运行 adb push busybox / data / local / tmp 传输文献顺利机上。在 Busybox FAQ 中不错找到商量怎么装配和使用 Busybox 的快速轮廓。
Xposed 是一个“无需转变 APK 即可转变系统和应用程序步履的模块框架。”从手艺上讲,它是Zygote的彭胀版块,在启动新进程时会导出用于运行 Java 代码的 API。在新实例化的应用程序高下文中运行 Java 代码不错分解、hook 和重写属于该应用程序的 Java 方法。Xposed 使用反射来检测和修改正在运行的应用程序,修改会应用到内存中,而况仅在进程的运行时持久保存,并未修改应用程序二进制文献。
要使用 Xposed,起始需要像 XDA-Developers Xposed framework hub 上解释的那样,在一个 root 开荒上装配 Xposed 框架。模块不错通过 Xposed 装配程序装配,通过 GUI 大开和关闭它们。
防范:沟通到 SafetyNet 很容易检测到 Xposed 框架的浮浅装配,咱们建议使用 Magisk 来装配 Xposed。这么,带有 SafetyNet 认证的应用程序会具有更高的使用 Xposed 模块进行测试的契机。
Xposed 已与 Frida 进行了比较。 在 root 开荒上运行 Frida server 时,最终你将得到一个一样灵验的设立。当你要进行动态检测时,这两个框架都十分有用。当 Frida 使应用程序崩溃时,你不错尝试在 Xposed 上使用近似的方法。接下来,近似于多数的 Frida 剧本,你不错莽撞地使用 Xposed 的繁密的模块,举例前边照看的绕过 SSL pinning 模块(JustTrustMe 和 SSLUnpinning)。Xposed 还包括其他模块,举例 Inspeckage,它使你大要进行应用程序更多的深度测试。最进军的是,你还不错创建我方的模块,以修改 Android 应用程序的常用安全机制。
Xposed 也不错通过底下的剧本装配在模拟器上:
请防范,在撰写本文时,Xposed 无法在 Android 9(API 品级28)上运行。但是在2019年它以 Edxposed 的名字被非负责地移植,援救Android 8-10(API 品级26至29),你不错在 EdXposed 的 Github 仓库中找到代码和用法示例。
为了分析Android应用程序,你应该在你的主机上装配以下器具。请在官方文档中检验以下器具或框架的装配说明,咱们将在指南中提到它们。
adb(Android Debug Bridge),随 Android SDK 一谈提供,联结腹地开发环境和已联结的 Android 开荒。你平时会使用它在模拟器或通过 USB 或 Wi-Fi 联结的开荒上测试应用程序。使用 adb devices 敕令不错列出联结的开荒,推论时并加上 -l 参数不错检索商量这些开荒的更多细节。
adb 提供了其他有用的敕令,比如 adb shell 在场地开荒上启动交互式的 shell,以及 adb forward 将特定主机端口上的流量转发到联结开荒上的不同端口。
请防范,如果联结了多个开荒,则必须使用 -s 参数界说场地开荒的序列号(如上一代码片断所示)。
Angr 是一个用于分析二进制文献的 Python 框架。它对于静态和动态象征分析都是有用的。换句话说:给定一个二进制和一个恳求景况,Angr将尝试到达阿谁景况,使用式样化的方法(一种用于静态代码分析的手艺)来找到一条旅途,以及强制推论。使用 angr 来获取恳求的景况平时比手动调试和搜索通往所需景况的旅途要快得多。Angr 使用VEX 中间话语进行操作,并带有 ELF/ARM 二进制文献加载程序,因此极度妥贴处理原生代码,举例原生 Android 二进制文献。
Angr 允许使用多数插件来进行反汇编、程序检测、象征推论、戒指流分析、数据依赖分析、反编译等等。
自从版块8,Angr 是基于 Python3 并不错使用 pip 装配在*nix操作系统、macOS 和 Windows 上:
angr 的一些依赖项包含 Python 模块 Z3 和 PyVEX 的派生版块,这将粉饰原始版块。如果你将这些模块用于其他用途,则应该使用 Virtualenv 创建一个专用的杜撰环境。另外,你也不错使用提供的 docker 容器。商量更多细节,请参阅装配指南。
在 Angr 的 Gitbooks 页面上有全面的文档,包括装配指南、教程和使用示例,还提供了齐备的 API 参考。
你不错通过 Python REPL(如 iPython)使用angr,也不错编写方法剧本。尽管 angr 的学习弧线有些笔陡,但是尽管 angr 的学习弧线有些笔陡,但是当你想要通过强制的步地得到一个可推论文献的给定景况,咱们如故建议你使用它。请见“逆向工程和删改”一章的“象征推论”部分,不错动作一个很好的例子来说明它是怎么使命的。
Apktool 用于解压 Android 应用程序包(APK)。浮浅地用模范 unzip器具解压 APK 会留住一些不可读的文献。AndroidManifest.xml 被加密成二进制 XML 神态,文本裁剪器无法读取。此外,应用程序资源仍然被打包到一个存档文献中。
当使用默许敕令行参数运行时,apktool 会自动将 Android 清单文献解密为为基于文本的 XML 神态并索求文献资源(它还会将 .DEX 文献反汇编为 smali 代码——这个特质咱们将在本书背面先容)。
解压缩的文献是:
还不错使用 apktool 将已解密的资源重新打包回二进制 APK/JAR。见本章背面的“探索应用程序包”一节和”Android 上的删改和逆向工程“一章中“重打包”一节,了解更多信息和实例。
Apkx 是流行的免费 DEX 诊疗器和 Java 反编译器的 Python 包装器。它自动索求、诊疗和反编译 apk,装配步地如下:
这会将 apkx 复制到 /usr/local/bin。请参阅“逆向工程和删改”一章的“反编译Java代码”一节,了解更多商量用法的信息。
Burp Suite 是一个用于出动和 web 应用程序安全性测试的集成平台。它的器具不错无缝地协同使命,以援救扫数这个词测试过程,从率先的障碍面映射和分析到发现和愚弄安全间隙。Burp Proxy 动作 Burp Suite 的 web 代理就业器,它被定位为浏览器和 web 就业器之间的中间东谈主。Burp Suite 允许您禁锢、查验和修改传入和传出的原始 HTTP 流量。
设立 Burp 代理您的流量极度浮浅。咱们假设您有一个 android 开荒和使命站联结到 Wi-Fi 相聚,该相聚允许客户端到客户端通讯。
PortSwigger 提供了对于怎么设立Android 开荒来使用 Burp 和怎么将 Burp 的 CA 文凭装配到 Android 开荒的教程。
Drozer 是一个 Android 安全评估框架,如果第三方应用程序与其他应用程序的 IPC 端点和底层操作系统进行了交互,你不错搜索应用程序和开荒中的安全间隙。
使用 drozer 的上风在于它大要自动推论多个任务,而况不错通过模块进行彭胀。这些模块极度有匡助而况涵盖了不同的类别,其中包括扫描器类别,该类别使你不错使用浮浅的敕令扫描已知的劣势,举例模块 scanner.provider.injection 不错检测系统中装配的扫数应用程序的内容提供者中的 SQL 注入 。 如果不使用 drozer,则浮浅的任务(举例列出应用程序的权限)需要几个要道,包括反编译 APK 和手动分析结果。
你不错参考 drozer GitHub 页面(对于 Linux 和 Windows,macOS 请参考这篇博客著作)和 drozer 的网站了解必备条件和装配说明。
drozer 在 Unix、Linux 和 Windows 上的装配说明在 drozer Github 页面中有解释。对于macOS,这篇博客演示了扫数的装配说明。
在滥觞使用 drozer 之前,还需要在 Android开荒上运行 drozer 代理。从 GitHub 发布页面下载最新的 drozer 代理,并用 adb install drozer.apk 装配它。
一朝装配完成,你不错通过运行 adb forward tcp:31415 tcp:31415 和 drozer console connect 启动一个会话到模拟器或 USB 联结的开荒。这被称为平直模式,你不错在用户指南的“滥觞一个会话”一节中看到齐备的说明。另一种弃取是在基础设施模式下运行Drozer,在这种模式下,你运行一个 Drozer 就业器,它不错处理多个戒指台和代理,并在它们之间路由会话。你不错在用户指南的“基础设施模式”一节中找到如安在此模式下设立 drozer 的详细信息。
面前您不错滥觞分析应用程序了。一个好的开端是列举一个应用程序的障碍面,不错通过以下敕令很容易地完成:
一样,如果莫得 drozer,这将需要几个要道。 app.package.attacksurface 模块列出了行动,播送给与者,内容提供者和导出的就业,因此它们是群众的而况不错通过其他应用程序进行拜谒。 一朝细目了障碍面,就不错通过 drozer 与 IPC 端点进行交互,而无需编写单独的逍遥应用程序,某些任务会需要它,比如与内容提供者通讯。
举例,如果应用程序的导出行动裸露了明锐信息,咱们不错使用 Drozer 模块 app.activity.start 来调用它:
前边的敕令将启动行动,但愿裸露一些明锐信息。Drozer 有针对每一种 IPC 机制的模块,如果你想尝试带有有意易受障碍的应用程序的模块,请下载 InsecureBankv2,该应用程序演示了与 IPC 端点干系的常见问题。请密切防范扫描器类别中的模块,因为它们对于自动检测系统包中的间隙极度有用,特别是如果你使用的是手机公司提供的 ROM。在畴前以致使用 drozer 识别出过 Google 系统软件包中的 SQL 注入间隙。
这里有一个非详备的敕令列表,你不错用来滥觞探索 Android:
你可能会发现其他有用信息的资源有:
Frida 是一个免费和开源的动态代码器具包,它允许你在腹地应用程序中推论 JavaScript 剧本,在通用测试指南的“删改与逆向工程”一章中照旧先容了。
Frida 通过 Java API 援救与 Android Java 运行时的交互。你大要在hook 和调用进程的 Java 和原生函数,以及它的原生库。你的 JavaScript 剧本对内存有完全的拜谒权限,举例读取或写入任何结构化数据。
底下是 Frida api 提供的一些任务,在 Android 上是干系的或独家的:
实例化 Java 对象并调用静态和非静态类方法(Java API )。
替换Java方法罢了(Java API )。
通过扫描 Java 堆摆设特定类的行动实例(Java API )。
扫描进程内存中出现的字符串(Memory API )。
禁锢原生函数调用以在函数进口和出口运行我方的代码(Interceptor API)。
记着,在Android上,你还不错从装配 Frida 时提供的内置器具中获益,包括 Frida CLI(frida)、frida-ps、frida-ls-devices 和 frida-trace。
Frida 频频被拿来和 Xposed 进行比较,但是这种比较并不屈允,因为这两个框架的遐想场地是不同的。动作一个应用程序安全测试东谈主员,了解这极少很进军,这么你就不错知谈在什么情况下使用哪个框架:
Frida 是逍遥的,你所需要作念的等于从场地 Android 开荒中的已知位置运行 frida-server 二进制文献(请参阅底下的“装配Frida”)。这意味着,与 Xposed 比拟,它莫得深刻装配在场地 OS 中。
逆向一个应用程序是一个反复的过程。由于上极少的影响,在测试时,你获取了更短的反馈轮回,因不需要(软)重启来应用钩子或浮浅地更新钩子。同期在罢了更持久的钩子时,你可能更可爱使用 Xposed。
你不错在进程运行时期的任何时候动态注入和更新 Frida JavaScript 代码(近似于 iOS 上的 Cycript)。这么,不错通过让 Frida 来 spwan 你的应用程序推论所谓的早期检测,或者你可能更可爱附加到一个插足特定景况的正在运行的应用程序。
Frida 大要处理 Java 以及原生代码(JNI),允许你修改它们。不懒散的是,这恰是 Xposed 的局限性,劳苦原生代码援救。
值得防范的是,到 2019 年头,Xposed 还不可在 Android 9(API 品级28)上运行。
要在腹地装配 Frida,只需运行:
参考装配页面了解更多细节。
下一步等于在你的 Android 开荒上设立 Frida:
除非另有说明,咱们假设在这里是 root 开荒。从 Frida 发布页下载 frida-serve 二进制文献。确保为你的 Android 开荒或模拟器的架构下载了正确的 frida-server 二进制文献:x86,x86_64,arm 或 arm64。确保就业器版块(至少是主版块号)与腹地 Frida 装配版块匹配。PyPI平时装配最新版块的 Frida。如果不细目装配的版块,不错使用 Frida 敕令行器具查验:
或者你不错运行以下敕令来自动检测 Frida 版块并下载正确的 frida-server 二进制文献:
复制 frida-server 到开荒上并运行它:
跟着 frida-server 的运行,你面前应该不错使用以下敕令获取正在运行的进程的列表(用 -U 选项指示 Frida 使用一个已联结的 USB 开荒或模拟器):
或使用 -Uai 参数组合限定列表,以获取联结的 USB 开荒(-U)上头前装配的(-i)扫数应用程序(-a):
聚色庄园这将骄贵扫数应用程序的称呼和象征符,如果面前正在运行,还将骄贵它们的 PID。在列表中搜索你的应用程序,并防范 PID 或其称呼/象征符,从面前起你将使用其中一个来援用你的应用程序。建议使用这些应用的象征符,因为在每次运行应用程序时 PID 都会改变。举例,以 com.android.chrome 为例,你面前不错在扫数 Frida 器具上使用此字符串,如在 Frida CLI,frida-trace 或 Python 剧本上。
要追踪特定的(底层)库调用,你不错使用 frida-trace 敕令行器具:
这会在 __handlers __ / libc.so/open.js 中生成一些 JavaScript 代码,Frida 将其注入到进程中。该剧本将追踪对 libc.so 中的 open 函数的扫数调用。你不错使用 Frida JavaScript API 根据需要修改生成的剧本。
不懒散的是,尚不援救追踪 Java 类的高等方法(但将来可能会)。
使用 Frida CLI 器具(Frida)与 Frida 交互使命。它挂接到一个进程,并为你提供 Frida API 的敕令行界面。
通过 -l 选项,你不错使用 Frida CLI 加载剧本,举例,加载 myscript.js:
Frida 还提供了一个 Java API,这对处理 Android 应用程序特别有匡助,它允许你平直使用 Java 类和对象。底下是一个剧本,用于重写 Activity 类的 onResume 函数:
上头的剧本调用 Java.perform 以确保您的代码在 Java VM 的环境中推论。它通过 Java.use 实例化一个 android.app.Activity 类的包装器,并重写 onResume 函数。新的 onResume 函数罢了打印见知到戒指台,并在行动每次处于复原景况时通过调用 this.onResume 来调用蓝本的 onResume 方法。
Frida 还允许你搜索并使用堆上的实例化对象。以下剧本搜索 android.view.View 对象的实例,并调用其 toString 方法,结果打印到戒指台:
输出会像这么:
你还不错使用 Java 的反射功能。要列出 android.view.View 类的群众方法,你不错在 Frida 中为此类创建一个包装器,并从该包装器的 class 属性调用 getMethods:
这将在终局打印很长的方法列表:
为了彭胀剧本编写体验,Frida 提供了与Python,C,NodeJS 和 Swift 等编程话语的绑定。
以 Python 为例,起始要防范的是不需要更多的装配要道。使用 import frida 启动 Python 剧本,就不错滥觞了。请参阅底下的剧本,该剧本仅运行先前的 JavaScript 代码段:
在这种情况下,运行 Python 剧本(python3 frida_python.py)与上一个示例具有调换的结果:它会打印 android.view.View 类的扫数方法到终局。但是,你可能但愿使用 Python 中的数据。使用 send 代替 console.log 会将数据以 JSON 神态从 JavaScript 发送到 Python 上。请阅读以下示例中的审视:
这灵验地过滤了方法,只打印包含字符串“Text”的方法:
终末,由你决定在什么地方处理数据,偶然候,用 JavaScript 来作念会比较便捷,而在其他情况下,Python 将是最好的弃取。天然,你也不错使用 script.post 将讯息从 Python 发送到 JavaScript 上。商量发送和给与讯息的更多信息,请参考 Frida 文档。
House 是一个用于 Android 应用运行时的出动应用分析器具包,由 NCC 小组开发和爱护,用 Python 编写。
它愚弄 root 开荒上运行的 Frida server 或重打包到 Android 应用程序中的 Frida gadget。House 的宗旨是通过便捷的 web GUI 提供一种浮浅的方法来原型化 Frida 剧本。
House 的装配说明和操作指南不错在 Readme of the Github repo 中找到。
Magisk(“Magic Mask”)是一种 root 你的 Android 开荒的方法,它的特殊性在于对系统进行修改的步地。当其他的 root 器具改变系统分区上的现实数据时,Magisk 不会(它被称为“systemless“)。这么就不错荫藏对 root 明锐的应用程序(举例银行或游戏)的修改,而况在 root 的情况下允许使用官方的 Android OTA 升级
你不错通过阅读 GitHub 上的官方文档来闇练 Magisk。如果您莫得装配 Magisk,不错在文档中找到装配说明。如果你使用负责的 Android 版块并策动升级,Magisk 在 GitHub 上提供了一个教程。
MobSF 是一个自动化的、一体化的出动应用程序审计框架,它也援救 Android APK 文献。启动 MobSF 最浮浅的方法是通过 Docker。
或通过运行以下敕令在主机上腹地装配并启动它:
一朝你启动并运行了 MobSF,你就不错通过在浏览器中大开 :80。只须将你想要分析的APK拖放到上传区域,MobSF就会滥觞使命。
在 MobSF 完成了它的分析之后,你将收到一页对于扫数被推论的测试的轮廓。页面被分割成多个部分,提供了一些对于应用程序障碍名义的初步辅导。
骄贵如下内容:
对于应用程序过火二进制文献的基本信息。
一些选项:检验 AndroidManifest.xml 文献。检验应用程序的 IPC 组件。
签名者文凭。
更多细节请参考 MobSF 文档。
Objection 是一个“由 Frida 提供的运行时出动探索器具包”,它的主要场地是允许通过直不雅的界面在未 root 开荒上进行安全性测试。
通过为你提供通过将 Frida gadget 注入应用程序重新打包的器具,Objection 罢了了这一场地。通过这种步地,你不错将重新打包的应用程序配置到未 root 开荒上让不会与应用程序交互,如前一节所述。
但是,Objection 还提供了一个 REPL,允许你与应用程序交互,使你大要推论应用程序不错推论的任何操作。在式样的主页上不错找到齐备的 Objection 功能列表,这里有一些兴致的:
在未 root 开荒上推论高等动态分析的能力是使 Objection 极度有用的特质之一。一个应用程序可能包含高等 RASP 戒指,不错检测你的 root 方法,注入 frida-gadget 可能是绕过这些戒指的最浮浅的方法。此外,包含的 Frida 剧本使快速分析应用程序或绕过基本的安全戒指变得极度容易。
终末,如果你照实不错拜谒一个 root 开荒,Objection 不错平直联结到运行中的 Frida server 来提供扫数功能,而不需要重新打包应用程序。
正如 Objection's Wiki 中描画的那样,不错通过 pip 平直装配。
如果你的开荒照旧逃狱了,你面前就不错和开荒上运行的任何应用程序进行交互了,你不错跳到底下的“使用 Objection”部分。
但是,如果但愿在未 root 开荒上进行测试,起始需要在应用程序中包含 Frida gadget。 Objection Wiki 详细描画了需要的要道,但是在作念了正确的准备之后,你将大要通过调用 Objection 敕令来给 APK 打补丁:
然后,需要使用 adb 装配修自新的应用程序,正如“基本测试操作——装配应用程序”中解释的那样。
滥觞使用 Objection 依赖于你是否给 APK 打了补丁,或是你是否使用运行了 Frida-server 的 root 开荒。运行一个打过补丁的 APK,Objection 将自动找到附加的开荒和搜索一个正在监听的 Frida gadget。但是,在使用 frida-server 时,你需要显式地告诉 frida-server 要分析哪个应用程序。
一朝插足了 Objection REPL,你就不错推论任何可用的敕令,以下是一些最有用的方法的轮廓:
更多对于使用 Objection REPL 的信息不错在 Objection Wiki 上找到。
radare2(r2)是一个流行的开源逆向工程框架,用于反汇编、调试、打补丁和分析二进制文献,该框架可编写剧本,援救多种架构和文献神态,包括 Android 和 iOS 应用程序。对 Android 援救 Dalvik DEX(odex, multidex),ELF(可推论文献,.so, ART)和 Java(JNI 和 Java 类)。它还包含了几个有用的剧本,不错在出动应用程序分析时期匡助您,它提供了底层的反汇编和安全的静态分析,在传统器具失败时极度有用。
radare2 罢了了一个丰富的敕令行界面(CLI),你不错在上头推论上述任务。但是,如果你不是很民风使用 CLI 进行逆向工程,你不错沟通使用 Web UI(通过 -H 参数)或者更便捷的 Qt 和 C++ GUI 版块 Cutter。请记着对于 CLI,更具体地说是它的可视化模式和剧本功能(r2pipe),是 radare2 庞杂功能的中枢,皆备值得学习怎么使用它。
请参考 radare2 的官方装配说明。咱们热烈建议永恒从 GitHub 版块装配 radare2,而不是通过 APT 等常见的包管束器。Radare2正处于极度活跃的开发阶段,这意味着第三方存储库频频会过期。
radare2 框架包含一组袖珍实用程序,不错在 r2 shell 中使用,也不错动作逍遥的 CLI 器具使用。这些器具包括 rabin2,rasm2,rahash2,radiff2,rafind2,ragg2,rarun2,rax2,天然还有 r2,这是主要的一个。
举例,你不错使用 rafind2 平直从一个加密的Android 清单文献(AndroidManifest.xml)中读取字符串:
或者使用 rabin2 来获取对于二进制文献的信息:
输入 rabin2 -h 检验扫数的选项:
使用 r2 实用程序拜谒 r2 shell,你不错像加载任何其他二进制一样加载 DEX 二进制文献:
输入 r2 -h 以检验扫数可用选项。一个非频频用的参数是 -A,它在加载场地二进制文献后触发分析。但是,应该对小的二进制文献严慎使用,因为它极度奢靡时辰和资源。你不错在“Android上的删改和逆向工程”一章中了解更多。
一朝插足了 r2 shell,你还不错拜谒其他 radare2 实用程序提供的函数。举例,运行 i 将打印二进制文献的信息,就像 rabin2 -I 所作念的那样。
要打印扫数字符串,在 r2 shell 中使用 rabin2 -Z 或敕令 iz(或更浮浅的 izq)。
在大多数情况下,你不错在敕令中附加特殊选项,举例 q 不错使敕令不太冗长,或者 j 不错用 JSON 神态提供输出(使用 〜{} 暗示JSON字符串)。
你不错使用 r2 敕令 ic 打印类名过火方法。(类信息)
你不错使用 r2 敕令 ii 打印导入的方法。(导入信息)
查验二进制文献时,一种常见的方法是搜索、导航到它并使之可视化,以便解释代码。使用 radare2 查找内容的方法之一是使用特定敕令过滤输出,即使用 ~ 加上重要字(~+ 暗示大小写不解锐)对它们进行 grep。举例,咱们可能知谈应用程序正在考证一些东西,咱们不错查验 radare2 扫数的 flag,望望咱们在那边找到与“考证”干系的东西。
当加载一个文献时,radare2 会标记它大要找到的扫数东西,这些标记的称呼或援用称为 flag,你不错通过敕令 f 来拜谒它们。
在这个案例中,咱们使用重要字”verify“来 grep flag。
看起来咱们在 0x00000a38 处找到了一个方法(标记了两次),在 0x00001400 处找到了一个字符串。让咱们通过使用它的标志来导航(寻找)到阿谁方法:
天然,您还不错使用 r2 的反汇编功能,并用 pd 敕令(或者 pdf,如果你知谈你照旧位于一个函数中)打印反汇编结果。
r2 敕令平时经受选项(见 pd?),举例,你不错通过在敕令 pd N 背面附加数字(“N”)来限定骄贵的操作码。
你可能但愿通过输入 V 插足所谓的可视模式,而不是只是将反汇编输出到戒指台。
默许情况下,你将看到十六进制视图。通过键入 p,你不错切换到不同的视图,如反汇编视图:
Radare2 提供了一种图形模式,它对于追踪代码流极度有用,你不错在可视模式下输入V:
这只是一些 radare2 敕令的一部分,用来滥觞从 Android 二进制文献中获取一些基本信息。Radare2 极度庞杂,在 Radare2 敕令文档中不错找到许多敕令。Radare2 将在扫数这个词指南顶用于不同的宗旨,如逆向代码、调试或推论二进制分析。咱们还将结合使用其他框架,特别是Frida(更多信息,请参阅 r2frida 一节)。
商量 radare2 在Android上的详细使用,特别是在分析原生库时,请参考“Android 上的删改和逆向工程”一章。你可能还想读一下 radare2 的官方竹素。
r2frida 是一个允许 radare2 联结 Frida 的式样,灵验地将 radare2 庞杂的逆向工程能力与 Frida 的动态分析器具包结合在一谈。R2frida 允许你:
请参考 r2frida 的官方装配说明。
跟着 frida-server 运行,你面前应该大要使用pid、spawn path、主机和端口或开荒 id 联结到它。举例,附加到 PID 1234:
商量怎么联结 frida-server 的更多示例,请参阅 r2frida 的 README 页面中的使用部分。
联结之后,你应该会看到带有开荒id的r2辅导符。r2frida 敕令必须以 \ 或 =!滥觞。举例,你不错使用敕令 \i 检索场地信息:
要在内存中搜索特定重要字,你不错使用搜索敕令 \/:
要以 JSON 神态输出搜索结果,只需在前边的搜索敕令中添加 j(就像在 r2 shell 中所作念的那样)。这不错在大多数敕令中使用:
要列出已加载的库,请使用敕令 \il 并使用 radare2 的里面 grep 敕令 〜 过滤结果。 举例,以下敕令将列出与重要字 keystore,ssl 和 crypto 匹配的已加载库:
近似地,通过特定的重要字列出导出表并过滤结果:
使用敕令 db 列出或设立断点。这在分析/修改内存时是有用的:
终末请记着,您也不错使用 \ 运行 Frida JavaScript 代码,加上剧真称呼即可:
你不错在他们的 Wiki 式样中找到更多对于怎么使用 r2frida 的示例。
在测试应用程序时,最常见的事情之一等于拜谒开荒 shell。在这一节中,咱们将看到如安在有或莫得 USB 线情况下从你的主机上费力拜谒 Android Shell,以及在腹地开荒拜谒。
为了从你的主机联结到 Android 开荒的 shell,adb 平时是你弃取的器具(除非你可爱使用费力 SSH 拜谒,举例通过 Termux)。
对于本节,咱们假设你照旧正确地启用了开发者模式和 USB 调试,正如“在真实开荒上进行测试”中所解释的那样。一朝你通过 USB 联结了 Android 开荒,你不错通过运行以下敕令拜谒费力开荒的 shell:
按 Control + D 或输入 exit 退出
如果你的开荒是 root 的或你正在使用模拟器,一朝你处在费力 shell 中,你不错通过运行 su 获取 root 拜谒权限:
只须当你使用模拟器时,才不错使用敕令 adb root 重新启动 adb,这么下次插足 adb shell 时,你就照旧领有 root 权限了。这也允许在使命站和 Android 文献系统之间双向传输数据,以致不错拜谒只须 root 用户不错拜谒的位置(通过 adb push/pull)。商量数据传输的更多信息,请参阅底下“主机-开荒数据传输”一节。
如果你有不啻一个开荒,记着在你的扫数 adb 敕令上包括 -s 参数,后跟开荒序列号(举例 adb -s emulator-5554 shell 或 adb -s 00b604081540b7c6 shell)。你不错使用以下敕令得到扫数联结的开荒的列表和他们的序列号:
你也不错不使用 USB 线拜谒你的 Android 开荒。为此,你必须将你的主机和安卓开荒联结到合并个 Wi-Fi 相聚,然后按照底下的要道进行:
用 USB 线将开荒联结到主机,并设立场地开荒在端口5555上监听 TCP/IP 联结:adb tcpip 5555。
断开与场地开荒的USB联结线,运行 adb connect <device_ip_address>。运行 adb devices 查验该开荒面前是否可用。
用 adb shell 大开 shell。
但是请防范,这么作念会让你的开荒对处于合并相聚并知谈你的开荒 IP 地址的任何东谈主绽开。你可能更可爱使用 USB 联结。
举例,在一个 Nexus 开荒上,你不错在设Settings -> System -> About phone -> Status -> IP address 找到 IP 地址,或者插足 Wi-Fi 菜单,在你联结的相聚上点击一下。
在 Android 开发者文档中不错看到齐备的说明和留隐衷项。
如果景象,还不错启用 SSH 拜谒。一个便捷的选项是使用 Termux,你不错莽撞地配置它来提供 SSH 拜谒(使用密码或公钥身份考证),并使用敕令 sshd 启动它(默许在端口8022上启动)。为了通过 SSH 联结到 Termux,只需运行敕令 ssh -p 8022 <ip_address>(其中 ip_address 是现实的费力开荒IP)。这个选项还有一些额外的克己,它允许在端口8022上通过 SFTP 拜谒文献系统。
与费力 shell 比拟,平时使用开荒上的 shell(终局模拟器))可能极度单调乏味,但对于调试,举例相聚问题或查验某些配置来说,它很便捷。
Termux 是一个用于 Android 的终局模拟器,它提供了一个 Linux 环境,不错平直使用或不使用 root,而况不需要设立。装配额外的包是一项琐碎的任务,但是它有我方的 APT 包管束器(与其他终局模拟器应用程序比拟的不同之处)。你不错使用敕令 pkg search <pkg_name> 来搜索特定的包,并使用 pkg install <pkg_name> 来装配包。你不错平直从 Google Play 装配 Termux。
你不错使用 adb pull <remote> <local> 和 adb push <local> <remote> 敕令将文献复制到开荒或从开荒中复制。它们的用法极度浮浅,举例,底下的操作将把 foo.txt 从面前目次(腹地)复制到 sdcard 文献夹(费力):
这种方法平时在你知谈你想要复制什么和复制到那边从那边复制时使用,也援救批量文献传输,举例你不错从 Android 开荒复制扫数这个词目次到你的使命站。
Android Studio 有一个内置的开荒文献资源管束器,你不错通过 View -> Tool Windows -> Device File Explorer 大开它。
如果你使用的是一个 root 开荒,那么面前不错滥觞浏览扫数这个词文献系统了。关联词,当使用未 root 开荒拜谒应用程序沙箱时,除非应用程序是可调试的,不然不会使命,即使那样,你也会被“拘押”在应用程序沙箱中。
当你在一个特定的应用程序上使命而况想要复制你可能在它的沙箱中碰到的文献时,这个选项极度有用(防范你只可拜谒场地应用程序大要拜谒的文献)。这种方法不需要将应用设立为可调试的,在使用 Android Studio 的开荒文献浏览器时需要这么作念。
起始,如“推选器具-Objection”中所述,以 Objection 的步地联结到应用程序。然后,像往常一样在终局上使用 ls 和 cd 浏览可用文献:
一朝你有一个文献你想下载,你不错运行 file download <some_file>。这将下载该文献到你的使命目次,一样的步地,你不错使用 file upload 上传文献。
症结是,在撰写本文时,objection 还不援救批量文献传输,因此你只可复制单个文献。不外,在某些情况下,如果你照旧在使用 objection 探索应用程序,并找到了一些兴致的文献,这极少如故很有用的。不需要记下文献的齐备旅途并使用 adb pull <path_to_some_file>,你不错平直 file download <some_file> 下载文献。
如果你有一个 root 开荒,而况装配了 Termux 以及在其上正确配置了 SSH 拜谒权限,那么在端口8022上应该照旧运行了一个 SFTP(SSH 文献传输合同)就业器,你可从终局拜谒它:
或者浮浅地通过使用援救 SFTP 的客户端(如FileZilla):
检验 Termux Wiki 以了解更多商量费力文献拜谒方法的信息。
获取妥协压应用程序从开荒中索求APK文献有几种方法。根据应用程序是群众的如故独到的,你需要决定哪种方法是最浮浅的。
从开荒中索求 APK 文献有几种方法。你需要根据应用程序是群众的如故独到的,决定哪种方法是最浮浅的。
最浮浅的弃取之一是从 Google Play Store 的群众应用程序镜像的网站下载 APK。但是,请记着,这些站点不是官方站点,而况不可保证该应用程序莫得重新打包或包含坏心程序。一些知名网站托管 APK,并以不修改应用程序而知名,以致列出了应用程序的 SHA-1 和 SHA-256 校验和:
防范,你不可戒指这些网站,你不可保证他们在改日作念什么,在莫得其他弃取时再使用它们。
gplaycli 是一个基于 Python 的 CLI 器具,用于从 Google Play Store 搜索、装配和更新 Android 应用程序。按照装配要道操作就不错运行它了,gplaycli提供了几个选项,请参考其匡助(-h)以获取更多信息。
如果你不细目一个应用程序的包名(或 AppID),你不错推论一个重要字搜索 APK (-s):
防范在使用 gplaycli 时的应用区域(Google Play)限定,为了拜谒限定在你的国度的应用程序,你不错使用其他应用程序商店,比如“其他应用程序商店”中描画的那些。
接下来,你不错通过指定 APK 的 AppID 来下载(-d)弃取的APK(添加 -p 骄贵进程条,添加 -v 骄贵信息):
com.google.android.keep.apk 文献将下载到你面前的目次中。正如你所想象的,这种方法是一种极度便捷的下载 APK 的的方法,特别是在自动化方面。
你不错使用我方的 Google Play 凭证或令牌,默许情况下,gplaycli 将使用里面提供的令牌。
推选的方法是从开荒获取应用程序包包,因为咱们不错保证应用程序包莫得被第三方修自新。要从一个 root 或非 root 开荒获取应用程序,不错使用以下方法:
使用 adb pull 取回 APK,如果你不知谈包名,第一步是列出开荒上装配的扫数应用程序:
一朝找到了应用程序的包名,就需要通过它在系统中存储的齐备旅途来下载它。
有了 APK 的齐备旅途后,面前不错浮浅地使用 adb pull 来索求它。
APK将下载到你的使命目次中。
另外,还有一些像 APK Extractor 这么的应用程序不需要 root,以致不错通过你可爱的方法分享所索求的 APK。如果你不可爱通过相聚联结开荒或设立 adb 来传输文献,那么这将极度有用。
使用 adb install 在模拟器或联结的开荒上装配 APK。
防范,如果你有原始的源代码而况使用 Android Studio,则不需要这么作念,因为 Android Studio 会为你完成应用的打包和装配过程。
分析应用程序的一个基本要道是相聚信息,这不错通过查验使命站中的应用程序包或费力拜谒开荒上的应用程序数据来完成。在背面的章节中,你会发现更高等的手艺,但面前,咱们将鸠合在基础上:获取扫数已装配应用的列表,探索应用程序包,拜谒开荒上的应用程序数据目次。这应该会给你一些对于这个应用程序的布景信息,以致不需要对它进行逆向工程或推论更高等的分析。咱们将回复以下问题:
当场地是装配在开荒上的应用程序时,你起始要弄了了你想要分析的应用程序的正确包名。你不错通过 pm(Android软件包管束器)或使用 frida-ps 来检索已装配的应用程序:
你不错添加参数只骄贵第三方应用程序(-3)和它们的 APK 文献的位置(-f),随后使用 adb pull 可进行下载:
这与运行 adb shell pm path <app_package_id> 近似。
使用 frida-ps -Uai 获取已联结 USB 开荒((-U)上头前装配(-i)的扫数应用程序(a):
防范,这也骄贵了面前正在运行的应用程序的PID。记下象征符和 PID(如果有的话),以后会用到它们。
一朝相聚了场地应用程序的包名,你将但愿滥觞相聚商量它的信息。起始检索 APK,如“基本测试操作——获取和索求应用程序”中所解释的那样。
APK 文献现实上是 ZIP 文献,不错使用一个模范的 unarchiver 进行解压:
底下是被解压的文献:
AndroidManifest.xml:包含应用程序包名,场地和最低 API 品级,应用程序配置,应用程序组件,权限等的界说。
META-INF:包含应用程序的元数据MANIFEST.MF:存储应用程序资源的哈希CERT.RSA:应用程序的文凭CERT.SF:MANIFEST.MF 文献中的资源列表和相应行的 SHA-1 提要
assets:包含应用程序资源(Android 应用程序中使用的文献,举例 XML 文献,JavaScript 文献和图片)的目次,AssetManager 不错检索该目次
classes.dex:以 DEX 文献神态编译的类,Dalvik 杜撰机/ Android Runtime 不错运行。 DEX 是 Dalvik 杜撰机的 Java 字节码, 针对袖珍开荒进行了优化
lib:包含构成 APK 的第三方库的目次。
由于使用模范 unzip 器具解压会留住一些不可读的文献,如 AndroidManifest.xml,你最好使用 apktool 解压APK,正如“推选器具- apktool”中所述,解压结果如下:
Android 清单文献是信息的主要来源,它包含了好多兴致的信息,比如包名、权限、应用程序组件等等。
这里是一些信息和相应的重要字的非详备列表,你不错很容易地通过查验文献或使用 grep -i <keyword> AndroidManifest.xml在 AndroidManifest 搜索。
App权限:permission(见“Android 平台 API”)
Backup llowance:android:allowBackup(见“android上的数据存储”)
应用程序组件:activity,service, provider,receiver(见“Android 平台 API”和“Android 上的数据存储”)
可调试标志:debuggable(参见“Android应用程序的代码质地和编译设立”)
请参阅前边提到的章节来了解更多对于怎么测试这些要点的信息。
如上文“探索应用程序包”所示,应用程序的二进制文献(classes.dex)不错在应用程序包的根目次中找到。它是一个所谓的 DEX(Dalvik 可推论文献)文献,包含编译后的Java代码。由于它的特质,在一些诊疗之后,你将大要使用反编译器来生成 Java 代码。咱们还看到了运行 apktool 青年景的 smali 文献夹。它以一种叫作念 smali 的中间话语包含了反汇编的 Dalvik 字节码,这是 Dalvik 可推论文献的一种东谈主类可读的暗示。
商量怎么 DEX 文献逆向工程的更多信息,请参考“Android上的删改和逆向工程”一章中的“查验反编译 Java 代码”一节。
你不错检验 APK 中的 lib 文献夹:
或者使用 objection:
到面前为止,这是你不错获取的对于原生库的扫数信息,除非你滥觞对它们进行逆向工程,即使用不同于逆向应用程序二进制文献的方法来完成,因为代码不可反编译只可反汇编。商量怎么对这些库进行逆向工程的更多信息,请参考“Android上的删改和逆向工程”一章中的“查验原生反汇编代码”一节。
平时望望 APK 根目次中能否找到其他的资源和文献是很值得的,因为偶然它们会包含额外的好东西,如密钥存储库、加密的数据库、文凭等。
一朝你装配了应用程序,还有更多的信息需要探索,像 objection 就会派上用场了。
当使用 objection 时,你不错检索不同类型的信息,其中 env 将骄贵应用程序的扫数量录信息。
在这些信息咱们不错找到:
里面数据目次(又称沙盒目次),在 /data/data/[package-name]或 /data/user/0/[package-name]
外部数据目次在 /storage/emulated/0/Android/data/[package-name] 或 /sdcard/Android/data/[package-name]
应用程序包的旅途在 /data/app/
里面数据目次用于存储运行时创建的数据,基本结构如下:
每个文献夹都有我方的宗旨:
cache:此位置用于数据缓存,举例,在此目次中找到 WebView 缓存。
code_cache:这是文献系统的应用程序特定缓存目次的位置,遐想用于存储缓存代码。对于运行 Android 5.0(API 品级21)或更高版块的开荒,当应用或扫数这个词平台升级时,系统将删除存储在该位置的扫数文献。
lib:此文献夹存储用 C/C++ 写的原生库,这些库可能有几个文献彭胀名之一,包括 .so 和 .dll(x86援救)。此文献夹包含应用程序具有原生库平台的子目次,包括a. armeabi:扫数基于 ARM 处理器编译的代码b. armeabi-v7a:仅适用于扫数基于版块7及更高版块的 ARM 处理器编译的代码c. arm64-v8a:扫数仅基于版块8及更高版块的 ARM 64位处理器编译的代码d. x86:仅适用基于 x86 处理器编译的代码e. x86_64:仅适用基于 x86_64 处理器编译的代码f. mips:基于 MIPS 处理器编译的代码
shared_prefs:此文献夹包含一个XML文献,该文献存储通过 SharedPreferences API 保存的值。
file:此文献夹存储应用创建的通例文献。
数据库:此文献夹存储应用程序在运行时生成的 SQLite 数据库文献,举例用户数据文献。
关联词,应用程序可能不仅在这些文献夹中存储更多的数据,还会在父文献夹(/data/data/[package-name])中存储更多数据。
商量安全存储明锐数据的更多信息和最好实践,请参阅“测试数据存储”一章。
在Android上,你不错通过使用 Logcat 很容易地检验系统讯息的日记,Logcat有两种推论步地:
Logcat 是 Android Studio 中 Dalvik 调试监视器就业器(DDMS)的一部分。 如果应用程序以调试模式运行,则日记输出将骄贵在 Android Monitor 的 Logcat 选项卡上。 你不错通过在 Logcat 中界说模式来过滤应用程序的日记输出。
你不错使用 adb 推论 Logcat 来持久化存储日记输出:
使用以下敕令,不错在作用域内对应用程序的日记输出进行 grep,只需插入包名。天然,你的应用程序需要运行,以便 ps 大要获取它的 PID。
通过 tcpdump、netcat (nc) 和 Wireshark 不错实时费力嗅探扫数 Android 流量。起始,确保你的手机上有最新版块的 Android tcpdump,以下是装配要道:
如果推论 adb root 复返造作 adbd cannot run as root in production builds,如下装配 tcpdump:
你可能会碰到造作 mount: '/system' not in /proc/mounts。
在这种情况下,你不错使用 $ mount -o rw,remount / 来替代 $ mount -o rw,remount /system; 一转。
记着:要使用 tcpdump,你需要手机有 root 权限。
推论 tcpdump,望望是否灵验。一朝传入了一些包,不错按 CTRL+c 住手 tcpdump。
要费力嗅探 Android 手机的相聚流量,起始推论 tcpdump 并通过管谈将其输出到 netcat(nc):
上头的 tcpdump 敕令波及到
通过使用管谈 (|),咱们将 tcpdump 的扫数输启航送到 netcat,netcat 会在端口11111上大开一个监听器。你平时需要监视 wlan0 接口。如果你需要另一个接口,请使用敕令 $ ip addr 列出可用的选项。
要拜谒端口 11111,你需要通过 adb 将该端口转发到你的开荒上。
底下的敕令通过 netcat 将你联结到转发的端口,并通过管谈联结到 Wireshark。
Wireshark 应该立即启动(-k)。它会联结到转发端口,通过 netcat 从模范输入(-i -)中获取所稀有据,你应该能看到来自 wlan0 接口的扫数手机流量。
你不错使用 Wireshark 以可读的神态骄贵拿获的流量,弄了了使用了哪些合同以及它们是否未加密。拿获扫数流量(TCP 和 UDP)极度进军,因此你应该推论测试应用程序的扫数功能并对其进行分析。
Wireshark 和 tcpdump
Firebase 云讯息传递(FCM)是 Google 云讯息传递(GCM)的后继居品,是 Google 提供的一项免费就业,可让你在应用程序就业器和客户端应用程序之间发送讯息。就业器和客户端应用程序通过 FCM/GCM 联结就业器进行通讯,可处理下贱和上游讯息。
下贱讯息(推送见知)从应用就业器发送到客户端应用程序;上游讯息从客户端应用程序发送到就业器。
FCM 适用于 Android、iOS 和 Chrome。FCM面前提供了两种联结就业器合同:HTTP 和 XMPP。如官方文档中所述,这些合同的罢了步地不同,底下的示例演示怎么禁锢这两个合同。
您需要在你的手机上配置 iptables 或使用 bettercap 来禁锢流量。
FCM 不错使用 XMPP 或 HTTP 与谷歌后端通讯。
FCM 使用端口5228、5229和5230进行 HTTP 通讯,平时只使用端口5228。
对于 XMPP 通讯,FCM 使用端口5235(Production)和5236(Testing)。
禁锢代理必须监听上头端口转发轨则中指定的端口(端口8080)。
启动应用程序并触发一个使用 FCM 的函数,你应该能在监听代理中看到 HTTP 讯息。
动作额外的安全层,推送见知不错使用 Capillary 加密。Capillary 是一个简化从基于 Java 的应用程序就业器向 Android 客户端发送端到端(E2E)加密推送讯息的库。
有几个器具援救对依赖 HTTP(S) 合同的应用程序进行相聚分析。最进军的器具是所谓的禁锢代理,OWASP ZAP 和 Burp Suite Professional 是最有名的。一个禁锢代理给测试东谈主员一个中间东谈主的位置。这个位置对于读取和修改扫数应用程序请乞降端点反应极度有用,用于测试授权、会话、管束等。
底下的过程,为 Android Studio 3.x 附带的 Android 模拟器设立 HTTP 代理:
在模拟器设立中配置HTTP代理:a. 点击模拟器菜单栏中的三个点b. 大开设立菜单c. 单击 Proxy 选项d. 在主机名字段中输入“127.0.0.1”,在端标语字段中输入代理端口(举例,“8080”)e. 点击应用
面前应该是通过主机上的代理路来由 HTTP 和 HTTPS 恳求。如果莫得,试着关闭或大开飞机模式。
在启动 AVD 时,还不错在敕令行上使用模拟器敕令配置 AVD 的代理。底下的示例启动 AVD Nexus_5X_API_23,并将代理设立为 127.0.0.1 和端口8080。
装配 CA 文凭的一种浮浅方法是将文凭推送到开荒上,并通过安全设立将其添加到文凭存储中。举例,你不错按以下步地装配 PortSwigger (Burp)CA 文凭:
然后系统会辅导你说明文凭的装配(如果你还莫得装配过,系统还会要求设立开荒 PIN)。
对于 Android 7.0 (API 品级24)及以上版块,校服“绕过相聚安全配置”一节中描画的调换过程。
起始必须评估可用的相聚设立选项。用于测试的出动开荒和运行监听代理的机器必须联结到合并个 Wi-Fi 相聚,使用(现存的)接入点或创建一个 ad-hoc 无线相聚。
配置好相聚并在测试机器和出动开荒之间建立联结之后,还需要推论几个要道。
代理必须配置为指向禁锢代理。
禁锢代理的 CA 文凭必须添加到 Android 开荒文凭存储中真的切文凭中。用于存储 CA 文凭的菜单的位置可能取决于 Android 版块和Android OEM 对设立菜单的修改。
如果叶子文凭的灵验期延长了一定时辰(对于Chrome,则为39个月),一些应用程序可能会骄贵 NET::ERR_CERT_VALIDITY_TOO_LONG 造作。如果使用默许的 Burp CA 文凭,就会发生这种情况,因为 Burp Suite 颁发的叶文凭与其 CA 文凭具有调换的灵验性。你不错通过创建我方的 CA 文凭并将其导入到 Burp Suite 来绕过这个问题,这在 nviso.be 上的一篇博客著作中有解释。
完成这些要道并启动应用程序后,恳求应该会骄贵在禁锢代理中。
在 secure.force.com 上你不错找到在 Android 开荒上设立 OWASP ZAP 的视频。
其他一些区别:从 Android 8.0(API 品级26)滥觞,当 HTTPS 流量通过另一个联结时,应用程序的相聚步履会发生变化。而从 Android 9(AP 品级28)滥觞,在握手过程中出现造作时,SSLSocket 和 SSLEngine 在造作处理方面的步履将略有不同。
如前所述,从 Android 7.0(API 品级24)滥觞,Android OS 默许不再信任用户 CA 文凭,除非在应用程序中指定,鄙人一节中,咱们将解释绕过 Android 安全戒指的两种方法。
从 Android 7.0(API 品级24)滥觞,相聚安全配置允许应用自界说它们的相聚安全设立,通过界说应用程序信任哪些 CA 文凭。
为了罢了应用程序的相聚安全配置,需要创建一个名为 network_security_config.xml 的新 xml 资源文献。这在谷歌 Android 代码库中有详细的解释。
创建之后,应用程序还必须在清单文献中包含一个条件,以指向新的相聚安全配置文献。
相聚安全配置使用一个 XML 文献,应用程序在其中指定哪些 CA 文凭将被信任。有许多绕过相聚安全配置的方法,底下将对此进行描画,参阅在 Android P 上的相聚安全配置安全分析指南了解更多信息。
相聚安全配置有不同的配置,不错通过 src 属性添加非系统文凭的颁发机构:
每个文凭不错是下列中的一种:
一个“raw resource”ID,指向包含 X.509 文凭的文献
预装配的系统 CA 文凭的“system”
应用程序信任的 CA 文凭不错是系统信任的CA,也不错是用户信任的 CA。平时你照旧在 Android 中添加了禁锢代理的文凭动作附加 CA。因此咱们将要点关注“user”设立,该设立允许你通过以下相聚安全配置强制 Android 应用程序信任此文凭:
要罢了这个新设立,你必须校服以下要道:
通过创建包含 <certificates src="https://bbs.kanxue.com/user">的相聚安全配置,使应用程序信任用户文凭
在反编译应用程序时,插足 apktool 创建的目次,并使用 apktool 重编译应用程序,新的 apk 将在 dist 目次中
请防范,即使这种方法极度浮浅,它的主要症结是你必须对想要评估的每个应用程序应用此操作,这是额外的测试支拨。
请记着,如果您正在测试的应用程序有额外的强化门径,比如考证应用程序签名,那么你可能无法再启动该应用程序。动作重打包的一部分,你将使用我方的密钥签名应用程序,因此签名变化将导致这么的查验立即隔断程序。你需要识别和禁用这些查验通过在重新打包的应用程序修改他们或使用 Frida 动态分析。
使用 Android-CertKiller 的 python 剧本不错自动推论上述要道。这个剧本不错从装配的 Android 应用程序中索求APK,对其进行反编译,使其可调试,添加允许用户文凭的新的相聚安全配置,编译并签名新的 APK,并通过 SSL Bypass 装配新的 APK。
为了幸免为每个应用程序配置相聚安全配置,咱们必须强制开荒经受代理的文凭动作系统信任的文凭之一。
有一个 Magisk 模块,它将自动将扫数用户装配的 CA 文凭添加到系统信任的 CA 列表中。
在 Github 发布页面下载最新版块的模块,将下载的文献推送到开荒上,点击 + 按钮导入到 Magisk 管束器的“Module”视图中。终末,重新启动 Magisk Manager 以使转变见效。
从面前滥觞,通过这个 Magisk 模块,用户在“设立”,“安全性和位置”,“加密和凭据”,“从存储装配”(位置可能有所不同)装配的任何 CA 文凭都会自动由此推送到系统的信任存储中。 重新启动并考证 CA 文凭是否在“设立”,“安全和位置”,“加密和凭据”,“受信任的凭据”中列出(位置可能有所不同)。
或者,您也不错手动校服以下要道,以达到调换的结果:
使 / 系统分区可写,这可能只在 root 开荒上进行。运行 'mount' 敕令以确保 / 系统分区是可写的:mount -o rw,remount /system。如果该敕令失败,尝试运行以下敕令 mount -o rw,remount -t ext4 /system
准备代理的 CA 文凭以匹配系统文凭神态,以 der 神态导出代理文凭(这是 Burp Suite 的默许神态),然后运行以下敕令:
通过校服上述要道,你不错让任何应用程序信任代理的文凭,这允许禁锢其流量,天然,除非应用程序使用 SSL pinning。
应用程序平时罢了一些安全戒指,这些戒指使得对应用程序推论安全查验变得愈加辛苦,举例 root 检测和文凭固定。逸想情况下,你将获取启用和禁用这些戒指的两个应用程序版块,这允许你分析戒指的正确罢了,然后不错陆续使用不太安全的版块进行进一步测试。
天然,这并不老是可能的,你可能需要对启用了扫数安全戒指的应用程序推论黑盒评估。底下的部分将向您展示怎么绕过针对不同应用程序的文凭固定。
一朝你设立了一个禁锢代理而况有了一个中间东谈主的位置,你可能仍然不可看到任何东西。这可能是由于应用程序中的限定(参见下一节),但也可能是由于你所联结的 Wi-Fi 中所谓的客户端烦扰。
无线客户端烦扰是一种安全特质,它阻滞无线客户端彼此通讯。此功能对搭客和 BYOD SSID 很有用,它增多了安全级别,以限定联结到无线相聚的开荒之间的障碍和逼迫。
如果咱们需要测试的Wi-Fi具有客户端烦扰怎么办?
你不错在 Android 开荒上配置代理指向 127.0.0.1:8080,通过 USB 联结办机到札记本电脑,使用 adb 作念一个反向端口转发:
一朝你完成了这个操作,Android 手机上扫数的代理流量将会在127.0.0.1上转到8080端口,它将融会过 adb 重定向到札记本电脑上的127.0.0.1:8080,你将会在 Burp 中看到流量。使用此妙技,还不错在具有客户端烦扰的 Wi-Fi 中测试和禁锢流量。
一朝你设立了一个禁锢代理而况有了一个中间东谈主位置,你可能仍然不可看到任何东西,这主若是由于以下原因:
这款应用使用了一个近似 Xamarin 的框架,它莫得使用Android操作系统的代理设立。
你正在测试的应用程序检测了设立的代理,不允许进行任何通讯。
在这两种场景中,你都需要额外的要道终末才能看到流量,鄙人面的部分中,咱们将描画两种不同的惩办决议,bettercap 和 iptables。
还不错使用在你戒指下的接入点来重定向通讯,但这将需要额外的硬件,咱们面前主要关注软件层面的惩办决议。
对于这两个惩办决议,你需要在 Burp 激活“援救不可见代理”,在代 Proxy Tab/Options/Edit 界面。
不错在 Android 开荒上使用 iptables 将扫数通讯重定向到监听代理,底下的敕令将把端口80重定向到在端口8080上你运行的代理:
考证 iptables 设立并查验 IP 和端口。
如果你想重置 iptables 配置,不错刷新轨则:
阅读“测试相聚通讯”一章和“模拟中间东谈主障碍”测试用例,不错了解运行 bettercap 的进一步准备和说明。
运行代理的机器和 Android 开荒必须联结到合并个无线相聚。使用以下敕令启动 bettercap,将底下的 IP 地址(X.X.X.X)替换为 Android 开荒的 IP 地址。
一些出动应用程序试图检测是否设立了代理。如果是设立了,他们会以为这是坏心的,不可正常使命。
为了绕过这种保护机制,您不错设立 bettercap 或配置不需要在 Android 手机上设立代理的 iptables。咱们之前莫得提到的第三种弃取是使用 Frida,在 Android 上不错通过查询 ProxyInfo 类并查验 getHost() 和 getPort() 方法来检测是否设立了系统代理。可能还有其他多样方法来完成调换的任务,以及你需要反编译 APK,以识别现实的类和方法名。
底下您不错找到一个 Frida 剧本的模板源代码,它将匡助你重写用于考证是否设立了代理的方法,并永恒复返 false(在本例中称为 isProxySet)。即使面前配置了代理,应用程序面前也会以为莫得设立,因为函数复返 false。
一些应用程序会罢了 SSL Pinning,这将阻滞应用程序将你的禁锢文凭动作灵考文凭经受,这意味着将不可监视应用程序和就业器之间的通讯。
商量静态和动态禁用 SSL Pinning 的信息,请参考“测试相聚通讯”一章中的“绕过 SSL Pinning”。
在反逆向方面,root 检测的场地是让应用程序在一个 root 开荒上运行愈加辛苦,这反过来就禁止了一些逆向工程师可爱使用的器具和手艺。和大多数其他驻扎门径一样,root 检测自己并不是很灵验,但是在扫数这个词应用程序等分散罢了多个 root 检测不错提高扫数这个词防删改决议的灵验性。
对于 Android,咱们对“root 检测”的界说更庸碌一些,包括自界说 ROM 检测,即细目该开荒是现存的 Android 版块如故自界说版块。
鄙人一节中,咱们将列出一些常见的 root 检测方法,你会在 OWASP 出动测试指南的 crackme 示例中发现其中一些方法的罢了。
Root 检测也不错通过像 RootBeer 这么的库罢了。
SafetyNet 是一个 Android API,它提供一组就业并根据软件和硬件信息创建开荒配置文献。然后将该配置文献与已通过 Android 兼容性测试的可经受开荒模子列表进行比较。Google 建议将该功能用作“动作防滥用系调和部分的一个附加深度驻扎信号”。
SafetyNet 真的切使命步地莫得得到很好的纪录,而况可能随时改变。当你调用这个 API 时,SafetyNet 会下载一个二进制包,包含谷歌提供的开荒考证代码,然后通过反射动态推论该代码。John Kozyrakis 在《SafetyNet:谷歌的Android删改检测》中指出,SafetyNet 也尝试检测开荒是否已 root,但具体是怎么细宗旨还不了了。
要使用 API,应用程序不错调用 SafetyNetApi.attest 方法(复返带有认证结果的 JWS 讯息),然后查验以下字段:
ctsProfileMatch:如果为“ true”,则开荒配置文献与Google列出的开荒之一匹配。
basicIntegrity:如果为“ true”,则可能未对运行该应用程序的开荒进行删改。
nonces:使反应与恳求相匹配。
timestampMs:查验自你发出恳求并获取反应以来经过了多永劫辰,延伸的反应可能标明行动可疑。
apkPackageName,apkCertificateDigestSha256,apkDigestSha256:提供商量 APK 的信息,该信息用于考证调用应用程序的身份,如果 API 无法可靠地细目 APK 信息,则短缺这些参数。
以下是示例认证结果:
SafetyNet 认证 API 率先提供了一个名为 basicIntegrity 的单一值,以匡助开发东谈主员细目开荒的齐备性。跟着API的发展,谷歌引入了一种新的、更严格的查验方法,其结果以一个名为 ctsProfileMatch 的值骄贵,该值允许开发东谈主员更精细地评估运行其应用程序的开荒。
从广义上讲,basicIntegrity 给你一个对于开荒过火 API 的一般齐备性的信号。许多 root 开荒 basicIntegrity 会失败,模拟器、杜撰开荒和有删改迹象的开荒(如 API hook)亦然如斯。
另一方面,ctsProfileMatch 会给你一个对于开荒兼容性的更严格的信号,只须通过谷歌认证的未修改开荒才能通过 ctsProfileMatch。ctsProfileMatch 会失败的开荒包括:
使用加密安全的立时函数在就业器上创建一个大的(16字节或更长的)立时数,以使坏心用户无法重用奏凯的认证结果来替代不奏凯的结果
仅当 ctsProfileMatch 值为真时,才信任 APK 信息(apkPackageName, apkCertificateDigestSha256 和 apkDigestSha256)。
应该使用安全联结将扫数这个词 JWS 反应发送到就业器以进行考证。不建议在应用程序中平直推论考证,因为在这种情况下不可保证考证逻辑自己莫得被修改。
verify 方法只考证 JWS 讯息是否由 SafetyNet 签名,它不可考证判决的灵验载荷是否稳健你的预期。尽管这个就业看起来很有用,但它只是为测试宗旨而遐想的,而况它有极度严格的使用配额,每个式样每天只须10000个恳求,不会根据恳求增多。因此,您应该参考 SafetyNet 考证示例,并在就业器上以不依赖于 Google 就业器的步地罢了数字签名考证逻辑。
当发出认证恳求时,SafetyNet 认证 API 为你提供一个开荒景况的快照。一个奏凯的认证并不一定意味着该开荒在畴前就照旧通过了认证,或者在将来就融会过认证,建议策动一种战略以进行高兴用例所需的最少数量的认证。
以防护意外中达到你的 SafetyNetApi.attest配额并获取 attestation 造作,你应该编译一个系统来监视你对 API 的使用,并在达到配额之前发出警戒,这么你不错提高配额。你还应该准备克己事理于超出配额而导致的认证失败,并幸免在这种情况下结巴扫数用户。如果你接近于达到配额,或者预期短期的峰值可能会导致你向上配额,那么不错提交此表单,恳求短期或历久增多 API 密钥的配额,这个过程以及额外的配额都是免费的。
请校服此清单,以确保你已完成将 SafetyNetApi.attest API 集成到应用程序中所需的每个要道。
也许最庸碌使用的程序检测方法是查验平时会在 root 开荒上发现的文献,举例常见的 root 应用程序的包文献过火干系文献和目次,包括以下内容:
检测代码还频频查找在开荒 root 后装配的二进制文献,这些搜索包括查验 busybox 和试图大开在不同的位置 su 二进制文献:
查验 su 是否在 PATH 中也不错起作用:
不错很容易地在 Java 和原生代码中罢了文献查验。底下的 JNI 示例(改编自 rootinspector)使用 stat 系统调用检索对于文献的信息,如果该文献存在,则复返“1”。
细目 su 是否存在的另一种方法是尝试通过 Runtime.getRuntime.exec 方法推论它。如果 su 不在旅途上,就会抛出 IOException。一样的方法不错用来查验在 root 开荒上频频发现的其他程序,比如 busybox 和平时指向它的象征连结。
supersu 是面前最流行的 root 器具,它运行一个名为 daemonsu 的身份考证看管进程,因此这个进程的出现是 root 开荒的另一个标志。不错使用 ActivityManager.getRunningAppProcesses 和 manager.getRunningServices API ,ps 敕令和浏览 /proc 目次摆设正在运行的进程。底下是一个在 rootinspector 中罢了的例子:
你不错使用 Android 软件包管束器来获取已装配软件包的列表,以下包的称呼属于流行的 root 器具:
系统目次上不寻常的权限标明可能是自界说的或 root 的开荒。系统和数据目次平时是挂载只读的,但当开荒是 root 时,偶然会发现它们挂载读写的。寻找这些挂载“rw”标志的文献系统,或者尝试在数据目次中创建文献。
查验测试版块和自界说 ROM 的标志也很有匡助。一种方法是查验 BUILD 标签中的 test-key,它平时暗示自界说的 Android 镜像,查验 BUILD 标签如下:
短缺谷歌 Over-The-Air(OTA)文凭是自界说 ROM 的另一个标志:在现存的 Android 版块中,OTA 更新 Google 的公开文凭。
使用 jdb、DDMS、strace 或内核模块运行推论追踪,以了解应用程序正在作念什么。你平时会看到与操作系统的多样可疑交互,比如大开 su 以读取和获取进程列表,这些交互投降是 root 检测的信号。识别并禁用 root 检测机制,如果你正在推论黑盒弹性评估,那么禁用 root 检测机制是第一步。
为了绕过这些查验,你不错使用几种手艺,其中大部分在“逆向工程和删改”一章中先容:
查验 root 检测机制,包括以下模范:
多种检测方法分散在扫数这个词应用程序中(而不是把扫数的东西都放在一个方法中)。
root 检测机制在多个 API 层上操作(Java API、原生库函数、汇编程序/系统调用)。
这些机制在某种程度上是原创的(不是从 StackOverflow 或其他源复制和粘贴的)。
为 root 检测机制开发绕过方法,并回复以下问题:
使用模范器具(如 RootCloak )不错莽撞绕过这些机制吗?
静态/动态分析对于处理 root 检测是必要的吗?
你需要编写自界说代码吗?
奏凯绕过这些机制需要多永劫辰?
你以为绕过这些机制的难度怎么?
如果根检测缺失或太容易被绕过,请按照上头列出的灵验性模范提议建议。这些建议可能包括更多的检测机制,以及更好地将现存机制与其他驻扎机制集成。
调试是分析应用程序运行时步履的一种极度灵验的方法。它允许逆向工程师单步推论代码、在职意点住手应用程序推论、查验变量的景况、读取和修改内存等等。
反调试特质不错是正经式的,也不错是反应式的。顾名念念义,正经式反调试起始阻滞调试器进行附加,反应式反调试包括检测调试器并以某种步地对它们作念出反应(举例,隔断应用程序或触发荫藏步履)。“越多越好”的轨则适用于:为了最大化效果,驻扎者结合了多种正经和检测方法,在不同的 API 层上运行,而况散播在扫数这个词应用程序中。
正如在“逆向工程和删改”一章中提到的,咱们在 Android 上必须处理两种调试合同:咱们不错使用 JDWP 在 Java 层进行调试,也不错使用基于 ptrace 的调试器在原生层进行调试。一个好的反调试决议应该能驻扎这两种类型的调试。
在“逆向工程和删改”一章中,咱们照看了 JDWP,这是调试器和 Java 杜撰机之间的通讯合同。咱们展示了,通过给应用程序的清单文献打补丁和转变 ro. debugging 属性来启用扫数应用程序的调试是很容易的。让咱们望望开发东谈主员检测和禁用 JDWP 调试器所作念的一些事情。
咱们照旧碰到过 android:debuggable 属性。Android 清单文献中的这个标志决定是否为应用程序启动 JDWP 线程。它的值不错通过应用程序的 ApplicationInfo 对象用程序代码来细目。如果设立了标志,则说明清单文献已被删改并允许调试。
尽管这对于逆向工程师而言可能是不言而谕的,你不错使用 android.os.Debug 类中的 isDebuggerConnected 细目是否联结了调试器。
通过拜谒 DvmGlobals 的全局结构,不错通过原生代码调用调换的 API。
Debug.threadCpuTimeNanos 暗示面前哨程已推论代码的时辰,由于调试会降速进程的推论速率,因此你不错使用推论时辰的互异来推测是否已联结调试器。
在 Dalvik 中,不错通过 DvmGlobals 结构拜谒全局杜撰机景况,全局变量 gDvm 有一个指向这个结构的指针。DvmGlobals 包含多样变量和指针,这些变量和指针对于 JDWP 调试极度进军,不错被删改。
举例,将 gDvm.methDalvikDdmcServer_dispatch 函数指针设立为 NULL 会使 JDWP 线程崩溃:
即使 gDvm 变量不可用,也不错通过使用 ART 中的近似手艺禁用调试。ART运行时将与 jdwp 干系的类的一些虚函数表导出为全局象征(在 C++ 中,虚函数表是包含指向类方法的指针的表)。这包括类 JdwpSocketState 和 JdwpAdbState 的虚函数表,它们分袂通过相聚套接字和 ADB 处理 JDWP 联结。你不错通过重写关联虚函数表中的方法指针来主管调试运行时的步履。
重写方法指针的一种方法是用 JdwpAdbState:: Shutdown 的地址重写函数 jdwpAdbState:: processIncoming 的地址,这将导致调试器立即断开联结。
在 Linux 上,ptrace 系统调用用于不雅察和戒指进程(tracee)的推论,并查验和转变该进程的内存和寄存器。ptrace 是在原生代码中罢了系统调用追踪和断点调试的主要步地。大多数 JDWP 反调试妙技(对于基于计时器的查验来说可能是安全的)不会拿获基于 ptrace 的经典调试器,因此,许多 Android 反调试妙技包括 ptrace,平时愚弄了一次只可联结到进程的一个调试器这一事实。
当你调试应用程序并在原生代码上设立断点时,Android Studio 将把所需的文献复制到场地开荒并启动 lldb-server,它将使用 ptrace 附加到进程。从面前滥觞,如果你查验被调试进程的景况文献(/proc//status 或 /proc/self/status),你将看到“TracerPid”字段的值与0不同,这是调试的标志。
记着,这只适用于原生代码。如果你正在调试只使用 Java/ kotlin 的应用程序,那么“TracerPid”字段的值应该是0。
这种手艺平时应用于 C 写的 JNI 原生库中,如 Google 的 gperftools(Google 性能器具)堆查验器罢了的 IsDebuggerAttached 所示。但是,如果你但愿将此查验动作 Java/Kotlin 代码的一部分,你不错参考 Tim Strazzere 的反模拟器式样中的 hasTracerPid 方法的 Java 罢了。
当你尝试我方罢了这种方法时,不错使用 ADB 手动查验 TracerPid 的值。底下的清单使用谷歌的 NDK 示例应用 hello-jni (com.example.hellojni) 在附加 Android Studio 的调试器后推论查验:
你不错看到 com.example.hellojni(PID = 11657)的景况文献怎么包含11839的 TracerPID,咱们不错将其象征为 lldb-server 进程。
你不错通过近似于以下浮浅示例代码,将子进程附加到父进程动作调试器来防护进程调试:
附加了子进程后,进一步附加到父进程的尝试将会失败。咱们不错通过将代码编译成 JNI 函数并将其打包到咱们在开荒上运行的应用程序中来考证这极少。
使用 gdbserver 试图附加到父进程会失败并有一个造作:
但是,你不错通过杀死子进程并开释父进程而不被 trace 来莽撞地绕过这个失败。因此,你平时会发现更复杂的决议,包括多个进程和线程以及某种式样的监视来阻滞删改。常用的方法包括
让咱们望望对上述方法的一个浮浅鼎新。在开动 fork 之后,咱们在父进程中启动一个额外的线程,该线程不时监视子进程的景况。根据应用程序是在 debug 模式如故 release 模式(由清单文献中的 android:debuggable 标志暗示),子进程应该作念以下事情之一:
在 release 模式中:对 ptrace 的调用失败,子进程立即崩溃并出现段造作(退出代码11)。
在 debug 模式下:对 ptrace 的调用灵验,而况子进程应该一直运行,因此,对 waitpid(child_pid) 的调用应该永远不会复返。 如果复返了,则说明有些可疑,将杀死扫数这个词经过组。
底下是使用 JNI 函数罢了的齐备的鼎新代码:
一样,咱们把它打包到一个 Android 应用程序中,望望它是否能使命。与前边一样,当咱们运行应用程序的调试版块时,会出现两个进程。
但是,如果咱们在此时隔断子进程,父进程也会退出:
要绕过这个检测,咱们必须略微修改应用程序的步履(最浮浅的方法是用 NOP 修改对 _exit 的调用和在 libc.so 中 hook 函数 _exit)。在这极少上,咱们照旧插足了人所共知的“武备竞赛”:罢了更复杂的驻扎式样和绕过它们。
莫得通用的方法不错绕过反调试:最好的方法取决于用来防护或检测调试的机制和举座保护决议中其他的驻扎门径。举例,如果莫得齐备性查验,或者你照旧停用了它们,修改应用程序可能是最浮浅的方法。在其他情况下,一个 hook 框架或内核模块可能是更可取的。以下方法描画了绕过调试器检测的不同方法:
修改反调试功能:通过浮浅地用 NOP 指示粉饰它,来禁用不但愿的步履。防范,如果反调试机制遐想致密,可能需要更复杂的修改。
使用 Frida 或 Xposed 在 Java 和原生层 hook API:操作函数的复返值,如 isDebuggable 和 isDebuggerConnected 函数,来荫藏调试器。
改变环境:Android是一个绽开的环境。如果其他方法都不起作用,你不错修改操作系统来推翻开发东谈主员在遐想反调试妙技时所作念的假设。
在处理期凌的应用程序时,你频频会发现开发东谈主员特意荫藏原生库中的数据和功能。 在“ UnCrackable App for Android”的 Level 2 中,不错找到一个示例。
乍一看,代码看起来像之前的挑战,名为 CodeCheck 的类负责考证用户输入的代码,真实查验似乎在 bar 方法中进行,该方法被声明为原生方法。
请检验 GitHub 中针对 Android Crackme Level 2 提议的不同惩办决议。
查验反调试机制,包括以下模范:
附加 jdb 和基于 ptrace 的调试器失败或导致应用隔断或不起作用。
多种检测方法分散在应用程序的源代码中(而不是扫数的检测方法或功能都鸠合在一个方法或功能中)。
反调试驻扎在多个 API 层(Java、原生库函数、汇编程序/系统调用)上操作。
这些机制在某种程度上是原创的(而不是从 StackOverflow 或其他源复制和粘贴的)。
起劲绕过反调试驻扎,并回复以下问题:
这些机制不错被浮浅地绕过吗(举例,通过 hook 单个 API 函数)?
通过静态和动态分析识别反调试代码有多难?
你是否需要编写自界说代码来禁用驻扎?你需要些许时辰?
你对绕过这些机制的难度的主不雅评价是什么?
如果反调试机制缺失或太容易被绕过,请按照上述灵验性模范提议建议,这些建议可能包括添加更多的检测机制,以及更好地将现存机制与其他驻扎机制集成。
对于文献齐备性有两个主题:
代码齐备性查验:在“Android上的删改和逆向工程”一章中,咱们照看了 Android 的 APK 代码签名考证。咱们还发现,逆向工程师不错通过重新打包和重新签名应用程序,莽撞绕过这个查验。为了让这个绕过过程愈加复杂,不错通过对应用程序字节码、原生库和进军数据文献进行 CRC 校验来增强保护决议。这些查验不错在 Java 层和原生层上罢了,念念路是在适当的地方进行额外的戒指,以让应用程序只可在未修改的景况下正确运行,即使代码签名是灵验的。
文献存储齐备性查验:应用程序存储在 SD 卡或群众存储中的文献的齐备性以及存储在 SharedPreferences 中的键值对的齐备性应该受到保护。
当为存储自己提供齐备性时,你不错通过给定的键值对(对于 Android SharedPreferences)或者通过文献系统提供的齐备文献创建 HMAC。
在使用 HMAC 时,不错使用 bouncy castle 罢了或用 AndroidKeyStore 对给定内容进行 HMAC。
使用 BouncyCastle 生成 HMAC 时,请完成以下要道:
使用 BouncyCastle 考证 HMAC 时,请完成以下要道:
在基于 Android 密钥存储库生成 HMAC 时,最好只在 Android 6.0 (API 品级23)或更高的版块中这么作念。
以下是一个便捷的 HMAC 罢了,莫得使用 AndroidKeyStore:
提供齐备性的另一种方法是对获取的字节数组进行签名,并将签名添加到原始字节数组中。
修改反调试功能,通过使用 NOP 指示粉饰干系的字节码或原生代码来禁用不但愿的步履。
使用 Frida 或 Xposed 在 Java 和原生层上 hook 文献系统 API。复返原始文献的句柄,而不是修改后的文献。
使用内核模块禁锢与文献干系的系统调用,当进程尝试大开修改后的文献时,复返文献未修改版块的文献描画符。
对于修改、代码注入和内核模块的例子,请参考“Android上的删改和逆向工程”一章。
以未修改的景况运行应用程序,并确保一切正常。对应用程序包中的 class .dex 和率性 .so 库进行浮浅的修改。如“基本安全测试”章节所述,重新打包并重新签名应用程序,然后运行应。应用程序应该检测到修改并以某种步地作念出反应,至少应该警戒用户或隔断。起劲绕过驻扎,并回复以下问题:
应用与应用程序源代码齐备性查验近似的方法,回复以下问题:
不错浮浅地绕过这些机制吗(举例,通过转变文献或键值的内容)?
获取 HMAC 密钥或非对称私钥有多难?
你是否需要编写自界说代码来禁用驻扎?你需要些许时辰?
你以为绕过这些机制的难度怎么?
逆向工程师常用的器具、框架和应用程序由可能代表着对应用的一次逆向尝试。这些器具中的一些只可在 root 开荒上运行,而其他一些则不错使应用程序插足调试模式或依靠在手机上启动一个后台就业。因此,应用程序不错通过不同的步地来检测和应付逆向工程障碍,举例隔断自身运行。
通过查找干系的应用程序包、文献、进程或其他特定的修改器具,不错检测到以未修改的式样装配的流行的逆向工程器具。鄙人面的示例中,咱们将照看检测 Frida 器具框架的不同方法,该框架在本指南中得到了庸碌使用。其他器具,如 Substrate 和 Xposed,也不错被近似地检测出来。防范,DBI/注入/hook 器具平时不错通过运行时齐备性查验(底下将照看这些查验)隐式检测到。
举例,在 root 开荒上的默出嫁置中,Frida动作 frida-server 在开荒上运行。当你显式地附加到一个场地应用程序时(举例通过 Frida -trace 或 Frida REPL),Frida 会将 frida 代理注入到应用程序的内存中。因此,你可能会在附加到应用程序之后(而不是之前)发现它。如果你查验 /proc//maps,会发现 frida-agent 动作frida-agent-64.so 存在:
另一种方法(也适用于非 root 开荒)包括将 frida-gadget 镶嵌到 APK 中,并强制应用程序将其动作原生库之一加载。如果在启动应用程序后查验应用程序内存映射(不需要显式地附加到它),你会发现镶嵌的 frida-gadget 动作 libfrida-gadget.so 存在。
检验 Frida 留住的这两个思路,你可能照旧以为检测它们是一项微不及谈的任务。现实上,绕过这么的检测是很浮浅的事情,但事情可能会变得愈加复杂。下表简要先容了一些典型的 Frida 检测方法,并简要照看了它们的灵验性。
以下的一些检测方法在 Berdhard Mueller的著作《多种特征检测 Frida》”中被提议,请参阅它以获取更多细节和示例代码片断。
请记着,这个表格远非详备无遗。咱们不错滥觞照看定名管谈(frida-server 用于外部通讯)、检测跳板(在函数开首处插入的辗转跳转向量),这将有助于检测 Substrate 或 Frida 的禁锢器,但是也可能无效,举例对 Frida 的 Stalker 以及许多其他或多或少灵验的检测方法。它们中的每一个都将取决于你是否正在使用 root 开荒、特定版块的 root 方法或器具自己的版块。终末,这是猫捉老鼠游戏的一部分,保护在不受信任的环境(运行在用户开荒中的应用程序)上处理的数据。
需要防范的是,这些戒指只会增多逆向工程过程的复杂性。如果使用,最好的方法是巧妙地组合这些戒指,而不是单独使用它们。关联词,它们都不可保证 100% 的灵验性,因为逆向工程师老是大要完全拜谒开荒,因此老是会赢!您还必须沟通到,将一些戒指集成到应用程序中可能会增多应用程序的复杂性,以致会影响其性能。
在测试开荒中装配多样逆向工程器具和框架然后启动应用程序。至少包括:Frida, Xposed,Substrate for Android, Drozer, RootCloak, Android SSL Trust Killer。
应用程序应该以某种步地反应这些器具的存在。举例:
接下来,绕过逆向工程器具的检测,回复以下问题:
以下要道将携带你绕过逆向工程器具检测:
修改反逆向工程功能,通过使用 NOP 指示粉饰干系的字节码或原生代码来禁用不但愿的步履。
使用 Frida 或 Xposed 在 Java 和原生层上 hook 文献系统 API,复返原始文献的句柄,而不是修改后的文献。
使用内核模块禁锢与文献干系的系统调用,当进程尝试大开修改后的文献时,复返文献未修改版块的文献描画符。
对于修改、代码注入和内核模块的例子,请参考“Android上的删改和逆向工程”一章。
在防逆向方面,模拟器检测的宗旨是增多在模拟器开荒上运行应用程序的难度,这禁止了逆向工程师使用某些可爱的器具和手艺。这种难度的增多强制逆向工程师去抵御模拟器检测或使用真实的物理开荒,从而限定了大鸿沟开荒分析所需的拜谒。
有几个宗旨不错标明开荒是模拟器。尽管扫数这些 API 调用都不错 hook,但这些宗旨提供了第一谈防地。
第一组宗旨在 build.prop 文献中。
你不错在 root 的 Android 开荒上裁剪文献 build.prop,也不错在从源代码编译 AOSP 时对其进行修改,两种手艺都不错让你绕过上头的静态字符串查验。
下一组静态宗旨愚弄 Telephony manage。扫数 Android 模拟器都有固定的值,这个 API 不错查询。
请记着 hook 框架,如 Xposed 和 Frida,都能 hook 这个 API 提供空虚的数据。
在模拟器中装配并运行应用程序。应用程序应该检测到它正在模拟器中推论,并隔断或拒却推论本应受到保护的功能。
起劲绕过驻扎,并回复以下问题:
此类别中的戒指会考证应用程序内存空间的齐备性,以保护应用程序不受在运行时的内存补丁的影响。这些补丁包括对二进制代码、字节码、函数指针表和进军数据结构不但愿的修改,以及加载到进程内存中的坏心代码。齐备性可通过以下步地考证:
这与“检测逆向工程器具和框架”有一些重复,事实上,咱们在那一章中展示了基于签名的方法,其时咱们展示了怎么搜索进程内存寻找 Frida 干系的字符串的,底下是多样齐备性监控的更多示例。
底下的检测代码来自 dead && end 的博客。
通过使用 ELF 二进制文献,腹地函数 hook 不错通过重写内存中的函数指针(举例,Global Offset Table 或 PLT hook)或修改函数代码自己的一部分(内联 hook)来装配。查验各自内存区域的齐备性是检测这种 hook 的一种方法。
Global Offset Table(GOT)用于分解库函数。在运行时,动态连结器会使用全局象征的皆备地址对该表进行修改。GOT hook 会重写存储的函数地址,并将正当的函数调用重定向到逆向者的代码。不错通过摆设进程内存映射并考证每个 GOT 条件指向正当加载的库来检测这种类型的钩子。
与之相背,GNU ld 只在第一次需要象征地址时才分解象征地址(惰性绑定),Android 连结器分解扫数外部函数,并在加载库之后立即写入相应的 GOT 条件(立即绑定)。因此,您不错期许扫数 GOT 条件在运行时都指向它们各自库的代码部分中的灵验内存位置。GOT hook 检测方法平时会遍历GOT并进行考证。
内联 hook 的使命步地是在函数代码的开首或落幕粉饰一些指示。在运行时,这个所谓的跳板将重定向推论注入的代码。你不错通过查验库函数的开首和落幕是否有可疑指示来检测内联 hook,举例可疑的跳转,会跳到库外位置。
确保禁用了扫数基于文献的逆向工程器具的检测。然后,使用 Xposed、Frida 和 Substrate 注入代码,并尝试装配原生 hook 和 Java 方法hook。应用程序应该大要检测到内存中的“坏心”代码,并作念出相应的反应。
使用以下手艺绕过查验:
修改齐备性查验,通过使用 NOP 指示粉饰相应的字节码或原生代码来禁用不但愿的步履。
使用 Frida 或 Xposed 来 hook 用于检测的 API 然后复返空虚值。
对于修改、代码注入和内核模块的例子,请参考“Android上的删改和逆向工程”一章。
期凌是将代码和数据诊疗为更难连络的过程,它是每个软件保护决议中不可分割的一部分。需要连络的进军极少是,期凌不是不错浮浅大开或关闭的东西,程序代码可能以多种步地、不同程度变得完全或部分不可连络。
在“Android 应用程序的代码质地和构建设立”一章的测试案例“Make Sure That Free Security Features Are Activated (MSTG-CODE-9)”中,咱们描画了一些基本的期凌手艺,这些手艺一般通过 R8 和 Pro-Guard 在 Android 上使用。
尝试反编译字节码,反汇编包含的库文献,并进行静态分析,至少应用程序的中枢功能(举例要期凌的功能)不应该被容易识别,考证以下内容:
要进行更详细的评估,你需要详细了解干系逼迫和所使用的期凌方法。
开荒绑定的场地是阻滞障碍者试图将应用过火景况从开荒 A 复制到开荒 B ,并陆续在开荒 B 上推论该应用程序。细目开荒 A 是确切任的之后,它可能比开荒 B 具有更多的特权。将应用程序从开荒 A 复制到开荒 B 时,这些互异特权不应转变。
在描画可用象征符之前,让咱们快速照看怎么将它们用于绑定,这里有三种方法运行开荒绑定:
使用开荒象征符增强用于身份考证的凭据,如果应用程序需要频繁地重新对其自身或用户进行身份考证,这是特意旨的。
使用与开荒安详绑定的密钥材料对存储在开荒中的数据进行加密不错加强开荒绑定,Android 密钥库提供了不可导出的私钥,咱们不错将其用于此宗旨。当坏心步履者从开荒索求此类数据时,由于无法拜谒密钥,因此无法解密数据,要罢了此场地,请推论以下要道:a. 使用 KeyGenParameterSpec API 在 Android 密钥存储库中生成密钥对。
b. 为 AES-GCM 生成一个密钥:
c. 通过 AES-GCM 加密,使用密钥对认证数据和应用程序存储的其他明锐数据进行加密,并使用实例 ID 等开荒特定参数动作关联数据:
d. 使用存储在 Android 密钥存储库中的公钥加密密钥,并将加密的密钥存储在应用程序的独到存储中。
e. 当需要拜谒令牌等身份考证数据或其他明锐数据时,使用存储在 Android 密钥存储库中的私钥对密钥进行解密,然后使用解密后的私钥对密文进行解密。
畴前,Android 开发者频频依赖于Settings.Secure.ANDROID_ID (SSAID)和MAC 地址。跟着 Android 8.0(API 品级26)的发布,这种情况有所改变。由于 MAC 地址在莫得联结到接入点时平时是立时的,因此 SSAID 不再是一个绑定开荒的 ID,而是一个绑定到用户、开荒和恳求 SSAID 的应用程序的签名密钥的值。此外,在谷歌的 SDK 文档中商量于象征符的新建议。基本上,谷歌建议:
请防范,Instance ID 和 Advertising ID 在开荒升级和开荒重置之间并不褂讪,但是 Instance ID 至少允许识别开荒上头前装配的软件。。
有几种方法不错测试应用程序绑定。
你不错陆续通过身份考证吗? 如果是这么,则绑定可能无法正常使命。
在你的 root 开荒上运行应用程序。
谷歌 Instance ID 使用令牌对正在运行的应用程序实例进行身份考证,当应用程序被重置、卸载等时候,实例 ID 被重置,这意味着你将领有该应用程序的新“实例”。 通过以下要道获取 Instance ID:
设立 Google Play 就业,在文献 build.gradle 中,添加
获取一个 Instance ID
生成令牌。
确保在无效的开荒信息,安全性问题等情况下,不错处理来自 Instance ID 的回调,这需要彭胀 Instance IDListenerService 并在那里处理回调:
请防范,Firebase 也援救 Instance ID。
谷歌建议不要使用这些象征符,除非应用程序处于高风险中。
在 Android 8.0(API 品级26)之前的 Android 开荒,不错恳求如下序列号:
对于运行 Android 版块 O 及更高版块的开荒,不错通过底下步地恳求开荒的序列号:
获取序列号:
检索 IMEI:
在你的 Android 清单中设立需要的权限:
谷歌建议不要使用这些象征符,除非应用程序处于高风险中。你不错如下检索 SSAID :
自 Android 8.0(API 品级26)以来,SSAID 和 MAC 地址的步履已转变。此外, Google SDK 文档中还提供了商量象征符的新的建议。由于这种新步履,咱们建议开发东谈主员不要仅依赖SSAID。象征符变得不褂讪起来,举例复原出厂设立后或升级到Android 8.0(API 品级26)后重新装配应用程序时,SSAID 可能会转变。有些开荒具有调换的 ANDROID_ID 或具有的 ANDROID_ID 不错被粉饰。因此,最好使用从 AndroidKeyStore 中立时生成的密钥,用 AES_GCM 加密 ANDROID_ID。然后应将加密的 ANDROID_ID 存储在 SharedPreferences 中(奥秘的)。一朝应用程序签名转变,应用程序就不错查验 delta 并注册新的 ANDROID_ID。如果在莫得新的应用程序签名密钥的情况下进行了转变,则应标明存在其他问题。
当源代码可用时,你不错寻找一些重要术语:
为了确保不错使用象征符,请查验 AndroidManifest.xml 中 IMEI 和 Build.Serial 的用法。 该文献应包含权限 <uses-permission android:name =“ android.permission.READ_PHONE_STATE” />。
当 Android 8.0(API 品级26)的应用程序恳求 Build.Serial 时,其结果将为“UNKNOWN”
有几种动态测试开荒绑定的方法,见前边“使用模拟器动态分析”和“使用不同的 root 开荒”。
MSTG-RESILIENCE-1:“应用程序通过提醒用户或隔断应用程序来检测到已生根或逃狱的开荒并对其作念出反应。”
MSTG-RESILIENCE-2:“应用程序阻滞调试或检测并反应所附加的调试器,必须粉饰扫数可用的调试合同。”
MSTG-RESILIENCE-3:“应用程序会检测并反应其自身沙箱中的可推论文献和重要数据的删改。”
MSTG-RESILIENCE-4:“应用程序不错检测并反应开荒上使用庸碌的逆向工程器具和框架。”
MSTG-RESILIENCE-5:“应用程序检测并反应在模拟器中运行的情况。”
MSTG-RESILIENCE-6:“应用程序检测并反应付其自身存储空间中的代码和数据的删改。”
MSTG-RESILIENCE-9:“期凌应用于编程驻扎,这反过来会禁止通过动态分析去期凌。””
MSTG-RESILIENCE-10:“应用程序通过开荒的多种非常属性获取开荒指纹罢了了开荒绑定功能。”
[防范]传递专科学问、拓宽行业东谈主脉——看雪讲师团队等你加入!女同 t p