Possible anti-sandbox trick using SetSystemTimeAdjustment API


Just to expand on the forensic side of things – the time adjustment value, if changed, does not survive the reboot; i.e the adjustment value is not stored anywhere (e.g. in Registry).

Old post

Today I was browsing some of my archives and (re-)discovered a program written by my ex-coworker before Tue Feb 10 20:20:38 2004 (thx PE compilation time ;). The program was written with QA test automation in mind, but when I ran it today on my win7 VM I realized that the very same trick could be used to affect the inner working of the sandbox systems, or even disturb some reversing work…

The program is simple; it allows the user to modify the ‘adjustment’ value for the Windows Clock.

What does it mean?

Googling around I found this post that explains the inner workings of this mechanism better than I could ever do myself. The magic API is called SetSystemTimeAdjustment; it’s good to know that it internally calls NtSetSystemInformation with a SystemTimeAdjustmentInformation parameter. Sandbox programmers please take a notice.

As per the MSDN article:

The GetSystemTimeAdjustment and SetSystemTimeAdjustment functions support algorithms that synchronize the time-of-day clock, reported via GetSystemTime and GetLocalTime, with another time source using a periodic time adjustment.

Okay, enough theory.

After I ran the program and adjusted the ‘adjustment’ (pun intended) setting to the ‘max’ my clock went completely crazy:

(btw. this is tested and recorded on win7; win10 clock is such a ‘paradigm shift’ in the user interface that I can’t even begin to describe my despair…)

Running timeout 10 command suddenly doesn’t work as it should. It exits immediately or almost instantly and shows some funny values on the screen (kinda integer overflow ;). Same goes for timeout 100, 1000, 10000…

Interestingly, running ping doesn’t cause any issues.

And this is because timeout is using a _time API function that is being checked every 100 ms. If we adjust the clock to run faster the _time function will produce the result that is immediately much higher than expected under normal circumstances (so, delta between the start value and next value is big enough o satisfy the exit condition); as a result, the timeout program will quit. Ping is using a call to Sleep (1000) API in a loop (between the pings, the number of which is default 3 and can be changed by the -n command line argument), and that’s why it is not affected.

So, the conclusion can be that if any program ran by a sandbox on the test system is relying on a difference between two sequential values returned by any of the time function relying on the adjustment (GetSystemTime , GetLocalTime, _time, etc.) – it will be affected. Sandboxes that don’t run any ‘worker’ programs on the guest system can sleep well, but… don’t they all run auto clickers (for GUI programs) these days? And these must rely on some delays/time functions. Hmm… As usual, a subject for a further research. I also wonder if changing the settings will affect existing software and potentially introduce some interesting race conditions or at least DoS. The good news is that use of this API requires admin privileges,