逆向课程笔记(from同事)01

安卓入门爬虫课笔记

第一课 第一个App开发环境

  • 虚拟机vs真机 ?
  • as vs eclipse ?
  • 手机 vs 模拟器 ?
  • 安卓6 vs 安卓8 (10)?
  • 第一个App

第二课 第一个app四大组件和系统架构

  • IP端口协议诊断(诊断)
  • 系统架构
  • 常用adb命令
  • 常用Linux命令

1、Activity

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

2、Service

Started(启动):当应用程序组件(如Activity)调用StartService()方法启动服务时,服务处于Started状态。

bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。

Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。

3、Content provider

Android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。

只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。

ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。

开发人员不会直接使用ContentProvider类的对象,大多数是通过ContentResolver对象实现对ContentProvider的操作。5、ContentProvider使用URI来唯一标识其数据集,这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。

4、Broadcast Receiver

你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。

动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。

Android系统架构

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

image.png

第三课 第一个app运行环境手机刷机指南

  • IP端口协议诊断(诊断)
  • 系统架构
  • 常用adb命令
  • 常用Linux命令
  • 刷机
  • 命令:

neofetch  查看系统信息

dumpsys meminfo (pid)  查看某一进程的信息

cat /proc/(pid)/status  查看某进程的status

cat /proc/(pid)/maps  查看某进程加载的so

dumpsys activity top  查看位于顶层的活动信息

dumpsys dbinfo (包名) 查看位于包名的数据库信息

netstat -alp 列出所有监听的服务和程序名

netstat -tunlp 列出所有tcp udp 端口和程序名 查制定端口

nethogs 按进程 端口 pid 分类整理收发包速率

ps aux(kalinethunnter)查看完整的进程信息

strace -p (pid) -o(xx.txt) 查看某个进程的内核操作(针对syscall反调试)并输出为文本

lsof -p (pid) > xx.txt pid信息保存到文件

第四课 动静态分析四大组件

  • 四大组件
  • as开发
  • 第一个简单app
  • 静态分析
  • 动态分析

android四大组件分别为activity、service、content provider、broadcast receiver。

第五课 动静态分析工具和概念

  • APK解包分析
  • 静态分析工具(jadx/jeb/gda)
  • 静态分析四大组件
  • 动态分析辅助 (frida)objection
  • frida必须手动启动, xposed随着art启动而启动
  • as+smali+DDMS+xposed+jeb(後回し)

开发的高度决定逆向的高度

  • 各种反编译工具的对比

jadx vs jeb vs GDA

  • objection 插件 wallbreaker

plugin wallbreaker classdump xxx 类名 --fullname (dump 一个类的所有方法)

  • 实用技巧:打印Intent

image.png

第六课 自动化动态分析和快速定位

  • objection 免root动态调试apk(基于重打包)

memory list exports xxx.so 查看一个so里面的导出函数

android heap search instances xxx 查找实例

android heap execute  实例id 方法  执行实例的方法 无参数

android heap evaluate  实例id    执行实例的方法 有参数 进入编辑器

image.png

  • objection内存漫游和组件控制
  • objection类和方法动态trace
  • objection+DEXDump 内存暴力脱壳机

objection -g 包名 explore -P ~/.objection/plugins/  加载objection 插件

  • objection RPC 可以直接curl的RPC

https://github.com/sensepost/objection/wiki/API

https://github.com/sensepost/objection/blob/master/agent/src/rpc/android.ts

objection explore --enable-api 启动rpc

image.png

第七课 真实app实操去广告重打包

  • (重)打包核心原理分析
  • Dalvik下常见格式互转
  • Dex格式反编译与Smali
  • 解包改包改业务流程
  • 手动重签名重打包

太极阳-VA-RATEL:重打包

Xposed + Apk = Xapk

定位:

  • 顺着开发的思路
  • 动态百分百准于静态
  • 所见即所得
  • Wallbreaker
  • startup command

https://www.jianshu.com/p/6bdbbab73705

https://blog.csdn.net/lpohvbe/article/details/7981386

https://www.jianshu.com/p/18e1f518c625

objection -g 包名 explore --startup-command "xxx"

objection -g 包名 run "xxx"

objection -g 包名 explore -s "xxx"

objection启动时hook

android sslpinning disable(objection hook ssl pinning )

/root/Android/Sdk/build-tools/30.0.1/d8 xxx.class  直接编译成dex

(class 路径

/AndroidStudioProjects/xxx/app/build/intermediates/javac/debug/classes/com/example/xxx)

一顿乱搜 --> ❌

顺着开发思路,思考这个功能是如何实现的 --> ☑️

wallbreaker dump 一个实例信息

image.png

重打包操作

apktool d xxx.apk 解apk包

找到要修改的smail 修改条件

apktool b xxx/

apk 路径(/apktool/zhibo/dist)

cd找到apk路径

keytool -genkey -alias abc.keystore -keyalg RSA -validity 20000 -keystore abc.keystore 生成签名

image.png

jarsigner  -verbose -keystore abc.keystore -signedjar new.apk old.apk abc.keystore  给apk签名

pm uninstall xxxx 在手机shell中卸载一个app

am start-activity xxx 启动一个app

第八课 真实app实操带壳app重打包去强制升级

  • DEXDump三种使用模式脱壳
  • Objection快速自动化定位
  • Wallbreaker内存可视漫游
  • 所见即所得的代码定位思路
  • 修改源码重打包去强制升级

查找弹框怎么实现

带壳重打包步骤:

1.apktool -s d xxx.apk 保留dex 解包apk

2.删除原来的classes 替换 脱壳后的dex 命名 classes.dex classes2.dex ....

3.修改AndroidManifest.xml 中的入口

<application android:allowBackup="true" ...android:name="xxx"(壳的入口)> 修改为app的包名

4.apktool b xxx(文件夹) 回编译

5.apk拷贝到这

image.png

6.jarsigner  -verbose -keystore abc.keystore -signedjar 青青草视频signed.apk 青青草视频.apk abc.keystore  给apk签名

第九课 真实App实操《加固的种类,甄别和处理方式》

  • 混淆加固技术的发展过程

葫芦娃公众号中的文章

  • 常见的混淆加固技术甄别
  • 查壳脱壳(工具)的核心原理

https://www.520monkey.com/archives/1118

  • 内存枚举,trace和可视化
  • 基于内存的反混淆和特征定位、
  • 所谓原生,就是离解释器更近:安卓原生就是libart.so来解释、linux原生就是CPU直接解释
  • 想要分析一个加固/保护手段,得先实现这个加固/保护。从开发的视角来看问题

练习

https://wx.zsxq.com/dweb2/index/search/%E4%B8%89%E9%81%93%E9%A2%98

第十课 手机刷机:Xposed介绍和模块安装玩机

  • xposed用户和使用场景
  • xposed和各类衍生品

Edxposed、太极、Ratel(平头哥)、virtual app

https://ratel.virjar.com/#/(平头哥)

  • n5x/n6p/pixel 安装xposed及其模块
  • xposd模块使用和玩法

第十一课 手机刷机:手调'Smali'和DDMS调试

先刷个7.1.2环境,装个xposed 看上节课刷

  • xposed开发环境 和 helloworld
  • Android Studio带源码调试

可调试java so

  • Jeb无源码调试Smali

image.png

jeb 使用方法 https://blog.csdn.net/freeking101/article/details/105910877/

1.双击进入方法定义

2.按x查看方法引用

3.debugger 调试:打开app debugger->start->attach

找到地方 按 tab转smali 然后 按 ctrl+b 下断点

4.开始就调试:adb shell am start -D -n 应用程序包名/.应用程序入口界面。(adb shell am start -D -n com.example.demo01/.MainActivity)下断点 然后start debugger  需要修改 VM/locals中的变量类型 才会显示正确的值

5.调试没有debug 为true的app:

    1. 重打包
    2. hook debugger的api 用 xposed的插件(Xdebuggable)

能否用frida实现?

    1. 同上

总结:

smali调试场景:扣算法细节、变形的标准算法、小项目

frida调试场景:快速定位、各种执行流、大项目

  • Smali基本概念和语法

https://blog.csdn.net/YoYo_Newbie/article/details/90745115

  • DDMS界面调试、定位、调用栈

(需要debugger 才能用)

路径:/root/Android/Sdk/tools/lib/monitor-x86_64/

主要功能:分析view、trace

1.DumpView工具(找到需要的信息,可以看他的class 然后直接到frida里面打调用栈 直接定位)

2.辅助增强工具

3.Hierarchy View

基于界面定位

view继承关系图

4.method profilling 方法追踪器

trace 所有方法 先strat 然后 调用完 然后stop 然后里面搜算法  

  • DDMS启动方案

https://wx.zsxq.com/dweb2/index/search/DDMS

Kali Linux里的as4的DDMS启动失败,原因是要用as自带的jre来启动,直接./monitor用的是Kali系统的jdk,版本太高了:

# ln -s  /root/Desktop/android-studio/jre/ /root/Android/Sdk/tools/lib/monitor-x86_64/

  • 逆向三板斧:

1.hook定位

2.主动调用

3.批量调用

第十二课 手机刷机:'Frida'开发和调试环境

  • 老手机刷安卓10焕发第二春

老手机刷安卓10:blissRoms、lineageos

  • python全版本随意切(pyenv)
  • Frida(-tools)全版本随意切
  • objection版本,ip+端口(批量)插件
  • frida(rpc)多主机多手机多端口混连

第十三课 抓包环境:抓包环境配置及原理

  • 从零开始的抓包配置手机
  • charles/burp抓包配置
  • 协议层中间人抓包核心原理
  • HTTP层中间人抓包配置
  • HTTP和SSL必须分清楚
  • 为何不使用HTTP代理而是VPN
  • SOCKS5/VPN 抓包的核心优势
  • 核心基准:OSI七层模型

核心原理:永远要降维打击,把自己置于要观察对象的下一层

HTTP和SSL是完全不同的东西,HTTPS是包裹在SSL协议里面的HTTP

疑问:https文件下载不走SSL吗?

第十四课 抓包环境:HTTPS.C/S校验核心原理

  • 从开发角度看待HTTPS问题
  • 客户端校验服务器
  • 服务器校验客户端
  • 手机网页HTTPS抓包配置(安卓8.1)
  • HTTPS案例:某某和某某某
  • 抓国外APP如何连接科学

charles 要用http的代理 1087端口

socks不行(VPN的问题)

burp可以用socks

一般HTTPS: 大部分只采用客户端校验服务器

双向绑定: 很少会有服务器校验客户端

SSL Cert Pinning:更少

第十五课 抓包环境:基于HOOK的抓包

  • 批量trace确定收发包框架

猜类->hook验证

  • ZenTracer/DDMS

zentrace 可以hook模糊匹配到的所有方法

M: + 类名 模糊匹配

E: + xx 精准匹配

  • HOOK收发包函数回溯参数来源
  • Objection/Wallbreaker

Objection批量hook,打出类的日志复制到excel中 前面批量加上 android hooking watch class 然后保存为txt

objection -g com.cz.babySister explore -c   "/root/Desktop/hook.txt"

  • Okhttp框架自吐:frida_OkCat
  • 无视证书绑定的libssl框架自吐

frida_ssl_logger native 层hook libssl里的 read 和 write api

只能打出https的

被混淆的时候 枚举出来的所有类可能找不到,需要apktool d xx.apk 后 进去grep

image.png

image.png

image.png

使用okhttplogger 反混淆

image.png

复制混淆的东西 然后去poker.js里面替换

image.png

缺点:不如抓包软件全面

优点:无视证书、基于Hook直接得到参数、打调用栈得到参数的构成和来源

第十六课 FRIDA速成:基本使用方法

  • 两种操作FRIDA模式:命令,RPC
  • FRIDA开发思想:HOOK三板斧
  • FRIDA两种操作APP模式:spawn、attach

双进程保护的app可以指定pid去hook(-p)

  • FRIDA命令行参数和常见模式
  • FRIDA开发思想:HOOK三板斧
  • 二进制补丁:FRIDA hook JAVA

--runtime=v8 使用js v8引擎编写js

SPAWN:创建进程就hook:有壳的会找不到一些对象

ATTACH:应用运行过程中hook:有壳也可以的,多进程的可以指定pid attach

三板斧:

  1. 先hook定位,看参数和返回值:定位
  2. 再构造参数、主动调用:利用
  3. 最后配rpc导出结果:规模化利用

java.perform 和 java.performNow的区别:

performNow 可以在class loader还没起来的时候去hook!

(试试hook debugger(hook不到,可能时机更早))

proguard-rules.pro文件负责混淆

第十七课 FRIDA速成:参数调用栈返回值

  • 开局:objection内存漫游辅助
  • 参数、重载、修改参数
  • 调用栈及其查看方式
  • 返回值、简单构造、修改返回值
  • objection和frida联合调试

hook的时候两个原则:

  • 离数据越近越好
  • 离动作越近越好

思考:基于调用栈检测主动调用

hook用不上Java.choose的

hook函数时不分动静态

第十八课 FRIDA速成:主动调用及批量自动化

  • 忽略方法实现过程:构造参数、主动调用

android.os.Build 改机api之一

  • 主动调用中的域、类方法、实例方法处理
  • RPC实现App自动重启,模拟点击,挂脚本

基于adb input keyevent

新建线程模拟操作

事件对应数字需要查看api

rpc导出函数前面的名字一定要小写后面可以大写

  • 配置RPC实现多机器,批量,自动化调用

python:

device = frida.get_device_manager().add_remote_device('192.168.x.x:xxxx')

  • RPC单公网IP远控内网frida-server集群

Attention:

  • 将手机打造成4G代理供requests/scrapy调用

com.android.okhttp.internal.huc.HttpURLConnectionImpl

(非okhttp调用无法抓取)

第十九课 网络库:HttpURLConnection

  • HttpURLConnection介绍
  • 开发流程和逻辑分析
  • 关键类、收发包函数梳理
  • objection/Wallbreaker内存漫游
  • Frida脚本收发包内容 “自吐“

1.玩安卓:java层就是玩java、玩java就是玩类

2.类确定好后,就确定离数据最接近的是哪个方法

3.确定数据在哪儿?感兴趣的数据是在哪个类的哪个方法在操作

为了学Frida

先搜刮内存 => 看android developer => 最后看aosp源码

okhttp 已经成为安卓底层网络库的实现

https://github.com/aqi00/android2

安卓学习案例

objeciton hook 构造函数

android hooking watch class_method java.net.URL.$init

自吐 okhttp

hook底层api

java.net.HttpURLConnection 只是一个抽象类,其中的方法需要hook实现类才能经过。

实现类为com.android.okhttp.internal.huc.HttpURLConnectionImpl

hook init的时候 后面要--dump-args 。。。

开发者代码:

https://developer.android.google.cn/reference

aosp 安卓源码:

http://androidxref.com/8.1.0_r33/

第二十课 网络库:okhttp3+logging

  • 网络库之okhttp3介绍
  • 开发流程和逻辑分析
  • 关键类、收发包函数梳理
  • Frida脚本收发内容“自吐”
  • Okhttp Interceptor

ok3与底层的okhttp关系不是特别大

混淆了ok3层可以用 siyujie的okhttp3脚本

没混淆可以用ok3的拦截器  (从adb logcat 看)

编译的dex

  1. /root/Android/Sdk/build-tools/30.0.1/d8

class 编译成dex

  1. apk解压取出

第二十一课 网络库:基于okhttp3的Retrofit

  • 网络库之Retrofit介绍
  • 开发流程和逻辑分析
  • 关键类、收发包函数梳理
  • Okhttp Interceptor
  • Frida脚本收发内容 “自吐”

Retrofit就是Ok3

所有搞Ok3的都可以搞Retrofit

写了一个吐baseUrl

第二十二课 究极自吐Socket

  • 顶层协议的基石:Socket
  • 基于内存漫游的关键类定位
  • HTTP收发包底层究极自吐
  • HTTPS收发包底层究极自吐
  • 所有网络库底层究极自吐libc(ssl)、Syscall

所有的应用层都逃不掉底层用Socket来传输

只要掌握了Socket,对上层应用就是降维打击

010查看16进制的数据

view -> edit as -> hex

edit -> paste from -> paste from hex

请求代码中写的是http 安卓8 会走http 和 安卓10中 会强制https

总结:从socket层hook write 和 read 函数 -> 究极自吐 秒杀所有协议

再打一份调用栈 直接定位请求位置!

第二十三课 WebSocket、XMPP自吐

  • WebSocket基本概念和特征
  • 收发包函数hook和自吐
  • XMPP基本概念和特征
  • 收发包函数hook和自吐

ws 特征:跟http是孪生兄弟、用于服务器向客户端发送消息

使用库也是okhttp

socket可以直接抓

okhttpCAT 也可以直接抓

业务层也可以直接抓

XMPP是聊天协议

使用的库没有固定标准

Socket层可以直接抓

业务层也可以直接抓

降维攻击真牛逼

hook java.lang.String.toString 根据字符串找调用栈

grep 50 xxxx 查看上下文

第二十四课 直播/弹幕协议Protobuf逆向分析

  • gRPC/Protobuf的意义和常用场景
  • Protobuf在安卓/服务器的开发流程
  • 基于内存漫游的关键类定位及批量trace
  • gRPC Socket自吐:地址端口及二进制流
  • Protobuf流的反序列化解析流程及重放
  • 安卓Socket框架通信自吐通杀应用层协议

grpc 客户端和服务端一样

点对点服务直传

nc ip port

第二十五课 多案例分析:没有抓不到的包

  • 手机上抓:Nethunter“可视化”抓包

优点:直观、所见即所得

缺点:没有内容,粒度太粗,简单看下

  • 手机上抓:Wireshark抓包转储

优点:可以转储内容,存下来稍后分析

缺点:只能看明文,不能解加密协议

  • 手机上抓:tcpdump抓包转储

优点:不需要刷Nethunter

缺点:没有界面?

  • 电脑+手机:hook Socket抓包
  • 电脑+手机:Frida Hook模拟抓包、改包、重放
  • 电脑+手机:Charles协议层抓包

手机上抓:优点:无法对抗,全部能抓,没有抓不到的包

hook抓包:

- 优点1:为所欲为,可以对包的内容进行进一步的更改和定制;

- 优点2:抓包全面,直接就是明文,不需要解协议(无需绕过证书绑定)

- 缺点:可能会不全、可能会漏。hook点是有限的,万一它在用奇葩的框架做网络传输就会漏掉

Charles+Postern:协议层抓包:

- 优点:全面。已经解好了协议,HTTP、WebSocket直接解好。

- 缺点:配置证书稍微麻烦,解不了纯Socket。

  • 抓包问题到此为止,nothing more。

VNC viewer 电脑上连nethunter的kali

  • 找到hook 地址的方法
  • 通过hook event 来定位类
  • hook 系统的cipher类进行跟踪定位

第二十六课 没有trace不出的执行流

  • 类是安卓世界的一等公民
  • 基于内存漫游的关键类定位和trace
  • 溯源就是定位到具体的类
  • 关键域:id vip memi1 invite...
  • 关键方法:login Register buy ``...
  • Frida/Objection/Wallbreaker各种自吐

对开发的熟悉程度决定逆向的程度

所有的判读都在服务器,那在本地的hook其实就失效了

逆向全部搞定之后,就开始寻找业务逻辑漏洞

爬虫er来说,抓取是没问题了。

第二十七课 Frida分析违法应用

  • Frida hook Socket抓所有应用层包
  • Frida hook onClick直接定位控件业务代码
  • Frida hook Cipher直接定位加解密代码
  • Java.choose修改对象属性破解VIP
  • Frida hook 收发包/改包破解VIP
  • Frida RPC /Python开发脱机脚本

只要是在手机上运行的,它就离不开系统;

只要是系统里的东西,都可以调试和分析,都是可以破解的。=》 “我就是系统”本身。

  • “我就是系统”可见即可得的逆向思维
  • trace系统框架库快速定位关键代码

只要是基于本地判断的,我们都可以破解;

基于服务器判断,就很难破解,得寻找业务逻辑漏洞

从来不需要搜关键字,搜关键字这种操作应该从历史长河中消失,是一种完全的投机

不要相信静态的结果,一定要去内存里去捞

不能够以战术的勤奋,掩盖战略的懒惰;选择不对,努力白费;方向不对,再努力都没用;

耗时操作可以send到电脑上执行

图片的保存和解密 Bitmap

hook破解:

- hook破解

- 改包破解

主动调用:

- 接口遍历

- 批量注册

- 短信爆破

逻辑漏洞:

- 重构利用

- 脱机登录等等

第二十八课 Frida$Native:Frida hook Native 基础

  • JNI&NDK
  • NDK开发的基本流程
  • so逆向的基本流程
  • 静态注册和动态注册
  • frida hook native

JNI 介绍

https://bbs.pediy.com/thread-224672.htm

https://www.jianshu.com/p/87ce6f565d37

Frida 代码案例

https://awakened1712.github.io/hacking/hacking-frida/

Google NDK 开发案例

https://github.com/android/ndk-samples

frida 对接JNI ENV源码

https://github.com/frida/frida-java-bridge/blob/47f9e17f1a3695ce9800296ba3d2edb9d685ba36/lib/env.js

打印 jstring

Java.vm.getEnv().getStringUtfChars(arg,null).readCString()

JNIEXPORT jstring JNICALL Java_cn_hluwa_demo01_MainActivity_stringFromJNI(

JNIEnv *env,

jobject /* this */

//静态的native函数为jclass

)

JNI中数据类型

Java中的基本数据类型是int、long、short、float、double、char、byte、boolean这些,为了避免与C语言的基本数据类型冲突,在JNI中,将JAVA的基本数据类型重定义成了:jint、jlong、jshort、jfloat、jdouble、jchar、jbyte、jboolean。那jstring又是怎么回事呢?虽然String不是Java基本数据类型,但它实在是太常用了,所以便有了jstring;对于数组,则是再后面再加个Array,如:jintArray、jbyteArray,但是没有jstringArray,欸,那如何表示呢?还有其他的非基本类型呢? 除了上述以及jclass、jthrowable、jarray这些有专用重定义之外其他类型均使用jobject表示,所以String数组就是jobjectArray啦。Ctrl+单击jstring就可跳到jni.h头文件查看各个定义了。

JNI的加载流程

System.loadLibrary("native-lib");

loadLibrary的作用就是加载这个动态链接库,这样后面的代码调用才能成功的找到对应的原生函数。而静态代码块的执行时机非常早,比什么构造函数、onCreate都要早,在类加载的时候就被调用库加载并非一定要在当前类、static块中!。加载库还有其他方法,比如使用System.load(String)方法,其传入链接库的具体路径;甚至有的是在Native层中使用dlopen、mmap等方式来进行加载,就相当于自己实现了一个loadLibrary,但是最终的目的都是一样的:将代码加载入内存中

初始化函数

    对链接库进行加载的程序叫做linker,文件路径为/system/bin/linker。linker加载so的时候会依次调用其init_array中的函数来执行开发者的初始化代码,可在IDA中按shift+f7打开Segmentation视图,若有.init_array项,那么其中的函数就会被依次执行,这些函数都没有参数。

    linker中加载so的函数叫做dlopen,而loadLibrary跟load其实也是基于dlopen,但其添加了一个回调就是JNI_OnLoad,只要在代码中定义一个名为JNI_OnLoad的函数,dlopen完成之后就会将其调用。

jint JNI_OnLoad(JavaVM* vm, void* reserved)

    IDA经常不能正确识别参数列表,所以手动y的时候一定要正确的修改,就像这样。

image.png

image.png

image.png动态注册

如今许多开发者都出于安全性考虑或其他需求,不愿使用函数名规则绑定,而是自己动态注册来绑定native函数。方法也很简单,只需调用RegisterNatives函数即可。其申明如下:

jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)

clazz 就是native函数所在的类,可通过FindClass获取(将.换成/);methods是一个数组,其中包含注册信息,nMethods是数量。

JNIEXPORT jstring JNICALL stringFromJNI(JNIEnv env,jobject / this */) {

std::string hello = "Hello from C++";

return env->NewStringUTF(hello.c_str());

}

jint JNI_OnLoad(JavaVM vm, void reserved)

{

JNIEnv * env;

vm->GetEnv((void**)&env,JNI_VERSION_1_6);

JNINativeMethod methods[] = {

{"stringFromJNI","()Ljava/lang/String;",(void*)stringFromJNI},

};

env->RegisterNatives(env->

FindClass("cn/hluwa/demo01/MainActivity"),methods,1);

return JNI_VERSION_1_6;

}

JNINativeMethod结构体有三个成员,第一个是java层的方法名,第二个是方法签名(括号内是参数类型括号后是返回类型,具体可搜索JNINativeMethod signature这里暂不多讲),第三个是C函数指针。这样三个参数就便成了一组注册信息。

反编译的时候可能会是这样子的(C++编译。C编译出来函数名只有RegisterNatives):

第一个其实就是JNIEnv,第二个是class,第三个是methods。

所以如果在逆向过程中看到这个函数的调用,那么直接查看第三个参数即可得到具体的注册信息。

image.png

c++filt 解开name mangling

第二十九课 Frida$Native:Frida hook libssl

  • 安卓系统框架中的SSL库解析
  • Java层与Native层对照联动关系
  • frida-trace so导出表自动化trace
  • 枚举系统库的符号表和导出表

使用sub 和 add 对地址进行操作

  • frida hook native打印各种数据类型

对照C里面的接口体打印

hexdump 对照地址查看 涉及内存布局问题

  • frida RPC 流量重组成pcap保存

我的native函数?在哪个so里?→ 枚举一下所有的导出函数和内部符号(如果是动态注册,就失效了)

意义在于稍微提高一下native hook的速度

So层相关操作:

https://www.anquanke.com/post/id/195869

frida-trace -UF -I xxx.so

frida-trace -U -f xxx(app包名) -I xxx.so

trace 一个so的所有方法

所有https就是走的 libssl.so 里面的 SSL_write 和 SSL_read

疑问:

int SSL_read(SSL *ssl, void *buf, int num)

int SSL_write(SSL *ssl, const void *buf, int num)

为啥里面的buf 可以直接readCstring打印出来?

什么情况下使用readCString?

读取指针地址位置的字节字符串

对应的writeUtf8String是写入指针地址位置的字符串处

const newPtrstr = r.writeUtf8String("haha");                             console.log("readCString():"+newPtrstr.readCString());

readCString([size = -1])

readUtf8String([size = -1])

readUtf16String([length = -1])

readAnsiString([size = -1]):

  • 在该存储器位置为ASCII,UTF-8,UTF-16,或ANSI字符串读取字节。size如果您知道字符串的大小(以字节为单位),则提供可选参数,或者忽略该字符串,或者如果该字符串是NUL终止的,则指定-1。同样,length如果您知道字符串的长度(以字符为单位),则可以提供可选参数。
    如果从该地址读取的size/length字节中的任何一个不可读,则将引发JavaScript异常。
    请注意,readAnsiString()仅在Windows上可用。
  • writeUtf8String(str)writeUtf16String(str)writeAnsiString(str):编码和写入的JavaScript字符串到这个存储位置(与NUL -终止子)。
    如果写入该地址的任何字节不可写,则将引发JavaScript异常。
    请注意,writeAnsiString()仅在Windows上可用。

第三十课 Frida$Native:Frida hook libc

  • libc.so介绍:glibc、Linux C、bionic C
  • 字符操作关键函数:strstr,strlen

检测xp frida 等 可以过反调试

  • 文件操作关键函数:open,fopen,write
  • 网络操作关键函数:recv,send
  • 线程操作关键函数:pthread_create

可过反调试,判断第三个参数是否为反调试函数

枚举符号的修复一下

如果玩的6,可以得到app的所有信息

C库的trace还是比较麻烦的,太靠底层了

系统理解的有多深,app的秘密就越少

第三十一课 自制路由器:OSI七层模型之网络层

  • Kali Linux/Nethunter常用网络命令
  • 网络工具集/瑞士军刀:netwox
  • 网络层:MAC/IP/ARP/DHCP
  • 传输层:TCP/UDP/ICMP
  • 应用层:DNS/Telnet/NC/FTP/HTTP

终极目的:让App毫无感知就被抓包了

ARP防洪攻击:网络层的中间人攻击:工作原理是在网络层

iptables:制作更加复杂的路由器

ICMP:两件事情:ping && traceroute && 网络探测/网络主机发现

第三十二课 自制路由器和4G代理

  • PC Kali Linux 自制路由器
  • 树莓派刷Kali Linux自制路由器

https://konstakang.com/devices/rpi4/

  • 树莓派刷安卓10运行安卓原生App
  • 手机刷Kali Nethunter制作4G代理
  • curl/requests/scrapy使用4G代理

https://gadgetversus.com/processor/broadcom-bcm2711b0-specs/

curl → proxychains → sslocal → nps → 内网穿透 → npc → ssserver → 4G

第三十三课 自制路由器:传输层协议

  • 树莓派从U盘启动
  • 树莓派刷Kali Linux自制路由器
  • 传输层:ICMP/TCP/UDP
  • 应用层:DNS/Telnet/NC/FTP/HTTP
     

题外话:QUIC 部署最新的技术、得到最强的性能、而不需要浏览器的兼容

https://tech.meituan.com/2017/03/17/shark-sdk.html

中文字符默认UTF8编码传输:https://www.qqxiuzi.cn/bianma/Unicode-UTF.php

推荐使用netcat进行各种网络行为

第三十四课 FRIDA补充

  • HOOK补充
  • 主动调用补充
  • 参数构造补充
  • 动态加载DEX

Java.enumerateClassLoaders(callbacks)

Java.ClassFactory

  • get(classLoader):获取给定类加载器的类工厂实例。幕后使用的默认类工厂仅与应用程序的主类加载器交互。其他类加载器可以Java.enumerateClassLoaders()通过此API找到并与之交互。
  • loader:只读属性,为当前使用的类加载器提供包装。对于默认的类工厂,将通过首次调用来更新Java.perform()

枚举classloader 再用java.Class.Factory切换才能找到loader的类

试试 get 是否能够同时获取多个classloader -> 没成功 就使用Java.classFactory.loader = loader  来切换

image.png

  • native hook补充

主动调用的参数构造两种方法:

  • 一种是先hook
  • 自己new一个
  • (域里反射拿一个)

hook native函数 使其不要执行

Interceptor.replace

反调试试验:自己的程序kill别的程序 查看adb logcat

第三十五课:Frida辅助证书解绑两大案例

  • 服务器校验客户端证书,原理和案例
  • Frida绕过检测开启抓包自动退出
  • 客户端证书和密码直接Frida自吐
  • 客户端证书格式互转及导入抓包
  • 证书绑定场景的鉴定,分析和解绑
  • 混淆后的证书绑定Frida解绑抓包

服务器在校验客户端证书:400 No required SSL certificate was sent

证书绑定校验失败:Client closed the connection before a request was made. Possibly the SSL certificate was rejected.

You may need to configure your browser or application to trust the Charles Root Certificate. See SSL Proxying in the Help menu.

SSL pinning的解法

hook java.io.file.$init 来获取调用栈 和读取的证书进行查找位置 进行unpinning

hook openssl 加密库也可以?

也可以看logcat的日志...

第三十六课 HOOK抓包通杀脚本

  • ssl-logger项目code-review
  • 根据hook触发客户端地址
  • 兼容性测试→迁移到安卓10
  • byte[]的子字符串及发送给python
  • Wireshark的一些基操

review r0caputre

试试最新的frida

  •  

猜你喜欢

转载自blog.csdn.net/weixin_45316122/article/details/114673472