自动化易班健康打卡

疫情又反复了学校又开始要求打卡了可最近的阴间作息3点睡12点起让我实在难以完成学校的要求每天12点前上报健康状况所以只能寻求自动化手段了

在网上稍微搜寻发现已有前辈做的研究了Github仓库但是原作者已删库跑路易班的API似乎也有更新打卡的表单也有修改所以我们还需要稍作修改

1.png

1. 表单更新

观察源代码得大体思路是模拟登录后拿到token使用token调用查询未完成任务列表的接口从结果中查找指定类型的任务拿到表单ID再向另一个接口提交表单ID与提交的数据则任务完成

其中关键的控制表单内容的部分如下

 dict_form = {"2fca911d0600717cc5c2f57fc3702787": ["湖南省", "长沙市", "天心区"],
                        "cab886bf693f23a34ed78ed71deaadc3": yb.name,
                        "b418fa886b6a38bdce72569a70b1fa10": ["36.2", "36.3", "36.4", "36.5", "36.6", "36.7", "36.8"][random.randint(0, 6)], # 随机体温
                        "c77d35b16fb22ec70a1f33c315141dbb": util.get_time_no_second()}

很明显每项数据的字典就是字段ID后者就是字段的数据我们的表单结构更新只需要拿到新版表单的字段ID对应修改就行

那么要拿到表单ID就需要拿到表单的源代码为了避开移动端抓HTTPS包的困难但是后面还是没有避得开这里采用FiddlerWindows微信用电脑版微信访问易班校本化的微信公众号平台

模拟人工完成一次打卡抓到一系列的API分析打卡过程如下

  1. 获得未完成的任务列表每个任务有一个TaskID

  2. 根据TaskID拿到表单模板IDWFid

  3. 请求拿到表单模板的各个字段名称ID类型等等模拟提交的程序不需要这个接口

  4. 将表单的数据与对应的任务ID POST提交回去

2.png
3.png
4.png
5.png

与前辈的代码对比发现表单提交的部分并没有改动相应的修改了表单结构替换代码即可

dict_form = {"2fca911d0600717cc5c2f57fc3702787": ["湖南省", "123", "456"],
                        "db19a5f588037889a2ff5b6894a303a9":"绿码",
                        "19ba06c51ab8eee843a235ece7064865":"第二针",
                        "2d4135d558f849e18a5dcc87b884cce5": "36", # 随机体温
                        "c77d35b16fb22ec70a1f33c315141dbb": util.get_time_no_second()}

2.接口变更

改好后试了一下发现报登录失败但是检查了账号信息是没有错误的

6.png

查看前辈代码中登录相关的部分发现是登录的API过期了如图一所示代码如下

def login(self):
        params = {
            "mobile": self.account,
            "imei": "0",
            "mobile": self.passwd
        }
        # 最新不需要加密密码直接登录的接口来自我B站视频评论用户破损的鞘翅(bilibili_id:45807603)
        r = self.request(url="https://mobile.yiban.cn/api/v3/passport/login", params=params)
        if r is not None and str(r["response"]) == "100":
            self.access_token = r["data"]["user"]["access_token"]
            return r
        else:
            raise Exception("账号或密码错误")

试了一下版本号发现应该是v4但是麻烦的是v4的登录接口有变动方法变为了POST字段至少还需要一个ct而该字段的含义就不清楚了所以在这里我想着在易班的产品上再找找机会

7.png

整理一下思路

我们的目的是拿到AccessToken这个往往能用比较长的一段时间

要么更新至新版API的登录接口用密码拿到AccessToken有两个途径抓包得到新版接口的结构逆向App

要么曲线救国直接利用已有的AccessToken如果失效就人工更新一般是把登录后得到的Token保存在App数据库里面Root后拿到应该是不难的

要么模拟微信公众号的认证过程获得授权这个可以绕过易班主App的认证个人认为这个最难成功概率最低

尝试1利用主站PC网页端登录用从网页端ajaxlogin接口拿到的token来尝试结果失败似乎移动端网页端的认证是分开的从产品的角度感觉也是分开的PC网页与移动端很多功能都不交叉

尝试2在网上找到一些 其他的资料v4接口提示缺的ct等字段补充了结果最后接口就直接报客户端版本低似乎与ctidentity的值有关

尝试3么的办法还是只能抓包试一下了看看到底是个啥接口

由于Android 7以上系统对SSL证书进行了二次校验App默认将不再信任用户加载的证书除非Root后加载到根证书区域为了避免麻烦我尝试使用Android 6的模拟器将模拟器的网络流量导入Fiddler第一次使用的模拟器是x86无法安装直接报不符合ABI错误看来App没有声明X86的支持

PS C:\Users\fyyo4\AppData\Local\Android\Sdk\platform-tools> .\adb install C:\Users\fyyo4\Downloads\yiban_20210810_501.apk
Performing Push Install
C:\Users\fyyo4\Downloads\yiban_20210810_501.apk: 1 file pushed, 0 skipped. 230.0 MB/s (31692716 bytes in 0.131s)
        pkg: /data/local/tmp/yiban_20210810_501.apk
Failure [INSTALL_FAILED_NO_MATCHING_ABIS]

后面换了个armel的镜像不知道是因为存在指令集转换本来就这么慢还是Android AVD的官方模拟器跨指令集效率太低模拟器十分缓慢在我的电脑上完全无法正常使用

后续可以更换其他模拟器尝试一下但是就有点繁琐先放在这里吧

为什么不用实机实体机是Android 9要关闭HTTPS Pinning要么Xposed HOOK比如插件JustTrustMe要么想办法修改Target API低于Android 7

一般的做法是基于后者用平行空间等双开App动态运行APK如果宿主APP平行空间Target API是低于Android 7那么运行在宿主App容器中的目标App就变相降低了Target API这个时候抓宿主App的包就都可以抓到了但是在我的手机上总是安装不上平行空间的64位支持包

前者也有尝试过太极和VirtualXposed太极可以正常使用但是太极中JustTrustMe似乎没有启用App还是报错Trust anchor for certification path not found. VirtualXposed则无法正常安装易班提示不支持32位应用更换最后一个支持32位应用的版本0.18.2可以正常安装了但是无法运行容器中的易班App

iOS抓包呢iOS似乎没有那么严格的证书问题正常载入的证书似乎都会信任但是这该死的App还对代理做了检测我们暂时没有什么太好的办法接管网络流量要么换区付费装一个能以VPN形式接管网络数据的App然后想办法将流量送到FiddlerHTTP代理做处理要么弄一个特殊处理过的路由器单独给手机用在网关将数据转发到HTTP代理处理但无论是哪个都是不小的工程量很繁琐暂时先搁置在这里

8.png

尝试4想办法逆向App拉进JEB看了一下有很明显的加壳特征确定是腾讯御安全加固

9.png

查了一下网上的资料静态脱壳似乎都是一些商业化的成品工具比如MT管理器ARM Pro什么的没找到一个通用一点的方法动态脱壳在手机上可以使用fdex反射大师什么的PC上的可以用IDA动态脱壳原理基本都是等壳加载完了准备真正注入内存运行时在加载至内存这个关键点做文章有点X86脱压缩壳的味道这几天查资料的过程中有个感受就是Android的壳好像一般对源程序不方便做太多处理所以攻防点基本上都是不让你Debug不让你拿到真实的dex一旦拿到真实dex基本就是胜利了

现有条件不方便脱壳还是只能去装虚拟机了当然装了虚拟机会先试试抓包的

简单的尝试脱壳

更新于2022/2/20.

想办法搞出来了一个Xposed环境尝试了Fdex2和反射大师fdex2加载后闪退反射大师脱壳成功

这里提供一下反射大师脱出来的dex源自易班5.0.8注意是不完整的后文有提到classes.dex

dex再导入jeb可以看到确实得到了不少的内容

Snipaste_2022-02-20_00-48-55.png

com.yiban.app.login.utils下有一个我们感兴趣的类LoginUtil打开发现一部分登录相关的逻辑可以看到登录接口的参数多了不止一点点哦之前我们疑惑的那个ct没想到就是个常数😅

Snipaste_2022-02-20_00-50-17.png

我们关心的加密算法也露出尾巴了是从com.yiban.app.helper.EncryptionHelper这个类的encryptPassword这个方法加密来的双击进入……怎么没反应jebbug再一看我去怎么根本就没有com.yiban.app.helper这个package

Snipaste_2022-02-20_01-00-59.png

再细看原来远不止这一个类没有比如他用的retrofit2框架整个框架都没有见着所以很明显我们得到的dex并不完整尝试了一些其他的方法也没有得到更完整的dex似乎陷入了僵局

网上有说一些可能的原因就是壳在dex的相关位置先nop等到程序真正加载时再填充似乎也不是我这种情况我的dex并没有出现nop而且我是运行过相关逻辑后再脱壳的我的脱壳环境是Android 5.0.1也没有高版本系统那些乱七八糟的优化带来的问题

顺带地在建立Xposed环境时因为是老的安卓版本抓包也没有问题了HttpCanery直接就可以成功抓包App并没有单独验证证书根据抓包的情况看后面的接口应该没有怎么改动但是我拿accesskey直接跑脚本因为一些其他的原因脚本也失败了不确定是不是个例