首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

通过复制到虚拟机错误报告反向通道在 QubesOS 中执行任意代码

摘要

We have published Qubes Security Bulletin (QSB) 118: Dom0 arbitrary code execution in qvm-copy-to-vm error reporting . The text of this QSB and its accompanying cryptographic signatures are reproduced...

the error copy dom0 qube qvm The and file Qubes
2026-08-30 1 阅读 约9分钟阅读 vntok
分享:
字号:
我们发布了 Qubes 安全公告 (QSB) 118:Dom0 在 qvm-copy-to-vm 错误报告中任意执行代码。本 QSB 的文本及其随附的加密签名转载如下,随后是本公告的一般解释和认证说明。 Qubes 安全公告 118 ---===[ Qubes 安全公告 118 ]===--- 2026-08-28 Dom0 在 qvm-copy-to-vm 错误报告中执行任意代码 用户操作 ------------ 继续正常更新 [1],以便接收下面“修补”部分中描述的安全更新。用户无需执行任何其他操作来响应此 QSB。摘要 -------- 如果使用 qvm-copy-to-vm 将文件从 dom0 复制到恶意 qube,则该 qube 可以将任意命令注入 dom0。影响 ------- 如果攻击者攻陷了 qube,并且用户从 dom0 向受攻陷的 qube 发起 `qvm-copy-to-vm` 调用,则攻击者可以利用此漏洞向 dom0 注入任意命令,从而允许攻击者控制 Qubes 操作系统。技术细节 ------------------ `qvm-copy-to-vm` 工具允许将文件从 dom0 复制到指定的 qube。它使用“qfile”协议,这是一种简化的存档格式,包括简单的文件元数据(比“tar”或“cpio”简单得多)。该协议还包括最后的传输确认,该确认由目标发送回源。此确认包括所有传输文件的校验和、错误代码(如果有)以及最后接收的文件的名称。如果出现错误(如错误代码字段所报告),dom0 将显示一条 GUI 消息,其中包括目标 qube 所报告的错误信息和受影响文件的名称。该漏洞存在于该文件名的处理中: 1. `wait_for_result()` 函数在将接收到的名称传递给错误处理程序之前调用 `sanitize_remote_filename()`: linux-utils/qrexec-lib/pack.c: 55 static void sanitize_remote_filename(char *untrusted_filename) 56 { 57 for (; *untrusted_filename; ++untrusted_filename) { 58 if (*untrusted_filename < ' ' || 59 *untrusted_filename > '~' || 60 *untrusted_filename == '"') 61 *untrusted_filename = '_'; 62 } 63 } 64 65 void wait_for_result(void) 66 { ... 98 /* 清理远程文件名 */ 99 sanitize_remote_filename(last_filename); 100 101 errno = hdr.error_code; 102 if (hdr.error_code != 0) { 103 switch (hdr.error_code) { 104 case EEXIST: 105 call_error_handler("名为 \"%s\" 的文件已存在QubesIncoming dir", last_filename); 106 break; ... 2. 然后, `call_error_handler()` 调用错误报告函数的 dom0 变体 -- `gui_fatal()` -> `display_error()`,它使用 `system()` 启动实际的错误对话框: core-admin-linux/file-copy-vm/qfile-dom0-agent.c: 15 void display_error(const char *fmt, va_list args) { 16 char *dialog_cmd; 18 struct stat st_buf; 19 int ret; 20 21 (void) vsnprintf(buf, sizeof(buf), fmt, args); &st_buf); 23 #define KDIALOG_CMD "kdialog --title '文件复制/移动错误' --sorry " 24 #define ZENITY_CMD "zenity --title '文件复制/移动错误' --warning --text " 25 if (asprintf(&dialog_cmd, "%s '%s: %s (错误类型: %s)'", 26 ret==0 ? KDIALOG_CMD : ZENITY_CMD, 27 程序调用短名称, buf, strerror(errno)) < 0) { 28 fprintf(stderr, "未能为错误消息分配内存:(\n"); 29 return; 30 } 31 #undef KDIALOG_CMD 32 #undef ZENITY_CMD 33 fprintf(stderr, "%s\n", buf); 35 } 36 37 _Noreturn void gui_fatal(const char *fmt, ...) { 38 va_list args; 40 display_error(fmt, args); 42 exit(1); 43 } 问题是“sanitize_remote_filename()”仅删除非 ASCII 字符(和双引号),但保留 shell 元字符。然后,“system()”通过 shell 运行构造的命令,包括攻击者控制的名称。请注意,“qvm-copy-to-vm”的 VM 变体不受影响,因为其错误报告函数版本不使用“system()”: core-agent-linux/qubes-rpc/gui-fatal.c: 16 static void Produce_message(const char *type, const char *fmt, va_list args) 17 { ... 31 if (progress_type && !strcmp(progress_type, "gui")) 32 { 33 switch (fork()) 34 { 35 case -1: 36 exit(1); // 还有什么 37 case 0: 38 if (geteuid() == 0) { 39 if (setuid(getuid()) != 0) { 40 perror("setuid 失败,未调用 zenity/kdialog"); 42 } 43 } 44 fix_display(); execlp(“/usr/bin/zenity”,“zenity”,“--error”,“--text”,dialog_msg,NULL); 46 execlp(“/usr/bin/kdialog”,“kdialog”,“--sorry”,dialog_msg,NULL); 48 默认值:; 49 } 50 } 51 free(dialog_msg); 52 } 53 54 void g
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱