超星学习通enc加密算法分析过程

前言

最近做完超星学习通的秒签到+秒抢答软件后,有很多人来找我让我做一下学习通的刷课软件,但是我又没时间,所以第一次有人找我的时候,我就粗略的上去看了一下,发现有加密,就放弃了,但是越来越多人找我做,我就想着再去看看,今天是2020年11月22日,星期日,花了一个下午搞明白的他的加密算法,如果你对这个有兴趣,或者你正在做相关软件或网站,不妨看看这篇文章,看看我是如何分析的

正文

首先我们要了解到的是,学习通的网课视频是如何判定看完的,通常我们第一时间想到的过程是

1.打开相关课程页面     2.看完整段视频     3.等橙色的点变成绿色

所以,由上面的步骤,我们先来走一走正常流程,这里我找一个已经看过的视频进行分析,这个看没看过的视频无所谓,分析一下是如何判定的而已

第一步,打开相关学习页面

调出开发者工具

回到刚才的学习页面,刷新一下,就会有网页的所有提交过程

这时我们点一下播放,看看会发生什么

我们会关注到这里多了3行东西,而第三行是没用的,只有第二行才是重点,我们继续

因为是已经学习过的课程,所以在这个课程里我们可以随意拖动进度条,把进度条拖到最后几秒钟,等待自动结束看看又会发生什么

我们会关注到,绿色是我们点击播放出现的,当我们拖动进度条到最后,自动播放完毕后,会提交红色框内的2条数据,此时整个看视频的过程就走完了,下面开始进入分析正题

正文

还是上面的步骤,当我们看完视频的时候,会分别提交出多个数据包,而上面绿框和红框内的数据包有什么不同呢,我们来对他们进行分析

https://mooc1.chaoxing.com/multimedia/log/a/159053481/459a84d22d9bab980108f737f78de5fb?clazzId=34658305&playingTime=0&duration=1383&clipTime=0_1383&objectId=985c75c3f1e9f5781d4d0b563b52e49a&otherInfo=nodeId_384296572-cpi_159053481&jobid=1606028367568197&userid=156497977&isdrag=0&view=pc&enc=4eef75716f50dfa7a190b73605760fd2&rt=0.9&dtype=Video&_t=1606058953735
// 上面是点击播放时的数据
// 而下面则是播放完毕的数据
https://mooc1.chaoxing.com/multimedia/log/a/159053481/459a84d22d9bab980108f737f78de5fb?clazzId=34658305&playingTime=1383&duration=1383&clipTime=0_1383&objectId=985c75c3f1e9f5781d4d0b563b52e49a&otherInfo=nodeId_384296572-cpi_159053481&jobid=1606028367568197&userid=156497977&isdrag=4&view=pc&enc=05258c7ba96ef4153b9321298ef679f0&rt=0.9&dtype=Video&_t=1606058966451

这时,我们观察到这两条数据有三个地方是不一样的

第一个地方,是他们的playingTime值不一样

第二个地方,是他们的enc值不一样

第三个地方,是他们的_t值不一样

也就是说通过分析,我们得出3个地方是不一样的结果

首先来观察playingTime 这个参数,一开始我们点击播放的时候,playingTime的值为0,当我们播放完毕的时候,playingTime的值是1383,试着猜想一下,这个playingTime有什么用,再结合playingTime的翻译,我们粗略可以得出,这应该是一个判断当前播放时间的参数,为了认证这个想法,我们可以多次尝试点击暂停,然后等待几秒钟,再点击播放,最终可以证实我们的猜想是正确的

那解决了playingTime的问题,我们就要来解决_t的问题,如果你接触过相关开发,基本上可以得出这是一个16位的现行时间戳

当我们解决了playingTime_t的值后,我们就要来解决enc这个值了

这时我们试着把我们抓出来的第一条数据,把playingTime的值修改一下,再在浏览器调用一下,你会发现,403了,这是因为enc这个值我们还没计算出来,所以接下来我们就要分析enc这个值是如何去计算的

计算enc值

一般这种加密算法都会通过js计算,也就是JavaScript来计算,所以我们首先通过js来判断一下

首先刚才的开发者工具中加载了很多js文件,我们不能盲目一个一个看,我们需要找的是有关键字的js文件,例如加密,播放,视频,进度等类型的js文件,点击开发者工具的放大镜进行搜索,输入enc,回车后会得出相关内容

这时我们需要做的是通过关键字来找js文件,最终,在videojs-ext.min.js 文件中找到关于enc的信息

从箭头指向的enc=可以轻松看出enc的值是由什么构成的

var sendLog_ = function(player, isdrag, currentTimeSec, callback) {
            if (!params.reportUrl) {
                return
            }
            if (params.isFiled == 1 || params.state == 1) {
                return
            }
            var format = "[{0}][{1}][{2}][{3}][{4}][{5}][{6}][{7}]"
              , clipTime = (params.startTime || "0") + "_" + (params.endTime || params.duration);
            var enc = Ext.String.format(format, params.clazzId, params.userid, params.jobid || "", params.objectId, currentTimeSec * 1000, "d_yHJ!$pdA~5", params.duration * 1000, clipTime);
            var rurl = [params.reportUrl, "/", params.dtoken, "?clazzId=", params.clazzId, "&playingTime=", currentTimeSec, "&duration=", params.duration, "&clipTime=", clipTime, "&objectId=", params.objectId, "&otherInfo=", params.otherInfo, "&jobid=", params.jobid, "&userid=", params.userid, "&isdrag=", isdrag, "&view=pc", "&enc=", md5(enc), "&rt=", params.rt, "&dtype=Video", "&_t=", new Date().getTime()].join("");
            logFunc(player, rurl, callback)
        };

从代码中我们可以看出enc 的值分别由clazzId userid jobid objectId currentTimeSec * 1000 d_yHJ!$pdA~5 duration * 1000 clipTime 这几个参数组成,再对比一下我们播放完毕提交的数据包

https://mooc1.chaoxing.com/multimedia/log/a/159053481/459a84d22d9bab980108f737f78de5fb?clazzId=34658305&playingTime=1383&duration=1383&clipTime=0_1383&objectId=985c75c3f1e9f5781d4d0b563b52e49a&otherInfo=nodeId_384296572-cpi_159053481&jobid=1606028367568197&userid=156497977&isdrag=4&view=pc&enc=05258c7ba96ef4153b9321298ef679f0&rt=0.9&dtype=Video&_t=1606058966451

不难看出,我们所找到的enc算法是正确的.

那么现在enc的初步算法我们已经找到了,但问题来了,我们该如何去找出这几个参数呢,还记得我们刚才做的步骤吗,我们把播放到播放完毕的流程数据包都抓下来了,现在分析一下数据包就好了,首先,观察一下clazzId userid通过字面意思,基本上我们可以得出clazzId userid就是班级id和用户id的意思,这就简单了.

首先,如果你成功做到登录并且获取到相关课程列表,你一定会得出userid 我相信这对你来说并不难

其次,我们可以从相关学习页面的链接中找到clazzId到这里,我们已经成功找出了useridclazzId接下来我们的任务,就是要找到jobid objectId currentTimeSecduration clipTime 

找出其他参数

假设我们已经通过技术获取到课程主页,并且获取到每一个课程的链接

第一步

我们模拟我们已经拿到了课程目录的链接

https://mooc2-ans.chaoxing.com/mycourse/studentcourse?courseid=215590920&clazzid=34658305&cpi=159053481&ut=MSIE

从这个链接里面我们可以获取到的参数就是clazzId和有可能用到的courseIdcpi

第二步

在这一步,我们已经进入到目录页面,我们需要做的是获取每一个小目录的地址,我们可以从第一步的页面源代码中找到,并且找到需要用到的初次enc 值

同时我们可以通过toOld这个函数来获取初次enc 值

这时我们就有一个很明确的地址指向了,现在我们打开测试目录的1.1二级目录,也就是这个链接

https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId=[knowledgeid]&courseId=[courseid]&clazzid=[classid]&enc=[首次enc]&cpi=159053481&openc=61c08127d51b246d0dac27e8a94f1c24

这时我们就会得出一个问题,图中并没有明确表示出openc 和chapterid 的值,我们该如何找到呢

首先看图中的toOld的function可以看出括号内第二个就是knowledgeid ,而从程序代码中不难看出knowledgeid就等于chapterid所以这个问题我们就解决了,那现在缺的就是openc我们先可以把这个openc给去掉,看看能否访问页面,结果是可以的

但为了保证严谨的态度,我们要找出openc该怎么找呢

经过返回查找,最终我们在

https://mooc2-ans.chaoxing.com/mycourse/stu?courseid=[courseid]&clazzid=[classid]&cpi=[cpi]&enc=[首次enc]&t=[16位现行时间戳]&pageHeader=1

这个页面的源代码中找到openc的值

到这里我们就成功进入到相关视频页面,那接下来我们就需要找有用的参数了

第三步

在视频页面的源代码中,我们发现到一个需要用到前面所找出的参数的

同时我们在下面找到相关链接

这时我们单独对这个链接进行访问,看看会得出什么

这时我们会发现,页面返回了一个视频,而这个视频正是我们视频学习页面的视频,那我们就单独对这个页面进行数据提取

但你也会发现,到了这里,我们好像没有任何参数进度,别着急,你已经成功了一半了

第四步

前面说到,我们需要找出视频看完认证需要的参数有jobid objectId currentTimeSecduration clipTime

而我们单独对视频页面进行数据提取,我们试着搜索jobid看看会发生什么

这时你会发现,我们非常轻松地找出jobid这个参数

继续寻找objectId currentTimeSecduration clipTimeobjectId试试

结果不出所料,我们同样找出objectId,同样的,你会发现有几个参数非常熟悉,首先是duration,dtoken,还记得前面说过的东西吗,我们需要提交视频完整看完的数据包由clazzId userid jobid objectId currentTimeSec * 1000 d_yHJ!$pdA~5 duration * 1000 clipTime 这几个参数组成,现在我们已经把全部参数找出来了,而现在有2个问题

currentTimeSec * 1000是什么?

这个我们可以看成duration * 1000

clipTime0_xxxxxx 我们也可以看成0_duration

所以我们已经找出所有的参数

但是现在还差一个东西,那就是otherInfo=nodeId_384296572-cpi_159053481 这个otherInfo 的值,这个在哪里找呢

我们在单独的视频页面尝试搜索一下otherInfo这个值,发现他与objectId位于同一行

到这里我们已经把所有的参数都找出来了

还记得我们视频看完所提交的数据包吗

https://mooc1.chaoxing.com/multimedia/log/a/159053481/459a84d22d9bab980108f737f78de5fb?clazzId=34658305&playingTime=1383&duration=1383&clipTime=0_1383&objectId=985c75c3f1e9f5781d4d0b563b52e49a&otherInfo=nodeId_384296572-cpi_159053481&jobid=1606028367568197&userid=156497977&isdrag=4&view=pc&enc=05258c7ba96ef4153b9321298ef679f0&rt=0.9&dtype=Video&_t=1606058966451

这个数据包中的enc 值是05258c7ba96ef4153b9321298ef679f0

那么现在我们就通过enc算法来验证一下是否为这个值

而通过上文,我们知道enc的算法是

var sendLog_ = function(player, isdrag, currentTimeSec, callback) {
            if (!params.reportUrl) {
                return
            }
            if (params.isFiled == 1 || params.state == 1) {
                return
            }
            var format = "[{0}][{1}][{2}][{3}][{4}][{5}][{6}][{7}]"
              , clipTime = (params.startTime || "0") + "_" + (params.endTime || params.duration);
            var enc = Ext.String.format(format, params.clazzId, params.userid, params.jobid || "", params.objectId, currentTimeSec * 1000, "d_yHJ!$pdA~5", params.duration * 1000, clipTime);
            var rurl = [params.reportUrl, "/", params.dtoken, "?clazzId=", params.clazzId, "&playingTime=", currentTimeSec, "&duration=", params.duration, "&clipTime=", clipTime, "&objectId=", params.objectId, "&otherInfo=", params.otherInfo, "&jobid=", params.jobid, "&userid=", params.userid, "&isdrag=", isdrag, "&view=pc", "&enc=", md5(enc), "&rt=", params.rt, "&dtype=Video", "&_t=", new Date().getTime()].join("");
            logFunc(player, rurl, callback)
        };

解释一下

这里的[{0}][{1}][{2}][{3}][{4}][{5}][{6}][{7}] 的意思就是

[classid][userid][jobid][objectId][currentTimeSec * 1000][d_yHJ!$pdA~5][duration * 1000][clipTime]

那么到这里,我们把所有的参数已经提取出来了

[classid] = 34658305
[userid] = 156497977
[jobid] = 1606028367568197
[objectId] = 985c75c3f1e9f5781d4d0b563b52e49a
[currentTimeSec * 1000] = duration * 1000 = 1383000
[d_yHJ!$pdA~5] = d_yHJ!$pdA~5
[duration * 1000] = 1383000
[clipTime] = 0_1383

所以整理一下就是

[34658305][156497977][1606028367568197][985c75c3f1e9f5781d4d0b563b52e49a][1383000][d_yHJ!$pdA~5][1383000][0_1383]

现在我们的任务就剩下1个了

那就是把这串东西进行Md5加密即可

当然,毫无疑问是一致的

但还没结束,计算出enc后,需要把相应数据重新放进提交数据包中,就像这样

https://mooc1.chaoxing.com/multimedia/log/a/[cpi]/[dtoken]?clazzId=[classid]&playingTime=[duration]&duration=[duration]&clipTime=0_[duration]&objectId=[objectid]&otherInfo=[otherInfo]&jobid=[jobid]&userid=[userid]&isdrag=4&view=pc&enc=[Md5计算过后的enc值]&rt=0.9&dtype=Video&_t=[16位现行时间戳]

你只需要将链接中的相应参数填入就好了,例如本次测试的视频最终数据提交包就是

https://mooc1.chaoxing.com/multimedia/log/a/159053481/459a84d22d9bab980108f737f78de5fb?clazzId=34658305&playingTime=1383&duration=1383&clipTime=0_1383&objectId=985c75c3f1e9f5781d4d0b563b52e49a&otherInfo=nodeId_384296572-cpi_159053481&jobid=1606028367568197&userid=156497977&isdrag=4&view=pc&enc=05258c7ba96ef4153b9321298ef679f0&rt=0.9&dtype=Video&_t=1606058966451

这样我们的enc算法就已经分析完毕了,同时我们也做到了秒刷课的效果

但请注意,超星学习通会对此类操作进行相关检测,若有异常,会导致你的课程全部清空需要重新学,或者扣学分的操作

所以,本文只是作为学习参考,一切后果作者概不负责

版权声明:
作者:X1a0He
链接:https://www.x1a0he.com/xxtenc
来源:X1a0He's Blog
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>