吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 8070|回复: 76
上一主题 下一主题

[调试逆向] 某大学继续教育平台刷课分析

  [复制链接]
跳转到指定楼层
楼主
laodan 发表于 2020-1-1 14:59 回帖奖励
本帖最后由 laodan 于 2020-1-1 15:16 编辑

前言

前两天发小让找一下有没有可以刷课的平台或者软件,找遍论坛和网络也没有找到关于此学院的信息。
无奈,只能自己上手了。
本文应该可能只适用于河南大学继续教育网络平台

分析

首先网络平台,最关键的就是有一个向服务器提交数据观看时间的请求,综合此情况,那么就开始抓取请求。
以我当前浏览器搜狗浏览器为例,在课程页面按F12键,调出开发者工具,点击NetWork,勾选住PreserveLog(持续日志或译为保留日志)。
点击课程平台,在第一次点击之时是不会有请求信息的,这个在稍候解析JS文件的时候说明。
播放之后再次点击一次需要观看的课程,这个时间首先就出现了请求了。

先来看一下updstatus中的这个请求。

请求地址:

[POST]http://henu.cjnep.net/lms/web/timing/updstatus

请求头:

Cookie: _csrf=xxxx; Hm_lvt_fc82d39d0aabdf72237c051c09b9428e=1577847473; PHPFRONTSESSID=xxxxx; contact=%5B%7B%22id%22%3A%221%22%2C%22teacher_name%22%3A%22%5Cu5e73%5Cu53f0%5Cu4f7f%5Cu7528%5Cu54a8%5Cu8be21%22%2C%22qq_number%22%3A%222924134909%22%7D%2C%7B%22id%22%3A%222%22%2C%22teacher_name%22%3A%22%5Cu5e73%5Cu53f0%5Cu4f7f%5Cu7528%5Cu54a8%5Cu8be22%22%2C%22qq_number%22%3A%221283346554%22%7D%5D; noticeNumber=19; Hm_lpvt_fc82d39d0aabdf72237c051c09b9428e=1577848743

其中关键的参数我已经用xxxx为代替。
请求内容:

userId=xxxx&courseId=xxxx&scoId=27463&historyId=272631&addTime=5&totalTime=1149.619955¤tTime=1008.187626&hasCheckOne=false&hasCheckTwo=false&hasCheckThree=true&firstUpdate=false

userIdcourseId用xxx代替,其中userId身份证号做为判断依据,scoId为当前观看地址中的itemidhistoryId为历史ID,addTime为增加的时间,totalTime为总时间,currentTime为当前播放时间,hasCheckOnehasCheckTwohasCheckThreefirstUpdate为判断,于本文测试无用,暂不自多说。

Cookie中的信息自不必多说,这个为自己的登陆信息。咱们首先在伪造的请求则是请求中的内容。

相同的请求测试一下。

状态为-1,出现了错误。那么说明还是有着验证的,如何寻找到验证呢?
接下来开始寻找关键的JS代码段,来查看JS代码,寻找可能存在的验证。

关键字

关键字为updstatus,为什么选择updstatus,可以看上面的请求地址中,他的文件为updstatus,所以咱们来寻找播放页面所有的JS文件里面,哪个文件包含了updstatus

可以看到在地址中:https://cc9.mynep.com.cn/open/player/jobplayer.js

存在了updstatus关键字,下载下来这个文件。

JS代码段:

        updateStatus: function(finished) {
                if (st_updating) return;
                //if (!finished && Job.conf.lastViewedTime == 0) return; //时间点为0时不提交
                st_updating = true;
                var obj = {};
                obj.userId = Job.conf.userId;
                obj.courseId = Job.conf.courseId;
                obj.scoId = Job.conf.scoId;
                obj.historyId = Job.conf.historyId;
                //obj.addTime = Job.conf.updInterval;//新增学习时间,单位秒
                if (Job.conf.updStime) {
                        var stime = (new Date()).getTime();
                        var diff_time = Math.min((stime - Job.conf.updStime) / 1000, Job.conf.updInterval);
                        if (diff_time < 0) diff_time = 0;
                        Job.conf.updAddTime += diff_time;
                        Job.conf.updStime = stime;
                }
                obj.addTime = Math.floor(Job.conf.updAddTime);//新增学习时间,单位秒
                Job.conf.updAddTime -= obj.addTime;
                obj.totalTime = Job.conf.totalTime;
                if (finished) {
                        obj.finished = 1;
                        obj.currentTime = 0;
                } else {
                        obj.currentTime = Job.conf.lastViewedTime;//当前时间,可用来更新最后一次访问时间,学习到达最远时间点等
                }
                obj.hasCheckOne = Job.conf.hasCheckOne;
                obj.hasCheckTwo = Job.conf.hasCheckTwo;
                obj.hasCheckThree = Job.conf.hasCheckThree;
                obj.firstUpdate = Job.conf.firstUpdate; //第一次提交时,更新,用于统计学习次数
                Job.conf.firstUpdate = false;

                $.ajax(Job.conf.updStatusUrl, {type: 'POST', data: obj, dataType: 'xml'}).done(function(xml) {
                        console.log('update status');
                        if (xml) {
                                var status = Number($(xml.documentElement).find('>status').text());
                                if (status == -1) {
                                        Job.player.pause();
                                }
                                if (!Job.conf.historyId) {
                                        var historyId = Number($(xml.documentElement).find('>historyId').text());
                                        if (historyId) Job.conf.historyId = historyId;
                                }
                                window.onUpdstatus && window.onUpdstatus(status);
                        }
                }).always(function() {
                        st_updating = false;
                });
        }

网站的程序员很贴心啊,还给我备注上了。

基本这个JS代码段看的也是半懂不懂,但大概意思是可以看出来了。

userId=xxxx&courseId=xxxx&scoId=27463&historyId=272631&addTime=5&totalTime=1149.619955¤tTime=1008.187626&hasCheckOne=false&hasCheckTwo=false&hasCheckThree=true&firstUpdate=false

上文所说的这些参数都有涉及。其中最关键的属historyId、和addTime

obj.addTime = Math.floor(Job.conf.updAddTime);//新增学习时间,单位秒
if (!Job.conf.historyId) {
        var historyId = Number($(xml.documentElement).find('>historyId').text());
        if (historyId) Job.conf.historyId = historyId;
        }
        window.onUpdstatus && window.onUpdstatus(status);
        }

addTime为新增的时间,但如果返回正确的话,那么会根据这个时间来相应的增加时间。
再然后重点的是historyId参数。
首先

var historyId = Number($(xml.documentElement).find('>historyId').text());

获取historyId等于XML节点中的historyId,在这个时候就需要问了,XML文件是哪一个?
根据所获取的请求往下翻,看到如下请求:

请求地址

http://henu.cjnep.net/lms/web/course/startupxml?courseid=137&itemid=27463&historyid=272632

首先可以在historyid处看到最终的historyid,当然这个地址也可以在播放页面源文件中存在,可以看到。

伪造请求

请求地址:

http://henu.cjnep.net/lms/web/timing/updstatus

请求头:

Cookie: _csrf=xxxx; Hm_lvt_fc82d39d0aabdf72237c051c09b9428e=1577860273; PHPFRONTSESSID=gns54bbucprdtdgarpk2pl2k76; contact=%5B%7B%22id%22%3A%221%22%2C%22teacher_name%22%3A%22%5Cu5e73%5Cu53f0%5Cu4f7f%5Cu7528%5Cu54a8%5Cu8be21%22%2C%22qq_number%22%3A%222924134909%22%7D%2C%7B%22id%22%3A%222%22%2C%22teacher_name%22%3A%22%5Cu5e73%5Cu53f0%5Cu4f7f%5Cu7528%5Cu54a8%5Cu8be22%22%2C%22qq_number%22%3A%221283346554%22%7D%5D; noticeNumber=19; Hm_lpvt_fc82d39d0aabdf72237c051c09b9428e=1577860296

请求内容:

userId=xxxx&courseId=xxxx&scoId=27463&historyId=272632&addTime=60&totalTime=1149.619955¤tTime=1008.187626&hasCheckOne=false&hasCheckTwo=false&hasCheckThree=true&firstUpdate=false

请求时必须historyId参数必须为XML地址中的historyId参数,不然返回的状态是-1

状态返回成功了,那么返回课程页面看一下效果。
注意:设置的addTime60,那么就是请求一次即为六十秒的时间,多次点击可重复增加时间。


最后说一下

可以制作成软件成为一个半自动,在软件页输入课程地址,通过源码获取到XML地址,再然后将XML地址中的scoIdhistoryId记录下来,scoId为课程地址中的itemid值,historyId为最后时间的参数。
totalTimecurrentTime参数这两个随意,不输入也是可以的。
进行伪造请求即可成功。
请求时请务必关闭已经开启的播放界面,避免页面重复进行数据提交造成historyId参数的改变,导致软件请求不成功。这个是最注意的一点,调试的时候难受的要死。

免费评分

参与人数 20威望 +2 吾爱币 +30 热心值 +17 收起 理由
sunarea14 + 1
叠噢 + 2 + 1 我很赞同!
netCheney + 1 + 1 用心讨论,共获提升!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
建业阳仔 + 1 + 1 谢谢@Thanks!
dandaodaodan + 1 我很赞同!
菜鸟每天飞过 + 1 + 1 我很赞同!
VincentYsc + 1 + 1 我很赞同!
Janem + 1 + 1 我很赞同!
没有什么舍不得a + 1 + 1 http包代码生成器下载链接:https://www.lanzous.com/i8eqdwd
5ixk + 1 + 1 谢谢@Thanks!
cdb + 1 + 1 谢谢@Thanks!
千幻不爱 + 1 + 1 谢谢分享 希望10月份挂机会计时间用得上
willJ + 1 + 6 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
2060015666 + 1 谢谢@Thanks!
凌乱的暖风 + 1 + 1 热心回复!
daniel7785 + 1 用心讨论,共获提升!
lvyiwuhen + 1 + 1 热心回复!
庞晓晓 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
1216034714 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 2#
 楼主| laodan 发表于 2020-1-3 17:04 <
xisa 发表于 2020-1-1 15:38
楼主用的这个http包代码生成器是浏览器自带的么?不过看着好像没什么特殊功能,应该用其它类似软件也能代替 ...

这个代码生成器以前是VB贴吧的人一个作品,我一般习惯用这个软件,还是挺舒服的,可以直接生成VB代码。其它只要是可以进行请求的软件都是可以的。比如POSTMAN,或者精易论坛的调试助手。
推荐
xisa 发表于 2020-1-1 15:38
楼主用的这个http包代码生成器是浏览器自带的么?不过看着好像没什么特殊功能,应该用其它类似软件也能代替
5#
我与你的时光 发表于 2020-1-1 15:30
6#
黯水悠然 发表于 2020-1-1 15:50
谢谢楼主学到了。
7#
HenryXL 发表于 2020-1-1 15:51
楼主可以帮我的网课平台也弄一下学习时长的软件吗
8#
hs_f 发表于 2020-1-1 16:05
好经验,神武。
9#
hs_f 发表于 2020-1-1 16:14
刷刷效率高
10#
lntuer 发表于 2020-1-1 16:17
HenryXL 发表于 2020-1-1 15:51
楼主可以帮我的网课平台也弄一下学习时长的软件吗

私信账号密码帮你看一下
11#
 楼主| laodan 发表于 2020-1-1 16:43 <
[quote][url=forum.php?mod=redirect

这个平台吗?如果不是的话无能为力了。
12#
HenryXL 发表于 2020-1-1 16:47
laodan 发表于 2020-1-1 16:43
[quote][url=forum.php?mod=redirect

这个平台吗?如果不是的话无能为力了。

不是这个
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2020-4-5 18:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表