CSA CCPTP模块9-虚拟机环境检测
Command-Line虚拟的一些设备和真实物理主机设备信息有些差异,可以通过一些特殊指令获得相关信息。
dmidecode(need root)
dmidecode指令可以获取系统硬件相关的一些信息,原理是将DMI数据库信息解码,输出的信息包括BIOS、系统、主板、处理器、内存、缓存等。
在VMware

VM信息
在qemu启动的虚拟机中

VM信息
在真实的物理主机上

VM信息
在某云主机上

systemd-detect-virt(不需要root权限)
即可以识别是否处于vm,还可以识别container, 官方描述
It identifies the virtualization technology and can distinguish full machine virtualization from container virtualization. systemd-detect-virt exits with a return value of 0 (success) if a virtualization technology is detected, and non-zero (error) otherwise. By default, any type of virtualization is detected, and the options --container and --vm can be used to limit what types of virtualization are detected.
在vmware主机:systemd-detect-virt

在qemu-kvm启动的虚拟机:systemd-detect-virt

在真实物理主机:systemd-detect-virt

在某云主机:systemd-detect-virt

我最近复现qemu逃逸漏洞,于是就想到一个问题:如何在qemu启动的虚拟机确认qemu的具体版本号
最先想到的方式是通过附加qemu进程,搜索qemu version相关字符串。
找到qemu_get_version函数,交叉引用找到引用该函数的一些接口
简单分析了下,与scsi相关,在处理INQUIRY类型命令时会获取qemu版本信息。
case INQUIRY: if (!scsi_target_emulate_inquiry(r)) { goto illegal_request; }static bool scsi_target_emulate_inquiry(SCSITargetReq *r){.... /* PAGE CODE == 0 */ r->len = MIN(r->req.cmd.xfer, SCSI_INQUIRY_LEN); memset(r->buf, 0, r->len); if (r->req.lun != 0) { r->buf[0] = TYPE_NO_LUN; } else { r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE; r->buf[2] = 5; /* Version */ r->buf[3] = 2 | 0x10; /* HiSup, response data format */ r->buf[4] = r->len - 5; /* Additional Length = (Len - 1) - 4 */ r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */ memcpy(&r->buf[8], "QEMU ", 8); memcpy(&r->buf[16], "QEMU TARGET ", 16); pstrcpy((char *) &r->buf[32], 4, qemu_get_version()); }}
于是参照sg3_utils项目中的scsi_inquiry想要触发这里(没成功,虽然成功完成了SCSI_COMMAND,但是在所有与scsi相关的函数下断,没能断下,很奇怪,望了解的师傅指点下)。但是后来发现一个更简单的方式。
直接在Linux主机运行命令cat /proc/scsi/scsi或者lsscsi查看
VMware主机

qemu 2.5.92 和 2.2 启动的虚拟机


真实物理主机

某云主机

All In One
各种检测虚拟机的手段可以分为以下几类
搜索虚拟环境的进程、文件系统、注册表
搜索虚拟环境内存
搜索虚拟环境特定虚拟硬件
搜索虚拟环境的特定处理器指令和功能

