移动应用程序逆向
移动应用程序逆向
移动应用逆向分析
自己预习的内容
- 破解Android程序的通常方法
将apk文件利用ApkTool(Android反编译工具)进行反编译,生成Smali格式的反汇编代码,然后阅读Smali文件的代码来理解程序的运行机制,找到程序的突破口进行修改,最后使用ApkTool重新编译生产apk文件并签名,最后运行测试,如此循环,直至程序被成功破解。
反编译——理解运行机制——找突破口进行修改——重新编译——再签名——运行测试——循环往复
Why Android?
APP-移动互联网的入口
安全研究的“交集”
Android的市场份额 —— 和iOS其实是相通的
逆向Android的目的?
遇到的问题:
代码混淆
反调试
加壳
认识APK文件
1.AndroidMainfest
- XML格式
- 二进制数据存储
- 内容:
- 包名、名称、图标、targetSDK、版本号等;
- 需要的权限列表(安全研究时用得少,恶意代码分析用得多);
- 使用的组件信息(Activity,Service,Broadcast Receiver,Content Provider)
- Activity:可视的界面;生命周期、启动模式
- Service:服务,前台和后台
- BroadCast Receiver
- Content Provider:内容提供者:URI,增删改查
2.lib —— Native代码编译后的库、第三方库
3.res —— 资源文件
4.assets —— 音频、视频、图片等静态文件(有些加壳后存放到这个)
1.DEX文件
- Java -> dex
- dex.035 文件头,可以通过这个来找
2.SO文件
- C/C++编译后的文件(elf格式)
- JNI
- 第三方库(opencv,unity)
- 架构:armeabi…
3.签名文件
- 防止被篡改
- APP升级(判断是否是正确的升级包)
- 代码或数据共享(e.g.只给自己共享,不给别的APP共享)
- 文件结构:
- META-INF目录
- MANIFEST.MF 所有文件的SHA1/SHA256的Base64编码
- CERT.ST MANIFEST.MF文件的SHA1/SHA256的Base64编码
- CERT.RSA/.DSA 签名的公钥,SF签名后的数据
这是V1方式,这里也是一个漏洞利用点。正当用途:APP分发到各个市场的分发计费
Android 应用的逆向技术和方法
逆技
逆技:一机(一台Root后的手机,小米有开发版本的root系统);一APK;一椅(一逆逆一天);一钛合金眼
逆向流程
反编译 ——> 目标定位 <——> 核心目标逆向
1. 反编译
dex
- dex -> smali
- baksmail [TOOL]
- dex -> smali ->java
- jeb
- Apktool (前者结合用,Smali代码是不会有错的,伪Java可能会错)
- dex2jar
arm
- elf -> arm指令
- IDA
- Radare2 (NSA放出来的工具) [TOOL]
- Ghidra
- Arm指令 -> C++
- IDA F5
- Ghidra
2. 关键字定位
关键字定位
资源定位
日志定位
调用栈跟踪
关键字定位
1.字符关键字
2.代码关键字
3.Grep大法好
- 反编译后的静态代码
- 动态加载的代码(不一定找得到,也是代码保护的一个手段)
- 监控文件变化
资源定位
1.定位UI中的资源变量名(如红包的LOGO),例如红包按钮为“a77”
- ddms
- uiautomatorviewer
- dumpsys
2.res目录中寻找该变量对应的索引值
3.在Smali代码中grep所有对该索引值的引用
日志定位
1.adb logcat | grep
2.日志文件
- APP目录下
- SDcard
3.打开APP内置的日志开关(开发人员在开发时为方便调试打开的,几乎所有的APP都有,非常好用)
- 重打包
- hook
4.Smali注入
- 污点跟踪
- 数据流分析
调用栈跟踪
1.ddms method profiling
2.hook系统函数打印callback(相当于是录像一样
3. 核心目标逆向
静态分析
1.直接分析smali代码
类
基本数据类型
寄存器
函数和函数调用
代码块和跳转
2.分析伪java代码
3.直接分析arm指令
- 寄存器 SP, PC, LR
- 传参方式 返回值一般在R0
- 跳转 B, BL, BX, BLX
- 存储器访问 LTR, STR等
- 数据处理
- armh和thumb切换
4.分析伪C++代码
动态调试
1.AS无源码调试 [TODO,昨天的实验]
- 配置APP为可调试状态
- 反编译APK将smali导入AS工程(安装Smalidea插件)
- 新建remote调试,并配置好端口
- 以调试模式启动APP,开始调试
2.IDA调试 Android SO [TODO, 同样是昨天的实验]
- IDA导入SO文件
- root设备上启动android_server
- adb push/chmod
- IDA新建Remote Android Debuger
- adb forward tcp:23946 tcp:23946
- 选取目标进程,断点调试
3.Smali代码注入(插桩)
- 注入方法:反编译——修改Smali代码——重打包
- 使用场景:
- 批量打印logo
- 控制流分析
- 数据流分析
- 问题
- 重打包失败
- 签名检查
- 寄存器维护(和重打包失败一致)
4.HOOK技术
- 使用场景
- 注入到目标代码,改变执行结果
- 获取某一状态下的变量值
- HOOK本质(要理解工具、技术的本质,再去使用)
- 代码注入
- HOOK工具
- Xposed —— 替换app_process(所有进程的母进程)
- Frida —— Ptrace注入 [TODO,后面去研究一下] 图:Xposed和Frida对比
- 使用Frida Hook APP
注入原理
使用场景
- 设备root
- 非root
两种模式
- Attach 已有进程上附加,适合已运行的服务上,尤其是一些系统服务
- Spawn 新起一个进程,适合进程刚启动时
例子
动静结合
扩展
扩:腾讯玄武安全实验室,应用克隆
Android应用安全保护和对抗
如何保护?
反编译(干扰反编译工具)—— 目标定位(代码混淆) —— 核心目标逆向(代码混淆、反调试、加壳)
1. 干扰反编译工具
利用反编译工具的bug或漏洞
- AndroidManifest.xml
- dex
- So
转换成代码时的漏洞
- Smali -> Java
- Arm指令 -> C++
链接资源文件时的bug
- 特殊的资源文件
- 超长的资源id
例子
对抗->干扰反编译
1.反编译时不链接资源文件 –no-resource
2.使用新版本的反编译工具
3.分析底层的反编译代码
- Smali
- Arm指令
4.打造自己的逆向工具链(强联推荐,在对抗时,甚至是开发自己的反编译工具)
2. 代码混淆
将代码变得难以阅读
- 变量名、类名、方法名混淆
- 字符串加密
- 控制流混淆
变量名、类名、方法名混淆
- 超长名字 00o0ooo00ooo000ooo
- 相似字符 mabin -> m4bln
- 特定含义的代码 int int= 5
- 特殊编码 ȷava \u0237
- 难以阅读的字符
字符串加密
- 编码:ascii码、Base64、Unicode
- 自己实现的字符串加密
控制流混淆/平坦
- 运算混淆 a+b->a+c/d–c/d+b
- 控制流伪造
控制流平坦化(比较高级)
- 工具:OLLVM
- 原理:利用分发器,树立代码,通过分发器来控制代码流程,让线性的代码平坦化
代码混淆工具
Java工具
- ProGuard
- DexGuard
C++代码
工具:OLLVM
混淆的问题和使用场景
混淆带来的问题
- 运行不稳定
- 开发调试困难
- 执行效率低
什么APP会使用混淆?
- 受众基础大的APP不会使用“变态”的混淆方式 • 即使混淆,也只是一小部分核心逻辑
- 老版本的APP一般不会混淆
- 纯混淆的CTF题目很无聊
- 企业级的APP
对抗代码混淆
1.变量名、类名、方法名混淆
- 变量重命名 jeb、重打包
- 寻找老版本app
- 根据开源代码映射
- 自动化 -> 自动化相似代码检测
2.字符串加密
- 静态分析替换
- 动态hook
3.控制流混淆
- 优化反编译工具
- 符号执行
- 硬核逆向 状态机、经验、耐心
扩展
扩:15年iOS系统解析字符串时,系统崩溃,参考
扩:[重要]一些加了混淆的APP,可以去查看其老版本,老版本由于成本等问题,一般不会混淆,这是一个很好的入手点!
3. 反调试
Ptrace
先占坑:自己ptrace自己
检测TracePid的值
/proc/pid/status和/proc/pid/task/pid/status:普
通状态下,TracerPid这项应该为0;调试状态下 为调试进程的PID
检测调试器
进程名
- gdb_server
- android-server
端口号
- IDA: 23946
- Frida: 27042
内存特征码
基于时间的检测
检测程序自身是不是被下了断点,正在被调试。现实中用得比较少。
对抗反调试
- 找到所有的检测点并Patch(一个个绕过)
- 抢占先机式的Hook
- 开启上帝模式 – 修改系统 (打造自己的工具链时会用到)
4. 加壳与脱壳
加固
Dex加固
- 指令抽取
- Dex加密
- Java->C
So加固
- 有源码
- vmp
- 无源码
- So加密
- Section加密
加固后APK运行过程
Process.start->Application创建->attachBaseContext->onCreate->onStart->onResume->Activity生命周期
- 入口在壳dex处,获取“执行 权”
- 壳dex初始化
- 解密加固的dex
- 调用DexClassLoader加载解
密后的dex - “执行权”还给原dex
脱壳
Dex脱壳
Hook dex加载函数
Dump内存重建dex
定制化系统
脱壳工具
- dumpDex
- FDex2
- Frida
So脱壳
解密so
- hook loader
- 修复section
- dump内存
vmp
- 硬逆
- 状态机
- 虚拟机入口
移动应用第三方加固方案分析
https://www.cnblogs.com/baiqiantao/p/9286449.html
目的
建立体系架构,遇到的知识点归纳到这边,这样逆向起来会非常轻松
例题(GeekPWN)
考察点
1.包名
2.签名原理
3.障眼法、干扰
4.文件判断(信息搜集)
5.编程能力
WP:安全客/84837 无人机的钥匙
Frida使用
Frida无法使用的原因
1.root
2.selinux(一般需要关闭)
3.bug(在GitHub上的issues上)
Hook不上的几种原因
1.进程没有选对
2.动态加载的dex(插件化)
3.语法错误
如何做安全研究?
保持一份热情
持续的学习
- 安全咨询 sec.today Twitter
- 安全社区 看雪,吾爱破解,freebuf
- 安全风向 google/apple 漏洞公告、工业界(BlackHat)学术界会议(四大峰会)
深度决定了广度
刨根问底
e.g. 深入学习完Android后,再学习iOS会非常轻松沉得住气
善于思考、总结、沉淀
写博客