Links:

Bypassing Exam Cookie

The Implementation of Exam Cookie

My school — along with many others across Denmark — had just implemented Exam Cookie. It was introduced as the solution that would finally stop cheating. It was a response to the rise of ChatGPT as well as other AI tools. A Program that would monitor every aspect of your computer while taking a test. This made me curious whether it could be bypassed. That curiosity is what kicked off this blog post.

From the schools’ perspective the solution was flawless: students knew the program was installed, and teachers assumed that having it running meant students couldn’t cheat, so there were fewer teachers policing rooms in person. In reality, that confidence was misplaced. To be clear: my objective was to understand how the program worked and i didn’t have any malicious intentions. I wanted to understand what the software actually did on student machines and what data it collected.

Before Exam Cookie was rolled out, there were rumors it might be adopted. When I first heard those rumors I downloaded a copy just to see what it was and didn’t think much more of it. Later, when the rollout happened officially at my school, I grabbed the installer again and opened it up in dnSpy — and that’s when the real rabbit hole began.

First Attempt

The build I opened was heavily obfuscated with Babel The exact Babel configuration they used produced a virtualized build for which I could not find a public deobfuscation method for. I spent about two weeks working on that deobfuscation only to watch the Exam Cookie to push an update that completely changed how the client communicated with the servers. Effectively rendering everything I’d almost recovered useless

Second Attempt

A deeper look at the newer version revealed a switch in protection: They had moved to a different obfuscator Eziriz .NET Reactor. That new build was worse. It had more aggressive anti-debugging and anti-tamper features. I was still motivated, and started to deobfuscate the new build, but after roughly three weeks they tweaked the obfuscation settings and made the version I’d been working on obsolete.

This cycle of partial success is a huge motivation killer. Combine that with gaps in my C# and runtime debugging experience and I paused the project for a while.

Finding a Lead

Then, by pure luck, I discovered the very first copy I’d downloaded back when the Exam Cookie rollout was only a rumor. Lucky me: that old copy had no obfuscation nor any protection — none of the virtualization, no resource decryption, practically nothing. This was a goldmine.

Taking a Look at The Features

After taking a look at the non obfuscated version we now know that the program is capable of:

  • Full-screen screenshots
  • USB device enumeration
  • Application list
  • Clipboard contents monitoring
  • Network adapter logging
  • VM detection

Bypassing

While making a bypass for all individual features or emulating the network traffic is an plausible bypass, a way easier method is running the program inside a undetectable VM. To do this we’ll use dnSpy to extract the VmDetect.exe file, which handles the detection of any VM. Opening this file in Binary Ninja, we quickly identify the function sub_402080 which handles the checking of VMs, where we see the only check done is the following:

enum WIN32_ERROR lResult = RegOpenKeyExA(HKEY_CURRENT_USER, 
"HARDWARE\ACPI\DSDT\VBOX__", 0, KEY_READ, &hKeyResult);

Which essentially checks for the regerstry key HARDWARE\ACPI\DSDT\VBOX__ for the current user, if it’s exists, the program flags it as VM. As you can imagine bypassing this won’t be hard. In fact using any other VM than VM Box is the easiest way of bypassing this.

Finding Critical Credentials

While extracting the VmDetect executable, i also discovered the user and password to the WCF endpoint at https://examcookiewinapidk.azurewebsites.net VfUtTaNUEQ:AwWE9PHjVc. Which is likely where the collected data is stored. I haven’t explored this any further.