Some schools use a product called Respondus LockDown Browser for taking exams or quizzes in online/hybrid classes. Its goal is to prevent cheating by "locking down" the computer it is run on: disabling other applications from running, hiding the taskbar, disabling shortcuts, and opening the test environment in a web browser without a URL input. This of course has many accessibility implications (students dependent on keyboard shortcuts are stuck, screen readers might or might not work...) and is essentially ineffective (students can still use a second computer, or a smartphone). This article isn't really interested in that, though.
LockDown Browser is not very Linux friendly at all. As you might expect, since you can run any desktop environment/window manager you want and switch TTYs at will, it's hard for LockDown Browser to actually lock anything down. (That, and the folks at Respondus probably don't know how to write apps for Linux.) Since I run Linux on all my computers, it is impossible for me to take any quizzes or exams that require LockDown Browser without physically visiting a school computer lab. This is no fun!
Like any reasonable person would do, my first attempt at getting this to work was to spin up a Windows VM (using libvirt+kvm+qemu) and run the browser in there. However, LockDown Browser has some primitive VM detection and threw an error before fully launching. This is reasonable, since students without any morals or ethics might use a VM to cheat.
Given that Respondus can't write a version of this that runs on Linux, I figured they probably couldn't use any cool timing tricks or rely on the behavior of undocumented instructions to detect the VM. So, I set out to make my VM undetectable. This turned out to be pretty easy.
Not all of these steps may be necessary; since I am a law-abiding citizen and don't break contracts, I did not intentionally reverse-engineer the browser. That would be in violation of the EULA, and we can't have that.
Use dmidecode to get your own computer's smbios information. Make a sysinfo node as a child of the domain node in your libvirt domain config:
<sysinfo type="smbios"> <bios> <entry name="vendor">Dell Inc.</entry> <entry name="version">A00</entry> <entry name="date">06/30/2014</entry> <entry name="release">2.1</entry> </bios> <system> <entry name="manufacturer">Dell Inc.</entry> <entry name="product">Inspiron 7347</entry> <entry name="version">00h</entry> <entry name="serial">(service tag redacted)</entry> <entry name="uuid">8c573293-674a-4af1-bfbf-db5baddba5f4</entry> <entry name="sku">Inspiron 7347</entry> <entry name="family">103C_5335KV</entry> </system> </sysinfo>
Actually use the smbios data you just defined by adding to your os node:
<os> ... <smbios mode="sysinfo" /> </os>
Set the cpu mode to host-model. Disable the hypervisor feature. Your cpu node might look like this:
<cpu mode='host-model' check='partial'> <feature policy='disable' name='hypervisor'/> <model fallback='allow'/> </cpu>
In features node:
<features> <kvm> <hidden state="on" /> </kvm> </features>
Qemu sets disk/DVD device model names to things like "QEMU HARDDISK" and "QEMU QEMU DVD-ROM." This is very inconvenient.
You'll need to download a qemu source release and find instances of these strings. I searched for "QEMU and replaced the ones that I found with DELL. So "QEMU HARDDISK" becomes "DELL HARDDISK" and so on.
Build qemu, probably for only one target, and choose a prefix that's not where your usual qemu is. Install it.
./configure --prefix=/usr/local --target-list=x86_64-softmmu make -j5 make install
Edit your <emulator> in libvirt domain config to point to the appropriate binary, probably $PREFIX/bin/qemu-system-x86_64.
Don't use this to cheat (I'm not), that's not cool, it's immoral, and unethical. There's a reason I don't provide modified binaries or a full libvirt domain config here already: I don't want this to be particularly easy for a student who can easily just use a Windows machine.
Licensed under CC-BY-NC-SA 4.0. This means that you may not use this work for commercial purposes, including patching your software if you're Respondus. :)
(yeah, that won't work, but it was worth a try.)
You may find this information helpful for activities like malware analysis, since lots of malware also refuses to run in a VM. (Coincidence? 🤔)