NINGCOL 发表于 2021-3-16 14:15

逆向App获取api接口数据

本帖最后由 NINGCOL 于 2021-3-19 08:48 编辑

#### 1、准备工作

* Hopper Disassembler
* Reveal
* Charles
* XCode已经安装好MonkeyDev

#### 2、目标

   对目标app的接口返回内容进行解密

#### 3、开始

1. 先使用Charles对目标app配置好代{过}{滤}理。我们打开app,进入首页,刷新下数据。
   [!(https://s3.ax1x.com/2021/02/23/ybaM2F.png)](https://imgchr.com/i/ybaM2F)

   我们先看看这个app是个啥样子的,多点下界面看看后台返回的数据,发现首页的content是加密的字符串金句下面的每个content也是加密的,广场下的接口返回并没有加密。
   [!(https://s3.ax1x.com/2021/02/23/ybaivQ.md.png)](https://imgchr.com/i/ybaivQ)

2. 首页和金句下的接口返回的字段很多都是一样的,我们可以猜测应该加密方式应该是一样的,金句的接口返回的内容多,我们直接看金句的。
   [!(https://s3.ax1x.com/2021/02/23/ybaEbn.png)](https://imgchr.com/i/ybaEbn)
   
3. 打开Reveal分析下界面布局,我们发现内容label是在JRSentenceTableViewCell这个cell里面,整个cell是放在JRNodeSentenceInnerListView这个控制器中的
   !(https://s3.ax1x.com/2021/02/23/ybafxg.md.png)
   !(https://s3.ax1x.com/2021/02/23/ybaeU0.md.png)
   
4. 接下来进行我们进行静态分析,把砸壳好的目标app拖到Hopper Disassembler中,等子弹飞一会,我们直接在右边搜索JRSentenceTableViewCell这个关键字,看看里面都有哪些方法
   !(https://s3.ax1x.com/2021/02/23/ybawxe.png)]
   
   看到了一些初始化方法,以及刷新数据的方法,仔细看看, 刷新内容?感觉貌似有点像,我们看看
   !(https://s3.ax1x.com/2021/02/23/ybayVI.md.png)
   
   首先我们看 `ldr      x0, `这行,这行是把x0 + x23地址存储的字节给x0,所以现在x0就是*(self + sentenceBean)

   接着往下, `adrp    x8, #0x100ea9000` 0x100ea9000这个基址放在了x8里,x8+0xfd8就是textModel方法,方法放在了x20里
   `mov   x1, x20` 接着x20又赋值给了x1
   `bl   imp___stubs__objc_msgSend` 这里你就可以理解为,说到这里又有很多同学看不懂了,要理解这里,必须要理清楚方法调用的本质是什么
   
   !(https://s3.ax1x.com/2021/02/23/ybarqA.md.png)

看这张图,x0里面是self.sentenceBean,方法就是textModel,刚刚我们说过放在了x1里,现在我们来看就很容易理解了
   `mov      x21, x0` 这里的x0和x21 = 返回的值,我们先叫做a
   ` x1, `这里x1就是listTextHeight方法,x0就是textModel返回的值,就可以理解为,这个方法的作用就是根据文字内容算出文字高度
   就这样我们一直慢慢的往下分析,
   `ldr      x21, ` 这里的x21 = self.contentLabel
   `ldr      x0, ` 这里的x0 = self.self.sentenceBean,往下然后调用
   `mov      x22, x0 `x22 = listShowString方法返回的字符串s
   `ldr      x1, `这行代码,获取setAttributedText:
   `mov      x0, x21` 紧接着就是x21赋值给x0,这里的x21 = contentLabel
   `mov      x2, x22 ` x2 = x22 = s
   `bl         imp___stubs__objc_msgSend` 根据上面讲的可以翻译为[],这里就是设置label的文字内容

   !(https://s3.ax1x.com/2021/02/23/ybdAzD.md.png)

根据上面的分析我们就是知道文字的内容是从sentenceBean中来的,接下来我们直接搜索**sentenceBean**

!(https://s3.ax1x.com/2021/02/23/ybd9d1.png)

我们可以看到有很多set和get方法,头像、作者、内容、照片等等,根据编程经验,我们就知道cell的内容都是从这里来的了,也就是MVVM中的viewModel,数据的处理都在这里面,解密算法应该也是在这里面。在刚刚的搜索结果中我们发现了一个方法
   `-`

ivString这个东东,这不就是加解密用到的偏移量么,直接点开汇编,密密麻麻的好多行

!(https://s3.ax1x.com/2021/02/23/ybdGQg.md.png)

!(https://s3.ax1x.com/2021/02/23/ybdlJf.png)

打开结构图,逻辑也是相当复杂,这里就不具体列出来了,大概的内容就是在字典里取头像、作者、图片,判断是不是vip啥的这些东西;为什么有这么多的跳转?都是因为**cbz**这个指令,结果为零跳转执行,不为零就是接着后面的代码执行,代码里冲字典取值的时候都判断了值有没有,有才给JRSentenceBean里的属性赋值,所以才有那么多的跳转。

查看伪代码也可以看出来,其实没有那么多的跳转,我们直接查看伪代码

[!(https://s3.ax1x.com/2021/02/23/ybd8SS.md.png)](https://imgchr.com/i/ybd8SS)

发现`TripleDESDecryptWithKey:@"c3fea9f12db38ecbda3c408f"`出现了这个,是不是我们需要的解密方法呢?在前面发现也有个`@selector(deStringWithIv:)`判断了r0 != 0 才执行这个,那这个r0是个什么?我们打开结构图进行分析
[!(https://s3.ax1x.com/2021/02/23/ybdQFP.md.png)](https://imgchr.com/i/ybdQFP)

发现x1就是 ojectForKey方法,然后调用 ,判断返回的值为不为0,所以r0就是字典中i_s_e的值了,在上面的抓包中,我们发现有返回一个i_s_e的bool类型,发现就是true,所以解密的方法应该是**deStringWithIv**,而不是**TripleDESDecryptWithKey**这个,**deStringWithIv**方法需要传一个参数,就是传进来的ivString

接着点击**deStringWithIv**方法,看看他是怎么写的,直接看伪代码,发现需要r21和r22,r22就是刚刚的ivString,
[!(https://s3.ax1x.com/2021/02/23/ybd1W8.png)](https://imgchr.com/i/ybd1W8)

那r21呢?是这个单例里的cs,我们点进去看看
[!(https://s3.ax1x.com/2021/02/23/ybdJyQ.png)](https://imgchr.com/i/ybdJyQ)

self + 0x58,偏移了58,我们直接搜这个JRGlobalTool关键字

[!(https://s3.ax1x.com/2021/02/23/ybdNes.md.png)](https://imgchr.com/i/ybdNes)

进到init方法,发现有个parseKS方法,点进去看看,`*(self + 0x58) = @"dc04d6c00f50e75ae57dd6b9549440dd";` 这个就是我们需要的cs了,带回到原来的代码``这样我们只要拿到iv就可以解析出content的内容了

[!(https://s3.ax1x.com/2021/02/23/ybdYLj.png)](https://imgchr.com/i/ybdYLj)

那我们怎么拿到iv呢,回到`-`方法中

[!(https://s3.ax1x.com/2021/02/23/ybd0YV.png)](https://imgchr.com/i/ybd0YV)

点击右键,选择**references to selector initWithDict:viewType:ivString:**, 发现有个signature字段,整个感觉应该是在发送网络请求

[!(https://s3.ax1x.com/2021/02/23/ybdBWT.md.png)](https://imgchr.com/i/ybdBWT)

接下来用xcode新建一个hook项目,接下来hook一下initWithDict这个方法方法

[!(https://s3.ax1x.com/2021/02/23/ybdrSU.md.png)](https://imgchr.com/i/ybdrSU)

跑到真机上可以看到控制台上的输出,多下拉刷新几次,发现这个iv是变的,每次请求都不一样

[!(https://s3.ax1x.com/2021/02/23/ybdgm9.md.png)](https://imgchr.com/i/ybdgm9)

刚刚在上面提到发送请求貌似有个signature字段,我们看看Charles里的请求,就有一个signature,并且和控制台打印的一致。现在我们就知道``这里面的iv了

[!(https://s3.ax1x.com/2021/02/23/ybdyy4.md.png)](https://imgchr.com/i/ybdyy4)

#### 4、验证
最后来验证一下,po结果和解密完全一致

[!(https://s3.ax1x.com/2021/02/23/ybd2wR.md.png)](https://imgchr.com/i/ybd2wR)

NINGCOL 发表于 2021-4-16 19:54

o0蜗牛 发表于 2021-4-16 15:25
楼主,android也一样吗?
app修改后无法进行微信分享,弹出不是正版软件,是不是根据你分享的就可以实现修 ...

可以的,代码有检测,把检测的hook就行了

o0蜗牛 发表于 2021-4-16 15:25

楼主,android也一样吗?
app修改后无法进行微信分享,弹出不是正版软件,是不是根据你分享的就可以实现修改后也可以进行微信分享呢?

kevinZheng1314 发表于 2021-3-18 08:29

太厉害了吧

xterminal 发表于 2021-3-18 09:03

学习了,不错的分享

LK5325 发表于 2021-3-18 09:44

学习到了,不错

茶茶大人L 发表于 2021-3-18 14:43

不明觉厉{:1_893:} 看完了受教

NINGCOL 发表于 2021-3-19 08:46

排版乱了,重新修改了下

NINGCOL 发表于 2021-3-19 08:53

茶茶大人L 发表于 2021-3-18 14:43
不明觉厉 看完了受教

仔细看看,边看边做,就能弄明白了,很简单的

chenjicong1204 发表于 2021-3-20 14:28

谢谢楼主分享!

淡凡 发表于 2021-3-20 20:30

太厉害,学习

lanxiaopeng 发表于 2021-3-21 00:07

学习,感谢分享
页: [1] 2 3
查看完整版本: 逆向App获取api接口数据