[ 生活需要仪式感 ]

0%

不需要用手机的企业微信扫码登陆

TL; DR

通过油猴,在检测到浏览扫码页时,推送消息到企业微信机器人中,在企业微信桌面端的内置浏览器打开,进行登陆确认。


1 前言

公司登陆,在安全升级后,开启了双因子认证登陆(2FA),要么是 PIN+TOKEN,要么是 密码+手机验证码,又或者是 企业微信扫码

2FA 是指用户必须提供两种不同类型的身份验证信息才能进行身份验证。这些身份验证因素可能包括:

  • 你知道的东西(例如,密码或PIN)。
  • 你拥有的东西(例如,智能卡、USB令牌或手机)。
  • 你是谁(例如,指纹或其他生物特征)。

虽然安全性有所上升,但是对于便捷性来说是极大的倒退。

实际上,扫码登陆只是单一的 OTP 要素,不符合 2FA 逻辑,但是可能因为是在 你拥有的东西(手机) 上,所以也可能符合 2FA 逻辑?

不过,总的来说,现在需要进行 扫码登陆,或者是 PIN+TOKEN, 1Password 也没有办法拿到 OTP 密钥,也就没有办法自动登陆了,要解决这个问题。

2 解决方案

2.1 思路与想法

经过长期摸索和研究,有以下几个突破发现:

发现一

研究发现,接入方为了能够方便引入企业微信扫码登陆功能,大部分会直接使用 iframe 嵌套企业微信的扫码页面,即 open.work.weixin.qq.com/wwopen/sso/qrImg?key=xxxxx 这个地址

发现二

只要在企业微信客户端的 内置浏览器 中打开这个 SSO 登陆地址,就能够有 登陆 按钮进行登陆,完成验证。核心就是地址上带了 OTP 也就是 key,只要在授权的客户端里打开同一个页面,确认了这个 key 就是完成验证。

发现三

企业微信客户端内的地址,不是所有地址都能在 内置浏览器 中打开,必须是在应用内打开地址,才能够在内置浏览器中浏览。

方案四

群聊机器人,也能作为应用,在其推送的消息内链接触发 内置浏览器 浏览。

2.2 解决方案

有了以上几个发现后,就很容易能够串起一个自动化流程了。

【登陆过期跳转登陆页】-【检测到加载了企微SSO页面】-【触发油猴POST到企微机器人】-【企微打开地址完成验证】

2.3 申请企微群机器人

右键群聊 - 管理聊天信息 - 添加群机器人,

添加后,会或者一个 Webhook 地址,形如:

https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=41eo-xxx

2.3 油猴脚本

安装 TemperMonkey,新建一个脚本,导入下方脚本,并启用。

这个脚本的功能,如底下注释般简单,只干 4 个事情:

  • 判断当前是否有浏览企业微信的 SSO 登陆页面(@match地址),有就触发脚本
  • 捞取登陆页面里面,企微本次登陆验证key(OTP)
  • 拼接验证页面URL + key
  • 推送给群机器人

有几个注意点:

  • 脚本因为需要 POST 请求给群机器人,需要授权一个 GM_xmlhttpRequest 权限
  • 群机器人,任何人拿到地址,就能往里面发垃圾消息,所以要适时重置,并保护好自己的 WebHook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// ==UserScript==
// @name WeCom QRCode Poster
// @namespace https://0ne.store/
// @version 0.2
// @description Post QR code src to a specific robot URL
// @author Copriwolf
// @match https://open.work.weixin.qq.com/wwopen/sso/qrConnect*
// @grant GM_xmlhttpRequest
// ==/UserScript==

(function() {
'use strict';

var params = new URLSearchParams(window.location.search);
var redirect_uri = params.get("redirect_uri");

// Specify the target Robot URL
// 把群机器人的WebHook地址拷贝在这
var webHookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=41eo-xxxxxxxxxxxxxxxxx";

// Find the img element with class "qrcode lightBorder"
var imgElement = document.querySelector('img.qrcode');

// If the img element is found
if (imgElement) {
// Get the src attribute of the img element
var imgSrc = 'https:' + imgElement.getAttribute('src');

// Parse the URL and the query string
var parsedUrl = new URL(imgSrc);
var key = parsedUrl.searchParams.get("key");

// Construct the new URL
var confirmUrl = "https://open.work.weixin.qq.com/wwopen/sso/confirm2?k=" + key;

// Prepare the data to send
var data = {
"msgtype": "markdown",
"markdown": {
"content": `### 📍 企业微信账户登陆\n---\nHi,机器人检索到登陆二维码的链接\n<font color=\"comment\">☑️ [点击跳转](${confirmUrl})</font>\n> <font color=\"comment\">**实际跳转地址**</font>\n><font color=\"comment\">${decodeURIComponent(redirect_uri)}</font> `
}
};

// Send the data as a POST request
GM_xmlhttpRequest({
method: "POST",
url: webHookUrl,
data: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
},
});
}
})();

3 实现效果

只要登陆过期,跳到登陆页,就会在企业微信收到推送,直接点击登陆,无需换手。

同时,因为这个也算是在多端验证(假象),类似 TG 不扫码而是在其他登陆端验证 OTP 异曲同工。