1. 1. 移动应用程序逆向
    1. 1.1. 移动应用逆向分析
      1. 1.1.1. 自己预习的内容
      2. 1.1.2. Why Android?
      3. 1.1.3. 逆向Android的目的?
      4. 1.1.4. 认识APK文件
  2. 2. Android 应用的逆向技术和方法
    1. 2.1. 逆技
    2. 2.2. 逆向流程
      1. 2.2.1. 1. 反编译
        1. 2.2.1.1. dex
        2. 2.2.1.2. arm
      2. 2.2.2. 2. 关键字定位
        1. 2.2.2.1. 关键字定位
        2. 2.2.2.2. 资源定位
        3. 2.2.2.3. 日志定位
        4. 2.2.2.4. 调用栈跟踪
      3. 2.2.3. 3. 核心目标逆向
        1. 2.2.3.1. 静态分析
        2. 2.2.3.2. 动态调试
        3. 2.2.3.3. 动静结合
      4. 2.2.4. 扩展
  3. 3. Android应用安全保护和对抗
    1. 3.1. 如何保护?
    2. 3.2. 1. 干扰反编译工具
      1. 3.2.1. 利用反编译工具的bug或漏洞
      2. 3.2.2. 转换成代码时的漏洞
      3. 3.2.3. 链接资源文件时的bug
      4. 3.2.4. 例子
      5. 3.2.5. 对抗->干扰反编译
    3. 3.3. 2. 代码混淆
      1. 3.3.1. 将代码变得难以阅读
      2. 3.3.2. 变量名、类名、方法名混淆
      3. 3.3.3. 字符串加密
      4. 3.3.4. 控制流混淆/平坦
      5. 3.3.5. 控制流平坦化(比较高级)
      6. 3.3.6. 代码混淆工具
        1. 3.3.6.1. Java工具
        2. 3.3.6.2. C++代码
      7. 3.3.7. 混淆的问题和使用场景
        1. 3.3.7.1. 混淆带来的问题
        2. 3.3.7.2. 什么APP会使用混淆?
        3. 3.3.7.3. 对抗代码混淆
    4. 3.4. 扩展
    5. 3.5. 3. 反调试
      1. 3.5.1. Ptrace
      2. 3.5.2. 检测调试器
      3. 3.5.3. 基于时间的检测
      4. 3.5.4. 对抗反调试
    6. 3.6. 4. 加壳与脱壳
      1. 3.6.1. 加固
        1. 3.6.1.1. Dex加固
        2. 3.6.1.2. So加固
      2. 3.6.2. 加固后APK运行过程
      3. 3.6.3. 脱壳
        1. 3.6.3.1. Dex脱壳
        2. 3.6.3.2. So脱壳
    7. 3.7. 移动应用第三方加固方案分析
    8. 3.8. 目的
    9. 3.9. 例题(GeekPWN)
      1. 3.9.1. 考察点
    10. 3.10. Frida使用
      1. 3.10.1. Frida无法使用的原因
      2. 3.10.2. Hook不上的几种原因
    11. 3.11. 如何做安全研究?
      1. 3.11.1. 保持一份热情
      2. 3.11.2. 持续的学习
      3. 3.11.3. 深度决定了广度

移动应用程序逆向

移动应用程序逆向

移动应用逆向分析

自己预习的内容

  1. 破解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对比
  1. 使用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生命周期

  1. 入口在壳dex处,获取“执行 权”
  2. 壳dex初始化
  3. 解密加固的dex
  4. 调用DexClassLoader加载解
    密后的dex
  5. “执行权”还给原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会非常轻松

  • 沉得住气

  • 善于思考、总结、沉淀

  • 写博客