一文入门Android逆向 – 作者:tales

本文节主要介绍一下Android逆向常用的环境、工具、动静态分析思路,笔者通过学习肉丝大佬分享的一些内容,加上自己一些经验总结而来。

1、环境准备

环境也分三六九等,一个好的环境能让你节省大量时间和精力去投入到更有意义的事情中,所以Android移动安全第一步,就是配置一套无坑的环境,首先是硬件配置如下:

Kali-linux-2019-4-vmware-amd64

一台Nexus6P手机

一台Pixel XL手机

1.1、VMware虚拟机

1、下载并安装虚拟机后,注册码百度搜索注册即可。

VMware workstation下载(Windows)

VMware Fusion下载(Mac)

2、下载并运行kali虚拟机

kali-linux-2019-4-vmware-amd64-zip.torrent

3、Kali更改时区:

dpkg-reconfigure tzdata
然后选择`Asia→Shanghai`,然后重启即可。

4、更新源apt update

5、安装中文字体

apt install xfonts-intl-chinese

apt install ttf-wqy-microhei

1.2、Android studio

1、访问官网并下载最新版android studio

wget https://redirector.gvt1.com/edgedl/android/studio/ide-zips/4.0.1.0/android-studio-ide-193.6626763-linux.tar.gz

2、新建第一个Android项目

1598406800.png!small

3、耐心等待android-studio加载完成即可

如果下载速度过慢,可配置代理重新加载。

1598406964.jpg!small

1.3、Genymotion模拟器

1、genymotion下载

2、选择Android8.0版本,并选择主网卡设置为桥接模式

1598407021.jpg!small

3、运行模拟器,并消除wifi感叹号以及时间同步

在模拟器的shell里以root用户执行:

settings put global captive_portal_http_url https://www.google.cn/generate_204
settings put global captive_portal_https_url https://www.google.cn/generate_204
settings put global ntp_server 1.hk.pool.ntp.org
reboot

1.4、Genymotion ARM Translation

1、Genymotion是基于X86的,不支持ARM架构。所以有些应用是基于ARM架构编译的就无法安装,出现如下提示:

image

2、解决方法

安装ARM Translation tool

下载与Genymotion模拟器相对应的Android版本的Genymotion-ARM-Translation.zip

然后将该文件直接拖入Genymotion,点OK开始安装

image

安装完点OK,重启一下Genymotion即可

image

1.5、常用工具

1、命令工具

tmux: 可以关闭窗口将程序放在后台运行

jnettop: 监测网络流量,得到通讯IP、端口、URL、速率信息

netstat -tunlp:端口对应进程号、监听、收发包端口

htop: top 的增强版,当前系统负载、前台活跃进程、线程和占用

apt install tmux jnettop htop

1598407073.jpg!small

2、QtScrcpy

Android实时投屏软件

https://gitee.com/Barryda/QtScrcpy/releases

image

3、wifi adb

连接WIFI自动开启网络调试

https://www.apkmirror.com/apk/metactrl/wifi-adb-debug-over-air/

image

kali虚拟机adb连接模拟器:

直接adb devices时提示没设备,可以先使用adb connect 192.168.3.18:5555

1598407111.jpg!small

4、termux

Android终端模拟器应用程序,可直接运行而无需生根或安装。自动安装了最小的基本系统-使用APT软件包管理器可以使用其他软件包

https://termux.com/

image

5、Neofetch

在终端中显示Linux系统信息,可以连接手机查看手机系统信息

1598407130.jpg!small

2、四大组件与系统架构

2.1、Android四大组件

1、Activity

1、一个Activity通常就是一个单独的窗口
2、Activity之间通过Intent进行通信。
3、Activity应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。

2、Service

1、Started(启动):当应用程序组件(如Activity)调用StartService()方法启动服务时,服务处于Started状态。
2、bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。
3、Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。

3、Content provider

1、Android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。
2、只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。
3、ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。
4、开发人员不会直接使用ContentProvider类的对象,大多数是通过ContentResolver对象实现对ContentProvider的操作。
5、ContentProvider使用URI来唯一标识其数据集,这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。

4、Broadcast Receiver

1、你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
2、广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。
3、动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。

2.2、Android系统架构

Android采用分层的架构,分为四层,从高层到底层分为应用程序层(app+System apps),应用程序框架层(Java API Framework),系统运行库和运行环境层(Libraries + android Runtime)和Linux核心层(HAL+ Linux Kernel)

image

2.3、Android常用开发与逆向命令总结

1、file查看文件属性

2、使用echo命令写内容到文件中,然后利用cat读取文件内容。

3、使用dumpsys命令获取当前顶层activity的信息,grep进行过滤,-i参数忽略大小写。

image

4、ls -alit按时间排序显示当前目录全部信息。

5、dumpsys package com.termux查看该APP内存中的信息

1598407165.jpg!small

6、ps -e显示全部进程

ps -e |grep -i termux

7、dumpsys dbinfo com.termux查看数据库信息

image

8、adb pull /sdcard/app将手机中的文件拷贝到电脑当前目录下

adb push D:\tmp.txt /sdcard将本地文件放到手机中

注:如遇到权限问题,使用chmod改权限

9、adb forward端口转发

10、adb logcat查看当前日志信息

adb logcat |grep -i com.termux

1598407192.jpg!small

11、指定连接某台设备的adb shell

adb -s 192.168.3.18:5555 shell

12、查看某端口对应的进程名

netstat -tunlp |grep 7001  # 端口
netstat -tunlp |grep "com.termux" # 进程名
netstat -aple |grep -i https #正在通信的端口,查看使用https的通信

1598407215.jpg!small

13、htop实时查看手机进程

手机普通用户termux安装

pkg install htop

image

手机root用户查看htop,全部进程

$ su
# /data/data/com.termux/files/usr/bin/htop

image

3、刷机

3.1、推荐环境

  • Frida两套环境:

1、pixel(sailfish)+官方8.1.0_r1+twrp3.3.0+Magisk+Frida

2、pixel(sailfish)+twrp3.3.0+lineage16.0+addonsu16.0

  • Xposed一套环境:

1、pixel(sailfish)+官方7.1.2_r8+twrp3.2.1-0+SuperSU+XposedInstaller

  • Fart同Aosp两套环境:

1、pixel(sailfish)+最新fastboot+Fart8.1.0

2、n6p(angler)+老fastboot+Fart8.1.0

  • Kali NetHunter一套环境:

1、n6p(angler)+原生8.1.0_r1+twrp3.3.1+SuperSu

3.2、n6p(angler)+官方8.1.0_r1+twrp3.3.1+Magisk+Frida

下面带领大家刷两套常用手机环境。

搜镜像并下载8.1.0 (OPM1.171019.011, Dec 2017)

https://developers.google.com/android/images

然后下载对应手机型号的安装包

1598407245.jpg!small

root@tale:~/Desktop# wget https://dl.google.com/dl/android/aosp/angler-opm1.171019.011-factory-39448337.zip
root@tale:~/Desktop# 7z x angler-opm1.171019.011-factory-39448337.zip

1、将fastboot添加环境变量

# nano ~/.bashrc
添加export PATH=/root/Android/Sdk/platform-tools:$PATH
# source ~/.bashrc

2、手机完全关机,按住下音量键+关机键,进入bootloader模式

root@tale:~/Desktop/angler-opm1.171019.011# ./flash-all.sh

image

部分较老机型在使用fastboot刷入8.1.0_r1版本的FART时(比如bullhead),会出现各种奇怪错误,原因是使用高版本的fastboot会报错:

1598407265.jpg!small

复制自己编译的fastboot替换原文件即可。

# which fastboot
# mv /root/Desktop/fastboot Android/Sdk/platform-tools/fastboot
# chmod 777 fastboot

image

提示finished之后手机会进入重启状态

image

选择中文后,一直点下一步进入手机主屏幕,然后设置休眠时间长一些,再去点击10次版本号,打开开发者选项,打开“不锁定屏幕”

-关闭“自动系统更新”-开启“USB调试”

image

3.2.1、使用Magisk获取root

https://twrp.me/

选择TWRP 3.3.1-0 Released,然后点击devices page

image

选择Primary (Europe)

image

下载拷贝到kali虚拟机

手机进入bootloader模式,然后使用fastboot flash recovery命令

# adb reboot bootloader
# fastboot flash recovery twrp-3.3.1-0-angler.img 
注:刷pixel XL使用
# fastboot boot twrp-3.3.1-0-marlin.img

然后手机按两下向下音量键,点击开关键进入recovery mode模式

滑动进入后选择settings,然后取消“Enable screen timeout”

下载Magiskfrida-server

# wget https://github.com/topjohnwu/Magisk/releases/download/v20.4/Magisk-v20.4.zip
# adb push Magisk-v20.4.zip /sdcard/
# wget https://github.com/frida/frida/releases/download/12.11.10/frida-server-12.11.10-android-arm64.xz
# 7z x frida-server-12.11.10-android-arm64.xz 
放到官网推荐目录下
# adb push frida-server-12.11.10-android-arm64 /data/local/tmp/

然后点击install选项,找到Magisk-v20.4.zip,点进去之后向右滑动进行安装,完成之后点击Reboot System选择Do Not install

image

启动手机后,运行wifi adb时会弹出root请求选项,如下

image

3.2.2、启动frida-server

然后我们去开启手机frida-server

➜  ~ adb shell
angler:/ $ whoami
shell
angler:/ $ su
angler:/ # whoami
root
angler:/ # cd /data/local/tmp/
angler:/data/local/tmp # ls
frida-server-12.11.10-android-arm64 oat
angler:/data/local/tmp # chmod 777 frida-server-12.11.10-android-arm64                      
angler:/data/local/tmp # ./frida-server-12.11.10-android-arm64 &
[1] 8096

至此该套n6p(angler)+官方8.1.0_r1+twrp3.3.1+Magisk+Frida环境已刷成功。

3.3、n6p(angler)+官方8.1.0_r1+twrp3.3.1+SuperSu+NetHunter

2020年4月初,Kali在其官方博客上释出了最新的Kali Nethunter 2020.1,带来了全新的Kali NetHunter RootlessKali NetHunter Lite,同时对完整版Kali Nethunter进行了更加深入的优化,使用了全新的内核编译工具,从内核全面支持USB键盘、光驱和网卡模拟,功能更加强大,系统更加稳定。可以连上显示器和键鼠,直接成为一台电脑,直接把桌面环境带着走。

image

Kali Nethunter的完整镜像不是所有手机都能装的,只有官网支持的设备才能装。这里使用Nexus 6p(angler)进行举例,主要流程分四步:

  • 刷入官方原版镜像:
  • recovery:twrp
  • root:选择经典的SuperSU
  • 刷入Kali Nethunter

3.3.1、刷入官方原版镜像

首先完全关机,按住音量下+关机键,或直接使用如下命令,进入bootloader模式

# adb reboot bootloader
# cd angler-opm1.171019.011/
# ./flash-all.sh

3.3.2、三方recovery:twrp

# adb reboot bootloader
# fastboot flash recovery twrp-3.3.1-0-angler.img

3.3.3、使用SuperSU获取root

按两下音量↓键,开机键确认进入recovery mode
# adb push SR5-SuperSU-v2.82-SR5-20171001224502.zip /sdcard
然后安装SuperSU即可

3.3.4、刷入Kali Nethunter

下载Nexus 6P Oreo

https://www.offensive-security.com/kali-linux-nethunter-download/
root@tale:~# proxychains wget https://images.kali.org/nethunter/nethunter-2020.3-angler-oreo-kalifs-full.zip
# adb push /Users/tale/Downloads/nethunter-2020.3-angler-oreo-kalifs-full.zip /sdcard/
# adb reboot bootloader
按两下音量↓键,开机键确认进入recovery mode
然后选择安装Nethunter即可

刷机结束后进入系统首次也要先点击Nethunter的应用,申请的所有权限都给,左侧导航进入Kali Chroot Manager,点击START KALI CHROOT,只要初始化这一次,后续无论如何重启都会出现如图所示的Everything is fine and Chroot has been started!

至此详细刷机流程结束。

1598407303.jpg!small

3.3.5、使用Kali Nethunter

1、点开Nethunter这个app,给它所有的权限,左上角选择Kali Chroot Manager页面,看到chroot系统初始化完成。

2、点开Nethunter终端这款App,选择KALI,进入Kali系统。

3、apt update升级系统中的软件库信息。

4、可以安装linux环境才能跑的命令程序,如apt install neofetch htop jnettop等。

5、打开Nethunter这个应用,左上角切换到KeX Manager,点击“SETUP LOCAL SERVER”,输入一个连接密码和显示密码,输入和确认即可,然后点击“START SERVER”开启服务器。点开“KeX Client”这个App,在密码那一栏输入密码之后,点击“Connect”进行连接,即可直接进入Kali Nethunter操作系统的桌面。

1598407314.jpg!small

6、配合QtScrcpywifiadb更方便的从电脑操控手机,并不用连接数据线

7、可以在此手机系统运行操作burpWireshark来抓包,手机SIM卡的流量也可以抓到。

8、Kali Nethunter为诸多USB设备和无线网卡打上了驱动补丁,可以在手机上直接制作路由器,然后在网卡上进行抓包。(以后会发文章详情介绍)

制作路由器来抓包可以彻底解决抓不到包的问题,因为在路由器上抓包,对于一个App来说日常使用是没有区别的,所以可以做到对App的完全无感知的,从上帝视角对APP进行全面监控。

4、动静态分析

下面以具体一个恶意APP为实例,运用动静态分析方法结合工具使用来分析该APP。

通过模拟器安装该APP发现场面高能,背景和背景音乐非常不健康(笔者差点身败名裂),并且音量被调到最大,循环播放无法关闭,屏幕也被锁定无法关闭。

4.1、静态分析

静态分析原理基本就是一个反汇编过程,常用的静态分析工具为jadxjebgda,当我们拿到手分析一款APP时,基本先反编译、解包大致查看APK里的内容,下图为jadx-gui反编译之后的情况。

# proxychains wget https://github.com/skylot/jadx/releases/download/v1.1.0/jadx-1.1.0.zip

1598407330.jpg!small

可以看到该APP并没有加壳,然后我们解压APK文件后,发现在r文件夹下存放了资源文件(包括多人运动的图片与声音),dex为Dalvik虚拟机可执行文件,resources存放了一些字符串,meta包含该APP签名信息,AndroidManifest文件中包含了APP的配置信息。

image

将要分析的APP文件拖入jeb之后,进入MainActivity,然后选择Decompile,通过代码分析发现该APP首先注册了Broadcast,然后寻找该类Class.forName("com.shimeng.qq2693533893.MyServiceOne"),最后用startService来启动该类。主要逻辑在MyServiceOne类里。

1598407341.jpg!small

点开MyServiceOne发现里面有祝福的话

1598407350.jpg!small

通过在模拟器运行该APP发现,连接模拟器的ADB断掉,而且重启模拟器会自动弹出APP的页面并且自动播放声音,该声音无法关掉,而且重启手机后也会自动播放声音。

setprop persist.sys.usb.config none执行断掉自身USB的操作。

1598407359.jpg!small

4.2、动态分析

动态分析在运行代码的情况下,通过跟踪分析相关的内存,如寄存器内容,函数执行结果,内存使用情况等等,分析函数功能,明确代码逻辑。

objection是由Frida提供支持的运行时移动探索工具包,旨在帮助您评估移动应用程序的安全状况

# wget https://bootstrap.pypa.io/get-pip.py
# python3 get-pip.py
# pip install objection
# objection version
# adb push frida-server-12.11.10-android-arm64  /data/local/tmp
# adb shell
# su
# cd /data/local/tmp
# chmod 777 *
# ./frida-server-12.11.10-android-arm64
# objection -g com.android.settings explore

1598407375.jpg!small

通过objection动态分析该APP,不过因要分析的恶意APP会自动断掉USB连接,所以我们在模拟机上用termux运行frida服务,并监听8888端口,用电脑去连接监听的端口。

vbox: # ./frida-server-12.11.10-android-x86 -l 0.0.0.0:8888

通过frida-ps找到该APP包名com.shimeng.qq2693533893

# frida-ps -H 192.168.56.101:8888

配合加载Wallbreaker插件,更方便的搜索查看Android内存中的类结构、实例、内部数据等。

# git clone https://github.com/hluwa/Wallbreaker ~/.objection/plugins/Wallbreaker
# objection -N -h 192.168.56.101 -p 8888 -g com.android.settings explore -P ~/.objection/plugins

1598407394.jpg!small

通过动静态结合分析了解大致逻辑在com.shimeng.qq2693533893.MyServiceOne类中,操作按解除锁定后,然后hook该类

com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class com.shimeng.qq2693533893.MyServiceOne

image

1598407410.jpg!small

首先观察objection发现一直调用该函数access$L1000018

然后hook该方法

com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class_method com.shimeng.qq2693533893.MyServiceOne.access$L1000018 --dump-ba
cktrace

1598407427.jpg!small

发现一直在调用MyServiceOne$100000007,通过静态分析找到100000007,发现该方法是调用getStreamMaxVolume系统音量最大的api,所以该APP运行之后无法关闭音量。

1598407440.jpg!small

回头来看我们输入的解锁码然后打印出来的内容,相当于输入了一个解锁码的参数,下图涉及到的调用方法即APP的执行流程。

com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class com.shimeng.qq2693533893.MyServiceOne

1598407452.jpg!small

然后hook颜如玉方法

com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class_method com.shimeng.qq2693533893.MyServiceOne.
颜如玉 --dump-args --dump-backtrace --dump-return

1598407471.jpg!small

点击再点解锁,发现打印出了参数、返回值、调用栈。

1598407484.jpg!small

根据打印出的内容继续跟踪该类com.shimeng.qq2693533893.MyServiceOne$100000002

发现主要的判断逻辑如下,如果与9DDEB743E935CE399F1DFAF080775366相等,则移除MyServiceOne.this.util.removeView(),进入sm2

if(颜如玉QQ2693533893.getSaltMD5(MyServiceOne.颜如玉(v2.substring(0, 3))) + v2.substring(3, v2.length()).equals(“9DDEB743E935CE399F1DFAF080775366” + v3_1)) {

MyServiceOne.this.util.removeView();

MyServiceOne.this.sm2();

1598407498.jpg!small

至此,利用动态分析我们将更准确的定位到关键性逻辑,相比搜索字符串碰运气,更快捷靠谱。

5、脱壳

将解包后的dex文件导入010Editor进行分析查看,发现文件头为dex035,比较常用的葫芦娃脱壳机FRIDA-DEXDump的原理是采用暴力搜索内存中dex035进行特征匹配

# proxychains wget https://www.sweetscape.com/download/010EditorLinux64Installer.tar.gz
# tar zxvf 010EditorLinux64Installer.tar.gz 
# ./010EditorLinux64Installer

1598407511.jpg!small

个人比较常用的FRIDA-DEXDump如作者所说可实现三秒脱壳。

https://github.com/hluwa/FRIDA-DEXDump
默念一声"我想脱个壳"。
启动 APP。
启动 frida-server。
python main.py。
默数三秒,脱好了。

1598489695.jpg!small

6、总结

越学越菜

来源:freebuf.com 2020-08-27 08:55:12 by: tales

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论