本文节主要介绍一下Android
逆向常用的环境、工具、动静态分析思路,笔者通过学习肉丝大佬分享的一些内容,加上自己一些经验总结而来。
1、环境准备
环境也分三六九等,一个好的环境能让你节省大量时间和精力去投入到更有意义的事情中,所以Android移动安全第一步,就是配置一套无坑的环境,首先是硬件配置如下:
Kali-linux-2019-4-vmware-amd64
一台Nexus6P手机
一台Pixel XL手机
1.1、VMware虚拟机
1、下载并安装虚拟机后,注册码百度搜索注册即可。
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项目
3、耐心等待android-studio
加载完成即可
如果下载速度过慢,可配置代理重新加载。
1.3、Genymotion模拟器
2、选择Android8.0
版本,并选择主网卡设置为桥接模式
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架构编译的就无法安装,出现如下提示:
2、解决方法
安装ARM Translation tool
下载与Genymotion
模拟器相对应的Android
版本的Genymotion-ARM-Translation.zip
然后将该文件直接拖入Genymotion
,点OK开始安装
安装完点OK,重启一下Genymotion
即可
1.5、常用工具
1、命令工具
tmux
: 可以关闭窗口将程序放在后台运行
jnettop
: 监测网络流量,得到通讯IP、端口、URL、速率信息
netstat -tunlp
:端口对应进程号、监听、收发包端口
htop
: top 的增强版,当前系统负载、前台活跃进程、线程和占用
apt install tmux jnettop htop
2、QtScrcpy
Android
实时投屏软件
https://gitee.com/Barryda/QtScrcpy/releases
3、wifi adb
连接WIFI自动开启网络调试
https://www.apkmirror.com/apk/metactrl/wifi-adb-debug-over-air/
kali虚拟机adb连接模拟器:
直接adb devices
时提示没设备,可以先使用adb connect 192.168.3.18:5555
4、termux
Android
终端模拟器应用程序,可直接运行而无需生根或安装。自动安装了最小的基本系统-使用APT软件包管理器可以使用其他软件包
https://termux.com/
5、Neofetch
在终端中显示Linux
系统信息,可以连接手机查看手机系统信息
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)
2.3、Android常用开发与逆向命令总结
1、file
查看文件属性
2、使用echo
命令写内容到文件中,然后利用cat
读取文件内容。
3、使用dumpsys
命令获取当前顶层activity
的信息,grep进行过滤,-i参数忽略大小写。
4、ls -alit
按时间排序显示当前目录全部信息。
5、dumpsys package com.termux
查看该APP内存中的信息
6、ps -e
显示全部进程
ps -e |grep -i termux
7、dumpsys dbinfo com.termux查看数据库信息
8、adb pull /sdcard/app
将手机中的文件拷贝到电脑当前目录下
adb push D:\tmp.txt /sdcard
将本地文件放到手机中
注:如遇到权限问题,使用chmod改权限
9、adb forward
端口转发
10、adb logcat
查看当前日志信息
adb logcat |grep -i com.termux
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的通信
13、htop
实时查看手机进程
手机普通用户termux
安装
pkg install htop
手机root
用户查看htop
,全部进程
$ su # /data/data/com.termux/files/usr/bin/htop
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
然后下载对应手机型号的安装包
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
部分较老机型在使用fastboot
刷入8.1.0_r1
版本的FART
时(比如bullhead),会出现各种奇怪错误,原因是使用高版本的fastboot
会报错:
复制自己编译的fastboot
替换原文件即可。
# which fastboot # mv /root/Desktop/fastboot Android/Sdk/platform-tools/fastboot # chmod 777 fastboot
提示finished
之后手机会进入重启状态
选择中文后,一直点下一步进入手机主屏幕,然后设置休眠时间长一些,再去点击10次版本号,打开开发者选项,打开“不锁定屏幕”
-关闭“自动系统更新”-开启“USB调试”
3.2.1、使用Magisk获取root
选择TWRP 3.3.1-0 Released
,然后点击devices page
选择Primary (Europe)
下载拷贝到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”
下载Magisk
、frida-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
启动手机后,运行wifi adb
时会弹出root
请求选项,如下
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 Rootless
和Kali NetHunter Lite
,同时对完整版Kali Nethunter
进行了更加深入的优化,使用了全新的内核编译工具,从内核全面支持USB键盘、光驱和网卡模拟,功能更加强大,系统更加稳定。可以连上显示器和键鼠,直接成为一台电脑,直接把桌面环境带着走。
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!
。
至此详细刷机流程结束。
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
操作系统的桌面。
6、配合QtScrcpy
、wifiadb
更方便的从电脑操控手机,并不用连接数据线
7、可以在此手机系统运行操作burp
、Wireshark
来抓包,手机SIM
卡的流量也可以抓到。
8、Kali Nethunter
为诸多USB设备和无线网卡打上了驱动补丁,可以在手机上直接制作路由器,然后在网卡上进行抓包。(以后会发文章详情介绍)
制作路由器来抓包可以彻底解决抓不到包的问题,因为在路由器上抓包,对于一个App来说日常使用是没有区别的,所以可以做到对App的完全无感知的,从上帝视角对APP进行全面监控。
4、动静态分析
下面以具体一个恶意APP为实例,运用动静态分析方法结合工具使用来分析该APP。
通过模拟器安装该APP发现场面高能,背景和背景音乐非常不健康(笔者差点身败名裂),并且音量被调到最大,循环播放无法关闭,屏幕也被锁定无法关闭。
4.1、静态分析
静态分析原理基本就是一个反汇编过程,常用的静态分析工具为jadx
、jeb
、gda
,当我们拿到手分析一款APP时,基本先反编译、解包大致查看APK里的内容,下图为jadx-gui
反编译之后的情况。
# proxychains wget https://github.com/skylot/jadx/releases/download/v1.1.0/jadx-1.1.0.zip
可以看到该APP并没有加壳,然后我们解压APK文件后,发现在r文件夹下存放了资源文件(包括多人运动的图片与声音),dex为Dalvik
虚拟机可执行文件,resources
存放了一些字符串,meta
包含该APP签名信息,AndroidManifest
文件中包含了APP的配置信息。
将要分析的APP文件拖入jeb之后,进入MainActivity
,然后选择Decompile
,通过代码分析发现该APP首先注册了Broadcast
,然后寻找该类Class.forName("com.shimeng.qq2693533893.MyServiceOne")
,最后用startService
来启动该类。主要逻辑在MyServiceOne
类里。
点开MyServiceOne
发现里面有祝福的话
通过在模拟器运行该APP发现,连接模拟器的ADB断掉,而且重启模拟器会自动弹出APP的页面并且自动播放声音,该声音无法关掉,而且重启手机后也会自动播放声音。
setprop persist.sys.usb.config none
执行断掉自身USB的操作。
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
通过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
通过动静态结合分析了解大致逻辑在com.shimeng.qq2693533893.MyServiceOne
类中,操作按解除锁定后,然后hook
该类
com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class com.shimeng.qq2693533893.MyServiceOne
首先观察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
发现一直在调用MyServiceOne$100000007
,通过静态分析找到100000007
,发现该方法是调用getStreamMaxVolume
系统音量最大的api,所以该APP运行之后无法关闭音量。
回头来看我们输入的解锁码然后打印出来的内容,相当于输入了一个解锁码的参数,下图涉及到的调用方法即APP的执行流程。
com.shimeng.qq2693533893 on (Android: 8.0.0) [net] # android hooking watch class com.shimeng.qq2693533893.MyServiceOne
然后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
点击再点解锁,发现打印出了参数、返回值、调用栈。
根据打印出的内容继续跟踪该类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();
至此,利用动态分析我们将更准确的定位到关键性逻辑,相比搜索字符串碰运气,更快捷靠谱。
5、脱壳
将解包后的dex文件导入010Editor
进行分析查看,发现文件头为dex035
,比较常用的葫芦娃脱壳机FRIDA-DEXDump
的原理是采用暴力搜索内存中dex035
进行特征匹配
# proxychains wget https://www.sweetscape.com/download/010EditorLinux64Installer.tar.gz # tar zxvf 010EditorLinux64Installer.tar.gz # ./010EditorLinux64Installer
个人比较常用的FRIDA-DEXDump
如作者所说可实现三秒脱壳。
https://github.com/hluwa/FRIDA-DEXDump 默念一声"我想脱个壳"。 启动 APP。 启动 frida-server。 python main.py。 默数三秒,脱好了。
6、总结
越学越菜