吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4041|回复: 21
收起左侧

[Web逆向] MOOC认证 Authing网关检测认证分析-微信扫码

  [复制链接]
情绪666 发表于 2022-11-21 23:33
本帖最后由 情绪666 于 2022-11-21 23:54 编辑

一、前言
  • 之前mooc出现过网关拦截,需要使用微信扫码才能进入
  • 从而导致很多刷课程序无法正常使用
  • 于是分析得出,扫码后会返回一个Cookie名为 GATEWAY_TOKEN 携带此Cookie可以调用mooc的api 参考帖子>>>
  • 由于需要通过浏览器拿到Cookie,于是进行分析直接使用代码获取( 但依旧需要扫码 )



  • 编程语言使用 Python
  • 分析过程仅供学习,请勿用以非法用途
  • 思路过程都是通过浏览器的行为来获取的,以学习为主
  • 代码写了好几个月了,帖子才发,可以会遗忘一些
  • 代码中部分逻辑可能比较旧,部分代码也可以改进,由于能正常用,所以没有再去检查

二、分析


进入官网如果需要认证会自动重定向到认证页面



由于目前未启用认证,于是手动进入网关认证页面


里面有些固定的常量,关于mooc的id,都是固定的,也就是开放平台id,做过第三方平台接入的就知道,也就是mooc在别的平台的唯一id,都是在调用api的时候用的,能够知道是谁在调用哪些功能,并分配权限,了解即可


62cxxxxxxxxxxxxxxxxxbc 认证服务商给mooc的id,是唯一的,有用
62cxxxxxxxxxxxxxxxxxxx80 认证服务商给mooc的另一个id,有用,但也不必研究
wxfxxxxxxxxxxxxxxx81 mooc在微信的id,用来拿二维码的,有这个id微信才知道是谁来拿的



》》》》1、获取二维码《《《《


首先观察页面,仅有二维码是有效信息,于是按照思路应该先找到二维码的生成方式

微信截图_20221121232918.png





继续分析,发现有一个配置的api,以及不知道有什么用的三个api,通过图标可以看出应该有点用



微信截图_20221118141006.png






分析第一个请求右键,复制这些信息,然后粘贴到Postman或其他api请求软件



微信截图_20221118141506.png


扩展:Postman -->左上角三个横线-->File-->Import-->选择(Raw Text)找不到的可以百度"Postman如何导入浏览器请求"




三个请求同时放上去请求,发现页面是一样的,于是使用 https://open.weixin.qq.com/connect/qrconnect 原因就是这个请求来源于微信官方api,比较可靠
微信截图_20221118204703.png





说明:请求的参数 appid state 是有用的,appid应该是mooc申请的id,不会变,state多次观察浏览器的接口会发现是会变的,就是一个随机的UUID,后面会通过这个id拿到结果

然后通过xpath解析,拿到二维码链接,链接就在返回的html里面,这里我拿的是<img class="web_qrcode_img" src="/connect/qrcode/qwerxxxx"/>内容,看代码区 get_qrconnect_image 方法,记住 qwerxxxx 这个值下面会说





有了二维码,可以使用手机扫码,接下来就是获取返回值了,看代码区的 get_qrconnect_result 方法,拿返回结果的方式,可以直接观察浏览器做了什么,这里可以看出,浏览器在用一个uuid主动查询结果(前打开控制台,一般多等一会有结果,观察请求最明显,或者观察浏览器的websocket有没有什么状态),这个api的uuid其实是上面提到的 qwerxxxx 返回结果是:window.wx_errcode=408;window.wx_code='abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 扫码成功后结果会在wx_code(32位字符)里面,取出先保留起来,后面要用
微信截图_20221118225708.png




》》》》2、网关登录认证《《《《



接下来是网关部分

   1. 由于浏览器的一些问题,下面借助抓包工具 Charles 来查看数据
   2. 思路主要跟着浏览器进行,通过上面的步骤,我们现在有了:随机生成的UUID window.wx_code='abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 的扫码结果

观察浏览器请求,其中,code是微信扫码的结果 例如: abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,state是我们自己生成的uuid。为什么会知道:每当看到一个不知道哪里生成的值,都应该通过上面的请求依次查看,这些值一般会和上面有联系,或者直接看代码

微信截图_20221119224128.png

由于浏览器的问题,我们借助借助抓包工具 Charles 来查看数据

微信截图_20221119234223.png


之后,一边和浏览器走一边写代码,比较直观看结果,并且出现不一样的返回结果就要多留意

于是往下走,我们现在应该写回调的代码了,然后打印文本,就出现了 登录过程中点击返回/刷新/多次点击登录,导致无法登录成功,请关闭本页面之后重新登录 这个提示,无法进行下一步,但是明明是和浏览器的请求一致,为什么返回结果不一致,(这个地方会有个坑,可以看代码区 get_hep_callback 方法,调用了两个url,但是页面上我们只看到了一个有 /callback?code=xxx 的url,另一个 /social/hep-wx 是什么?先说下原因,其实可以避免,由于我懒,没有完全按照浏览器的请求调用),于是再次去扫码,再去重复流程,来观察




原因,就是前面看到的三个请求,我们用的是第三个直接拿到二维码,于是忽略掉了前两个,他们的流程是:第一个请求-->重定向-->第二个请求-->重定向-->第三个请求拿到二维码,主要在第二个请求,看图片,第二个请求会有个Set-Cookie 的操作,就是这个地方,前面出现的错误就是缺少这个cookie,于是我们直接调用第一个请求(参数和浏览器看到的一样就可以,没有随机的id,都是固定参数),过一遍浏览器的流程就可以,注意:这里requests的重定向功能是默认打开的所以直接运行会自动重定向,可以直接跑下去,让请求去帮我们set一个cookie就可以了


微信截图_20221119235543.png


所以,再回顾到代码那,就能够理解了,于是就顺利拿到了和抓包软件表单的内容了,xpath解析出 interactionKey debug_conn_id,用作同时也去提交表单,也就是把参数放到那个地址去请求,由于还要去看代码太麻烦,于是看浏览器,浏览器肯定会记录请求发送的流程,直接参考,找到和表单一样地址(/relayLoginState)的请求查看


微信截图_20221120001847.png


观察这个请求,也是一个302重定向,重定向到下面的地址,里面有Set-Cookie,所以我们继续跑这个请求就可以,对应代码区 get_hep_relay_login_state 方法,于是就顺利拿到了cookie,


期间碰到了很多问题,大多数是重定向以及一些必要的cookie没有set过来
总的来讲并不复杂,但是真正从0开始,还是有些困难
# 以上仅代表个人分析,分享,以及一些问题的查找思路,如有理解不得当,恳请批评指正
总结:遇到问题及时回顾,与浏览器运行流程一致,善用工具,善观察

三、运行截图

微信截图_20221120003306.png


四、代码

[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# -*- coding: utf-8 -*-
# [url=home.php?mod=space&uid=238618]@Time[/url] : 2022/7/28
# [url=home.php?mod=space&uid=686208]@AuThor[/url] : Melon
# [url=home.php?mod=space&uid=406162]@site[/url] :
# [url=home.php?mod=space&uid=786562]@note[/url] :
# [url=home.php?mod=space&uid=267492]@file[/url] : MoocGateWay.py
# @Software: PyCharm
import re
import time
import uuid
from io import BytesIO
 
import requests
from lxml import etree
 
MOOC_HEP_APPID = '62xxxxxxxxxxxxxxxxxxx'
MOOC_HEP_USER_POOLID = '62cxxxxxxxxxxxxxxxxxx'
MOOC_WX_APPID = 'wxxxxxxxxxxxxxxxxxxxx'
 
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
}
 
 
def get_qrconnect_image(session, uuid_val):
    url = "https://open.weixin.qq.com/connect/qrconnect"
    payload = {
        'appid': MOOC_WX_APPID,
        'redirect_uri': f'https://core.u2.hep.com.cn/connection/social/hep-wx/{MOOC_HEP_APPID}/callback',
        'response_type': 'code',
        'scope': 'snsapi_login',
        'state': uuid_val,
    }
    get = session.get(url=url, params=payload, headers=headers)
    etree_html = etree.HTML(get.content)
    return 'https://open.weixin.qq.com' + etree_html.xpath("//div[@id='wx_default_tip']/img[@class='web_qrcode_img']/@src")[0]
 
 
def open_image(session, image_url):
    try:
        from PIL import Image
        requests_get = session.get(url=image_url, headers=headers)
        Image.open(BytesIO(requests_get.content)).show()
    except Exception as e:
        logger.info(e)
        logger.info('打开微信二维码失败,请重新运行!!!')
 
 
def get_qrconnect_result(session, qrcode_image_code):
    url = "https://lp.open.weixin.qq.com/connect/l/qrconnect"
    payload = {
        'uuid': qrcode_image_code,
        '_': time.time(),
    }
    get = session.get(url=url, params=payload, headers=headers)
    return get.text
 
 
def get_hep_callback(session, qrconnect_result_code, uuid_val):
    url = "https://icve-gateway-web.u2.hep.com.cn/connections/social/hep-wx"
    payload = {
        'app_id': MOOC_HEP_APPID,
        'redirect_url': 'https://wangguan.icve.com.cn/sso/login2/?state=http://mooc.icve.com.cn/',
    }
    session.get(url=url, params=payload, headers=headers)  # 必须调用 同一个会话中会自动处理
    url = f"https://core.u2.hep.com.cn/connection/social/hep-wx/{MOOC_HEP_USER_POOLID}/callback"
    payload = {
        'code': qrconnect_result_code,
        'state': uuid_val,
    }
    get = session.get(url=url, params=payload, headers=headers)
    etree_html = etree.HTML(get.content)
 
    return {
        'interactionKey': etree_html.xpath("//input[@name='interactionKey']/@value")[0],
        'debug_conn_id': etree_html.xpath("//input[@name='debug_conn_id']/@value")[0],
    }
 
 
def get_hep_relay_login_state(session, payload):
    url = "https://icve-gateway-web.u2.hep.com.cn/interaction/federation/relayLoginState"
    login = session.post(url=url, data=payload, headers=headers)
    # 内部 header Location 里面就有登录的链接,进入之后返回ck
    return login.cookies
 
 
def mooc_gateway_auth(session):
    logger.info("\n\n===== 【正在进行 mooc 网关认证,请在弹出二维码 15s 内进行微信扫码,逾期请重新运行!】===== ")
    uuid_uuid = uuid.uuid1()
    # 获取二维码链接
    qrconnect_image_url = get_qrconnect_image(session=session, uuid_val=uuid_uuid)
    print('二维码链接获取成功: ', qrconnect_image_url)
    # 打开二维码进行扫码
    open_image(session=session, image_url=qrconnect_image_url)
    # 获取二维码唯一code
    image_url_code = qrconnect_image_url.replace('https://open.weixin.qq.com/connect/qrcode/', '')
    print('二维码 code 截取成功: ', image_url_code)
    # 获取扫码结果
    qrconnect_result_code = None
    while not qrconnect_result_code:
        print('监听扫码结果中......')
        get_qrconnect_result_val = get_qrconnect_result(session=session, qrcode_image_code=image_url_code)
        re_findall = re.findall(r"(?<=window.wx_code=').*(?=';)", get_qrconnect_result_val)
        if re_findall:
            qrconnect_result_code = re_findall[0]
    print('扫码结果为: ', qrconnect_result_code)
    # 获取生成 GATEWAY_TOKEN 的主要参数
    payload = get_hep_callback(session=session, qrconnect_result_code=qrconnect_result_code, uuid_val=uuid_uuid)
    print('回调返回值 payload: ', payload)
    # 获取到之后 用参数进行模拟登录 获取 GATEWAY_TOKEN
    get_hep_relay_login_state(session=session, payload=payload)
    print('COOKIES: ', session.cookies)
    return len([key for key in session.cookies.keys() if 'GATEWAY_TOKEN' in key]) > 0
 
 
if __name__ == '__main__':
    mooc_gateway_auth(requests.session())
 
#


免费评分

参与人数 8威望 +1 吾爱币 +27 热心值 +8 收起 理由
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ba11ab + 1 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
word11 + 1 + 1 谢谢@Thanks!
txljb + 1 + 1 我很赞同!
Ll001 + 1 + 1 我很赞同!
an9el + 1 + 1 我很赞同!
gddw + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

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

jiang1122 发表于 2022-11-21 23:58
感谢分享p
fangshouyiboba 发表于 2022-11-22 00:35
hk9186 发表于 2022-11-22 00:46
ChenXin996 发表于 2022-11-22 01:53
实用,感谢楼主
xxwo4me 发表于 2022-11-22 05:05
好贴顶一个!支持!!!!
FYL11162022 发表于 2022-11-22 06:53
先收藏,后面照猫画虎学学
xixicoco 发表于 2022-11-22 07:08
吆西,不错的文章
CuteCabbage 发表于 2022-11-22 08:12
不错,支持一个
ipaint 发表于 2022-11-22 09:11
谢谢分享。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-3-26 14:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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