Social media


Hacking CPU-Z – Can You Trust the Results?

cpuz-validator-2
May 4, 2013 update 2: The CPU-Z has confirmed the inclusion of many security improvement suggestions I submitted.  The next version will be much more secure in terms of the client application and the server.  Can’t say anymore :)
May 2, 2013 update 2: I’m in contact with the CPU-Z team and working with them to improve the security of the program.  The fake listings below have been removed.
May 2, 2013 update 1: HackingTricks.org should now be the record holder for World Frequency Records (Intel Core i7/i5/i3 CPU).  See the record-breaking (fake) 7360 MHz submission here.  
Yes, CPU-Z’s validation website accepts fake data.  See for yourself before the link is pulled: http://valid.canardpc.com/show_oc.php?id=2788357
The CPU-Z cvf file to generate the page you see above could be posted here for download for your own testing.  However, this would create many problems for the CPU-Z folks so it won’t be posted.
CPU-Z is an excellent tool for displaying detailed hardware information.  The main interface consists  of many tabs: CPU, Caches, Mainboard, Memory, SPD, Graphics, and About.  CPU, the main screen, provides real-time displays of Core Speed, Multiplier, Bus Speed, Core Voltage and more.  It’s both a diagnostic and an enthusiast tool that is commonly used by overclockers, system administrators, and regular tech guys.
Unlike other system information tools, CPU-Z has an extra feature that lets users validate clock speeds and system components.  By clicking the Validate or Validation buttons, the user can export clock speeds and the system’s configuration.
There are a couple ways to export system information.  Exported files can be posted directly to CPU-Z’s validation site (http://valid.canardpc.com/) or the user can save the file locally.  The Save Report buttons let the user export to either a .txt or .html file.  By default, the Save Validation File button exports a file called cpuz.cvf.
CPU-Z CVF File
Above, you can see what the inside of the cpuz.cvf file looks like.  You can immediately see that the data looks to be encrypted.  This makes sense because the whole validation service wouldn’t matter a whole lot if users could easily change their hardware stats.  Speaking of hardware stats, the CPU-Z validator site has an overclocking records (OC Records) section with ranks: http://valid.canardpc.com/records.php.
When saving a cvf file or uploading stats directly to the validator site, you may notice the validator checks whether the cvf file is corrupt or invalid.  If you manage to trick CPU-Z into producing results that literally do not add up, you will likely see a similar message…
cpuz-validator-1
Take a look at the red text in the above picture.  If you do the math, 100.32 * 16 is 1605.12.  That’s way off.  The value of 9069.18 MHz is hacked into the application.  CPU-Z’s validator does a great job in detecting these phony results.  Notice how “Rejected” appears at the top along with “Not Validated” in the forum banner / signature graphic.  During some spoofing tests, the validator did not generate a page to display results.  Instead, a plaintext error is generated.  The validator is very good at checking for abnormalities.
Despite the validator’s ability to check for the validity of overclocking speeds, the site does not seem to care about the integrity of the other data.  As you saw early in the post, it was possible to put an HTML link back to this website directly on the CPU-Z page.  In the wrong hands, it is theoretically possible to inject malicious code.  As long as client-side data is imported to the server without any checks, dangers exist.  How was this possible?  When the user clicks validate in CPU-Z, a buffer area 8192 bytes in size is created.  Each hardware specification is written into the buffer in Unicode format.  The entire buffer is then transformed into ASCII format, encrypted, and finally converted to a string to become the cvf format.
How can this be fixed?
Firstly, Instead of trusting any string from the client, it would be better for the server to use a fixed set of values to recognize each possible component.  For example, on the client side, if the program detects a component called “Sandy Bridge”, there should be a corresponding internal, numerical value.  This value can exist in a table among all other currently known hardware name possibilities.  This value, along with the rest of the identified component values, can then be somewhat encrypted using a key / salt based on the current time and other hard to guess pseudo-random values and then sent to the validation server.  The server then accepts the encrypted numerical values, decrypts them, and displays each component by matching up the component’s value with the server’s database of component values / strings.  It would still be possible to produce fake results (ex. an Ivy Bridge with a Celeron processor), but you’d have to know the internal value for each component, and of course, how to intercept / decrypt.
Due to the nature of the software, there must be trust in the client.  Any added complexity and obfuscation is a positive addition.  In the meantime, the best short term solution for the validator’s security problem is to sanitize all input.  This means the validator server should strip away all HTML and executable code.
I hear CPU-Z uses a driver – what’s that all about?
CPU-Z does employ a driver called cpuz136_x64.sys.  Even if you are using the 32-bit version of CPU-Z, the 64-bit driver is loaded.  The driver is 24KB in size and contains the following imports:
0000000000014000 HalSetBusDataByOffset HAL
0000000000014008 KeStallExecutionProcessor HAL
0000000000014010 HalGetBusDataByOffset HAL
0000000000014020 RtlAnsiStringToUnicodeString ntoskrnl
0000000000014028 RtlInitUnicodeString ntoskrnl
0000000000014030 IoDeleteDevice ntoskrnl
0000000000014038 KeInitializeEvent ntoskrnl
0000000000014040 RtlInitAnsiString ntoskrnl
0000000000014048 MmUnmapIoSpace ntoskrnl
0000000000014050 IoCancelIrp ntoskrnl
0000000000014058 RtlFreeUnicodeString ntoskrnl
0000000000014060 IoGetDeviceObjectPointer ntoskrnl
0000000000014068 ExFreePoolWithTag ntoskrnl
0000000000014070 IofCompleteRequest ntoskrnl
0000000000014078 KeWaitForSingleObject ntoskrnl
0000000000014080 PsGetVersion ntoskrnl
0000000000014088 IoCreateSymbolicLink ntoskrnl
0000000000014090 MmIsAddressValid ntoskrnl
0000000000014098 ObfDereferenceObject ntoskrnl
00000000000140A0 IoCreateDevice ntoskrnl
00000000000140A8 IofCallDriver ntoskrnl
00000000000140B0 KeBugCheckEx ntoskrnl
00000000000140B8 IoDeleteSymbolicLink ntoskrnl
00000000000140C0 IoBuildDeviceIoControlRequest ntoskrnl
00000000000140C8 MmMapIoSpace ntoskrnl
00000000000140D0 ExAllocatePoolWithTag ntoskrnl
00000000000140D8 RtlUnwindEx ntoskrnl
For a driver, most of these imports are fairly standard with the exception of HalGetBusDataByOffset and HalSetBusDataByOffset.  These two Windows HAL APIs are likely used for querying data that is otherwise inaccessible from usermode aka userland aka ring3.  Nothing of much interest.
Conclusion
In summary, CPU-Z is an excellent tool for evaluating a computer’s configuration.  Although there are security concerns with the validity and handling of its exported data, overclockers and regular computer users will be hard-pressed to find another diagnostic utility that provides such in-depth detail.
Editor’s note: to correct potential security issues quickly, I have already contacted CPU-Z.  There has not been a response to both contact attempts in over 48 hours.

Previous
Next Post »