MOOC认证 Authing网关检测认证分析-微信扫码
本帖最后由 情绪666 于 2022-11-21 23:54 编辑https://static.52pojie.cn/static/image/hrline/4.gif 一、前言 https://static.52pojie.cn/static/image/hrline/4.gif
[*]之前mooc出现过网关拦截,需要使用微信扫码才能进入
[*]从而导致很多刷课程序无法正常使用
[*]于是分析得出,扫码后会返回一个Cookie名为 GATEWAY_TOKEN 携带此Cookie可以调用mooc的api 参考帖子>>>
[*]由于需要通过浏览器拿到Cookie,于是进行分析直接使用代码获取( 但依旧需要扫码 )
[*]编程语言使用 Python
[*]分析过程仅供学习,请勿用以非法用途
[*]思路过程都是通过浏览器的行为来获取的,以学习为主
[*]代码写了好几个月了,帖子才发,可以会遗忘一些
[*]代码中部分逻辑可能比较旧,部分代码也可以改进,由于能正常用,所以没有再去检查
https://static.52pojie.cn/static/image/hrline/4.gif 二、分析 https://static.52pojie.cn/static/image/hrline/4.gif
进入官网如果需要认证会自动重定向到认证页面
由于目前未启用认证,于是手动进入网关认证页面
里面有些固定的常量,关于mooc的id,都是固定的,也就是开放平台id,做过第三方平台接入的就知道,也就是mooc在别的平台的唯一id,都是在调用api的时候用的,能够知道是谁在调用哪些功能,并分配权限,了解即可
62cxxxxxxxxxxxxxxxxxbc 认证服务商给mooc的id,是唯一的,有用
62cxxxxxxxxxxxxxxxxxxx80 认证服务商给mooc的另一个id,有用,但也不必研究
wxfxxxxxxxxxxxxxxx81 mooc在微信的id,用来拿二维码的,有这个id微信才知道是谁来拿的
》》》》1、获取二维码《《《《
首先观察页面,仅有二维码是有效信息,于是按照思路应该先找到二维码的生成方式
https://static.52pojie.cn/static/image/hrline/2.gif
继续分析,发现有一个配置的api,以及不知道有什么用的三个api,通过图标可以看出应该有点用
https://static.52pojie.cn/static/image/hrline/2.gif
分析第一个请求,右键,复制这些信息,然后粘贴到Postman或其他api请求软件
扩展:Postman -->左上角三个横线-->File-->Import-->选择(Raw Text)找不到的可以百度"Postman如何导入浏览器请求"
https://static.52pojie.cn/static/image/hrline/2.gif
三个请求同时放上去请求,发现页面是一样的,于是使用 https://open.weixin.qq.com/connect/qrconnect 原因就是这个请求来源于微信官方api,比较可靠
https://static.52pojie.cn/static/image/hrline/2.gif
说明:请求的参数 appid 和 state 是有用的,appid应该是mooc申请的id,不会变,state多次观察浏览器的接口会发现是会变的,就是一个随机的UUID,后面会通过这个id拿到结果
然后通过xpath解析,拿到二维码链接,链接就在返回的html里面,这里我拿的是<img class="web_qrcode_img" src="/connect/qrcode/qwerxxxx"/>内容,看代码区 get_qrconnect_image 方法,记住 qwerxxxx 这个值下面会说
https://static.52pojie.cn/static/image/hrline/2.gif
有了二维码,可以使用手机扫码,接下来就是获取返回值了,看代码区的 get_qrconnect_result 方法,拿返回结果的方式,可以直接观察浏览器做了什么,这里可以看出,浏览器在用一个uuid去主动查询结果(前打开控制台,一般多等一会有结果,观察请求最明显,或者观察浏览器的websocket有没有什么状态),这个api的uuid其实是上面提到的 qwerxxxx 返回结果是:window.wx_errcode=408;window.wx_code='abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 扫码成功后结果会在wx_code(32位字符)里面,取出先保留起来,后面要用
》》》》2、网关登录认证《《《《
接下来是网关部分
1. 由于浏览器的一些问题,下面借助抓包工具 Charles 来查看数据
2. 思路主要跟着浏览器进行,通过上面的步骤,我们现在有了:随机生成的UUID 和 window.wx_code='abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 的扫码结果
观察浏览器请求,其中,code是微信扫码的结果 例如: abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,state是我们自己生成的uuid。为什么会知道:每当看到一个不知道哪里生成的值,都应该通过上面的请求依次查看,这些值一般会和上面有联系,或者直接看代码
由于浏览器的问题,我们借助借助抓包工具 Charles 来查看数据
之后,一边和浏览器走一边写代码,比较直观看结果,并且出现不一样的返回结果就要多留意
于是往下走,我们现在应该写回调的代码了,然后打印文本,就出现了 登录过程中点击返回/刷新/多次点击登录,导致无法登录成功,请关闭本页面之后重新登录 这个提示,无法进行下一步,但是明明是和浏览器的请求一致,为什么返回结果不一致,(这个地方会有个坑,可以看代码区 get_hep_callback 方法,调用了两个url,但是页面上我们只看到了一个有 /callback?code=xxx 的url,另一个 /social/hep-wx 是什么?先说下原因,其实可以避免,由于我懒,没有完全按照浏览器的请求调用),于是再次去扫码,再去重复流程,来观察
原因,就是前面看到的三个请求,我们用的是第三个直接拿到二维码,于是忽略掉了前两个,他们的流程是:第一个请求-->重定向-->第二个请求-->重定向-->第三个请求拿到二维码,主要在第二个请求,看图片,第二个请求会有个Set-Cookie 的操作,就是这个地方,前面出现的错误就是缺少这个cookie,于是我们直接调用第一个请求(参数和浏览器看到的一样就可以,没有随机的id,都是固定参数),过一遍浏览器的流程就可以,注意:这里requests的重定向功能是默认打开的所以直接运行会自动重定向,可以直接跑下去,让请求去帮我们set一个cookie就可以了
所以,再回顾到代码那,就能够理解了,于是就顺利拿到了和抓包软件中表单的内容了,xpath解析出 interactionKey 和 debug_conn_id,用作同时也去提交表单,也就是把参数放到那个地址去请求,由于还要去看代码太麻烦,于是看浏览器,浏览器肯定会记录请求发送的流程,直接参考,找到和表单一样地址(/relayLoginState)的请求查看
观察这个请求,也是一个302重定向,重定向到下面的地址,里面有Set-Cookie,所以我们继续跑这个请求就可以,对应代码区 get_hep_relay_login_state 方法,于是就顺利拿到了cookie,
期间碰到了很多问题,大多数是重定向以及一些必要的cookie没有set过来总的来讲并不复杂,但是真正从0开始,还是有些困难# 以上仅代表个人分析,分享,以及一些问题的查找思路,如有理解不得当,恳请批评指正总结:遇到问题及时回顾,与浏览器运行流程一致,善用工具,善观察
https://static.52pojie.cn/static/image/hrline/4.gif 三、运行截图 https://static.52pojie.cn/static/image/hrline/4.gif
https://static.52pojie.cn/static/image/hrline/4.gif 四、代码 https://static.52pojie.cn/static/image/hrline/4.gif
# -*- coding: utf-8 -*-
# @Time : 2022/7/28
# @AuThor : Melon
# @site :
# @note :
# @file : 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")
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"),
'debug_conn_id': etree_html.xpath("//input[@name='debug_conn_id']/@value"),
}
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
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() > 0
if __name__ == '__main__':
mooc_gateway_auth(requests.session())
#
感谢分享p{:1_919:} 感谢分享 好文,可惜不读书了,支持一下 实用,感谢楼主 好贴顶一个!支持!!!! 先收藏,后面照猫画虎学学 吆西,不错的文章 不错,支持一个 谢谢分享。