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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9848|回复: 132
收起左侧

[Web逆向] 抓包某PMP培训机构APP并下载所有PMP课程

    [复制链接]
mr.z.j 发表于 2022-5-31 13:50
本帖最后由 mr.z.j 于 2022-5-31 16:59 编辑

前言

3年前报考了PMP,疫情原因推迟两年没考,近期通知6.25要考试了,临时抱佛脚赶快刷视频。

前年的时候也抓包把所有课程打包下了一次,但是现在PMP改版,之前的视频已经过时了,在线看的又不方便,所以又重新抓包下载,这次把过程和代码记录下来。

【备注】

PMP的考试是必须通过这种培训机构才可以报名考试的,即便你看了视频,想要考试,还是得先找机构报名,才能考试。


另外,抓包下载课程的前提条件还是必须得先买了课程才可以看到内容。


把下载的视频分享出来主要是出于大家一起学习项目管理。


使用到的工具:

【雷电3.0】【某环APP】【Charles抓包】

开发语言:

Java

步骤

1、安装Charles,开启代{过}{滤}理,设置https证书

这一步论坛或者百度一下很多教程,比如:搜索 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn ,这里就不细讲了。

1.png


Charles 4.2.7 - Sess_2022-05-31_16-37-46.png



2、安装雷电3.0模拟器

使用3.0的主要原因是抓包需要安装并信任https证书,安卓高版本好像没办法,所以用的是雷电3.0。

安装好之后设置网络桥接,安装驱动;

Snipper - Snipaste_2022-05-31_13-27-18.png

打开雷电之后,进入wlan设置,长按,修改网络,进入高级选项,打开代{过}{滤}理,设置为Charles代{过}{滤}理的IP+端口

雷电模拟器_2022-05-31_13-27-50.png

2225.png


3、安装某环APP,进入我的学习开始抓包

这里要吐槽一下APP的开发了,获取用户信息的接口没有任何登录鉴权,随便传个userid就可以获取该用户的邮箱 手机信息,借此其实可以轮询到所有的用户隐私信息。

Charles 4.2.7 - Sess_2022-05-31_16-37-25.png

言归正传,说下怎么获取所有的课程

这里通过点击APP,发现需要通过4个步骤

[Java] 纯文本查看 复制代码

static String url1 = "https://app.xxxx.com/Lesson/myLessons";// 1、获取班级地址
static String url2 = "https://app.xxxx.com/User/myLesson";// 2、获取课程地址
static String url3 = "https://app.xxxx.com/Lesson/detail";// 3、获取课程列表
static String url4 = "https://app.xxxx.com/Lesson/play";// 3、获取课程文件



每次请求传入的参数基本就是上一个接口返回的id,

所以代码逻辑就是

1、获取用户获取到该用户的班级列表

2、根据班级获取到班级内的课程

3、获取课程内的在线课程

4、根据在线课程获取课程的视频文件或者课程作业

5、多线程下载文件

下面是具体代码,时间有限,也没有做什么规范和优化,凑合看下吧

[Java] 纯文本查看 复制代码

public class Test {

        static String filePath = "E:\\下载\\PMP"; //保存路径
        static String userid = "xxxx";//抓包从请求头获取
        static String url1 = "https://app.xxxx.com/Lesson/myLessons";// 1、获取班级地址
        static String url2 = "https://app.xxxx.com/User/myLesson";// 2、获取课程地址
        static String url3 = "https://app.xxxx.com/Lesson/detail";// 3、获取课程列表
        static String url4 = "https://app.xxxx.com/Lesson/play";// 3、获取课程文件
        static Map<String, String> headMap = new HashMap<String, String>();

        public static void main(String[] args) throws Exception {

                List<String[]> tempmap = new ArrayList();

                filePath += new Random(10000).nextLong() + "\\";

                headMap.put("secket", "xxxxx");//抓包从请求头获取
                headMap.put("apid", "yun.aura.cn");
                headMap.put("Content-Type", "application/json;charset=UTF-8");
                System.out.println("获取班级列表");
                String result = SdkClient.post(url1 + "?p=1&uid=" + userid, "", headMap);
                System.out.println(result);
                if (result != null && !"".equals(result) && result.contains("userInfo")) {
                        JSONObject myLessonsresult = JSON.parseObject(result);
                        JSONArray data = myLessonsresult.getJSONArray("data");
                        for (int i = 0; i < data.size(); i++) {
                                JSONObject o = data.getJSONObject(i);
                                String LessonID = o.getString("lesson_id");
                                String LessonName = o.getString("name");
                                String current_filePath1 = filePath + LessonName + "\\";
                                System.out.println("创建班级目录:" + current_filePath1);

                                new File(current_filePath1).mkdirs();

                                System.out.println("获取班级课程,id=" + LessonID);
                                result = SdkClient.post(url2 + "?lid=" + LessonID + "&uid=" + userid, "", headMap);
                                System.out.println(result);
                                if (result != null && !"".equals(result) && result.contains("success")) {
                                        JSONObject myLessonsresult2 = JSON.parseObject(result);
                                        JSONArray data2 = myLessonsresult2.getJSONObject("data").getJSONArray("data");
                                        for (int i2 = 0; i2 < data2.size(); i2++) {
                                                JSONObject o2 = data2.getJSONObject(i2);
                                                String LessonID2 = o2.getString("lid");
                                                String LessonName2 = o2.getString("name");

                                                String current_filePath2 = current_filePath1 + (i2 < 9 ? ("0" + (i2 + 1)) : (i2 + 1)) + " "
                                                                + LessonName2 + "\\";

                                                System.out.println("创建课程目录:" + current_filePath2);
                                                new File(current_filePath2).mkdirs();

                                                System.out.println("获取课程文件列表,lid=" + LessonID2);

                                                result = SdkClient.post(
                                                                url3 + "?pkid=" + LessonID + "&id=" + LessonID2 + "&teach_type=2" + "&uid=" + userid,
                                                                "", headMap);
                                                System.out.println(result);
                                                if (result != null && !"".equals(result) && result.contains("Hello world")) {
                                                        JSONObject myLessonsresult3 = JSON.parseObject(result);
                                                        JSONArray catalogues = myLessonsresult3.getJSONArray("catalogue");
                                                        for (int i3 = 0; i3 < catalogues.size(); i3++) {
                                                                JSONObject catalogue = catalogues.getJSONObject(i3);
                                                                String catalogueName = catalogue.getString("name");

                                                                String current_filePath3 = current_filePath2 + (i3 < 9 ? ("0" + (i3 + 1)) : (i3 + 1))
                                                                                + " " + catalogueName + "\\";

                                                                System.out.println("创建课程文件目录:" + current_filePath3);
                                                                new File(current_filePath3).mkdirs();

                                                                JSONArray catalogues_childrens = catalogue.getJSONArray("children");

                                                                for (int i4 = 0; i4 < catalogues_childrens.size(); i4++) {
                                                                        JSONObject catalogues_children = catalogues_childrens.getJSONObject(i4);
                                                                        String catalogues_childrenName = catalogues_children.getString("name");

                                                                        String current_filePath4 = current_filePath3 + " "
                                                                                        + (i4 < 9 ? ("0" + (i4 + 1)) : (i4 + 1)) + catalogues_childrenName + "\\";
                                                                        System.out.println("创建课程文件二级目录:" + current_filePath4);
                                                                        new File(current_filePath4).mkdirs();

                                                                        JSONArray catalogues_childrens_too = catalogues_children.getJSONArray("children");

                                                                        for (int i5 = 0; i5 < catalogues_childrens_too.size(); i5++) {
                                                                                JSONObject kecheng = catalogues_childrens_too.getJSONObject(i5);

                                                                                String sort = kecheng.getString("sort");
                                                                                String playurl = url4 + "?pkid=" + LessonID + "&id=" + LessonID2 + "&sid="
                                                                                                + sort + "&teach_type=2" + "&uid=" + userid;
                                                                                result = SdkClient.post(playurl, "", headMap);
                                                                                if (result != null && !"".equals(result) && result.contains("Hello world")) {
                                                                                        JSONObject fileinfo = JSON.parseObject(result);
                                                                                        fileinfo = fileinfo.getJSONObject("data");
                                                                                        String fileinfoName = fileinfo.getString("kj_name");
                                                                                        String fileinfoUrl = fileinfo.getString("aliInfo");
                                                                                        System.out.println("创建课程文件:" + current_filePath4 + fileinfoName);
                                                                                        System.out.println(fileinfoUrl);
                                                                                        File urltxt = new File(current_filePath4 + "url.txt");
                                                                                        urltxt.createNewFile();
                                                                                        FileUtil.appendString(urltxt, fileinfoUrl);
                                                                                        tempmap.add(new String[] { fileinfoUrl, current_filePath4 + fileinfoName });
                                                                                }
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }

                                System.out.println("开启多线程下载");
                                ExecutorService threadPool = Executors.newCachedThreadPool();
                                int threadCount = 5;
                                int threadTaskCount = tempmap.size() / 5;
                                System.out.println(
                                                "共开启" + threadCount + "条线程,预计下载文件" + tempmap.size() + "个,每条线程下载" + threadTaskCount + "个文件");
                                CountDownLatch latch = new CountDownLatch(threadCount);

                                List<String[]> urls = new ArrayList();
                                for (int iii = 0; iii < tempmap.size(); iii++) {
                                        String[] url = tempmap.get(iii);
                                        urls.add(url);
                                        if (iii % threadTaskCount == 0 || iii == tempmap.size() - 1) {
                                                QueryTask task = new QueryTask(urls, latch);
                                                threadPool.execute(task);
                                                urls = new ArrayList();
                                        }
                                }
                                // 等待线程池中的线程全部执行完毕
                                latch.await();
                                // 关闭线程池
                                threadPool.shutdown();

                        }
                }

        }
}

class QueryTask implements Runnable {

        private List<String[]> urls;
        private CountDownLatch latc;

        public QueryTask() {
                super();
        }

        public QueryTask(List<String[]> urls, CountDownLatch latc) {
                super();
                this.urls = urls;
                this.latc = latc;
        }

        // 下载链接 下载到的目录 下载后的文件名称
        public static boolean download(String urlPath, String fileName) throws Exception {
                // 解决url中可能有中文情况
                URL url = new URL(urlPath);
                HttpURLConnection http = (HttpURLConnection) url.openConnection();
                http.setConnectTimeout(3000);
                // 设置 User-Agent 避免被拦截
                http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
                // 获取文件名
                InputStream inputStream = http.getInputStream();
                byte[] buff = new byte[1024 * 10];
                File file = new File(fileName);
                if (!file.exists()) {
                        OutputStream out = new FileOutputStream(file);
                        int len;
                        int count = 0; // 计数
                        while ((len = inputStream.read(buff)) != -1) {
                                out.write(buff, 0, len);
                                out.flush();
                                ++count;
                        }
                        // 关闭资源
                        out.close();
                        inputStream.close();
                        http.disconnect();
                        return true;
                }
                return false;
        }

        @Override
        public void run() {
                try {
                        for (String[] u : urls) {
                                download(u[0], u[1]);
                        }
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        // 每结束一个线程,就要总数减一
                        latc.countDown();
                }

        }

}



最后所有的文件也会按照目录生成

snipaste_20220531_134728.png

最终结果我上传到网盘了,见附件。


pmp2022网盘.zip

299 Bytes, 阅读权限: 10, 下载次数: 1000, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 26吾爱币 +30 热心值 +22 收起 理由
wisd0m7 + 1 谢谢@Thanks!
bookbug + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Marr + 1 + 1 我很赞同!
andone1983 + 1 + 1 感谢分享了,看看再说
paguco + 1 + 1 热心回复!
halo_o + 1 + 1 谢谢@Thanks!
tb19901109 + 1 + 1 谢谢@Thanks!
打酱油路过的 + 1 用心讨论,共获提升!
我有我职责 + 1 + 1 感谢你的分享。
逸只猫 + 1 + 1 谢谢@Thanks!
starh + 1 谢谢@Thanks!
gracelige + 1 谢谢@Thanks!
AMZ12138 + 1 + 1 用心讨论,共获提升!
yuanjindong + 1 谢谢@Thanks!
gyd1 + 1 + 1 谢谢@Thanks!
rain_low + 1 + 1 您好能私信发一下 *环国际app吗?
XJ666 + 1 + 1 用心讨论,共获提升!
cu2oh2co38 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
slaizp + 1 + 1 用心讨论,共获提升!
涛之雨 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
mokjf + 1 + 1 今天的分一定给你,这是新版的课程还是旧版的课程
Huangyc + 1 + 1 我很赞同!
lingyun011 + 1 + 1 热心回复!
勿懂 + 1 + 1 我很赞同!
依旧沉沉 + 1 我也报考了,敢不敢把视频共享出来~{:1_918:}
Syer + 2 + 1 谢谢@Thanks!

查看全部评分

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

linswin 发表于 2022-12-2 08:45
qliu00 发表于 2022-12-1 13:44
那你能帮忙爬一个希赛PMP视频不?
https://wangxiao.xisaiwang.com/zhibo2/v280007502.html

请注意:抓包下载课程的前提条件还是必须得先买了课程才可以看到内容。

如果购买了账号,可以私发给我,我帮你看看能不能逆向爬取。

点评

链接:https://pan.baidu.com/s/1vmHdfOQkFq0hn923FFqARg?pwd=xohh 提取码:xohh  发表于 2023-12-25 09:49
fenghz 发表于 2022-6-1 17:13
狼孩yannis 发表于 2022-6-1 15:23
PMP的考试是必须通过这种培训机构才可以报名考试的,即便你看了视频,想要考试,还是得先找机构报名,才能 ...

也有那种自学代报名的,就花个一两百而已
Syer 发表于 2022-6-1 13:11
AlvinWang76 发表于 2022-6-1 13:17
感谢楼主分享  正需要   7月要考试了 用的上
依旧沉沉 发表于 2022-6-1 13:18
我也报考了,敢不敢把视频共享出来~
 楼主| mr.z.j 发表于 2022-6-1 13:31
依旧沉沉 发表于 2022-6-1 13:18
我也报考了,敢不敢把视频共享出来~

网盘地址附件呢。
AlvinWang76 发表于 2022-6-1 13:43
楼主要是能资源放到阿里网盘就好了    度盘速度太慢了
 楼主| mr.z.j 发表于 2022-6-1 14:02
AlvinWang76 发表于 2022-6-1 13:43
楼主要是能资源放到阿里网盘就好了    度盘速度太慢了

俺买了百度会员的。。。
jobs_steven 发表于 2022-6-1 14:09
这个可以。。。学习了。。。。。
penzoe 发表于 2022-6-1 14:13
这个可以。。。学习了。。。。。
微笑嘻嘻 发表于 2022-6-1 14:15
谢谢楼主
学到了技术也学到了PMP
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-5-2 22:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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