Thursday, April 22, 2021

KDU v1.1 release and bonus (AsIO3.sys unlock)

KDU stands for Kernel Driver Utility. It was developed mainly to assist in some other projects, like for example VBoxHardenedLoader. Since release in the beginning of 2020 it supported various vulnerable drivers as "functionality providers".

Overall these are the major 1.1 version changes:

  • Driver mapping shellcode has been updated, two additional shellcode variants have been added;
  • More vulnerable drivers from Huawei, Realtek, MSI, LG, ASUSTeK have been added.

Details about changes are below.

Shellcode variants

Overall shellcode has been redesigned to work with mapped section instead of registry. Previous version read payload driver image from Windows registry specific key. It was quick and cheap solution as I didn't bother with it and just re-used Stryker bootstrap shellcode variant. Now KDU will allocate special section with random name to store payload driver image, additional parameters and to query result uppon shellcode execution completion.

There are three variants of driver mapping shellcode available for selection via -scv <number> command. The difference between them is how they handle payload execution part. First variant uses newly created system thread to run payload entry point. It is pretty much the same method as original KDU/TDL/Stryker use. Second allocates work item and runs payload entry point within existing system worker thread. Third is more complex as it is designed for a small limited usage with drivers that are unaware of preconditions required for manual mapping. Preciously they require their DriverEntry parameters to be valid. This shellcode variant will allocate driver object, fill it common part and pass it together with supplied registry path to the payload DriverEntry as parameters. This is something like Dustman copy-pasters did with Eldos RawDisk however it also provides valid registry path parameter which is can be used by payload driver. While using 3rd shellcode version you need to supply driver object name using command -drvn <ObjectName> and optionally registry key name -drvr <RegName>. If no registry key name specified KDU will assume registry key name is the same as driver object name. Examples of usage -> https://github.com/hfiref0x/KDU#usage.

New providers

  • Huawei PhyMemx64 driver from Huawei MateBook Manager of various versions. This driver is a blatant copy-paste from infamous WINIO source code;
  • Realtek RtkIo64 driver from Realtek Dash Client Utility of various versions. This driver based on PHYMEM open-source project code, which is a wormhole by design;
  • EneTechIo64 from MSI Dragon Center, it is similar to previously added EneTech variants (all based on WINIO), however it utilizes "unique" unlocking algorithm (see https://swapcontext.blogspot.com/2020/08/ene-technology-inc-vulnerable-drivers.html for a complete overview) and freshly signed so that is why I decided to add this variant too;
  • LG LHA driver from LG Device Manager, which is explained in Jackson_T blogpost. This driver is semi-original with some influence of open-source projects;
  • ASUSTeK AsIO2 driver from ASUS GPU Tweak utility, this driver also described in my blogpost about EneTech drivers derivatives.
That's all about KDU. Ironically bonus part is much longer.

Bonus (AsIO3.sys unlock)

ASUSTeK "giveio" drivers seems had some special love from the developers who are sitting on WINIO source code in EneTech. GLCKIO, GLCKIO2, AsIO, AsIo<O><variousnames>, AsIO2 and now AsIO3. What they share in common (except WINIO base) - their authors never fix their bugs. They actually just pull "new" version of driver when someone find a bug in it and contact ASUS for security reasons. Numerous CVE numbers generated by various groups/researches etc. So what they actually changing? Well, they just switching driver "locks" - a primitive handmade solutions which purpose is to block usage of the given driver by 3rd party. And under 3rd party I mean - block and/or ruin the way this driver was exploited in the submitted security issue. Thus submitted issue will be no longer reproducible as-is and they can tell - hey we fixed it, now you can gtfo, lol. Sometimes, like in case of AsIO2 their newly added locking code adds additional bugs and vulnerabilities. But nobody cares I guess.

Their latest release is AsIO3.sys with self-explaining pdb (C:\Working\MB\GLCKIO2\AsIO3\x64\Release\AsIO3_64.pdb). The key changes compared to AsIO2:

  1. They have been forced to make it pass Driver Verifier checks; 👏
  2. New driver lock, no more TinyAES with keys found by devs in Google search;
  3. All the bugs/vulnerabilities of WINIO stay same.

Driver is fresh and comes as part of ASUS GPU Tweak software v2303.

Pic 1. AsIO3 details.


New driver "lock" looks pretty damn solid and complicated! I mean they wasted so much code to create this ineffective piece of garbage while instead they could put their efforts into fixing (or even rewriting) entire WINIO. To "unlock" previous AsIO2 all you need - generate special resource named "asuscert" and put it into your application resources, see complete unlocking code here. In newest versions everything changed. 

AsIO contain three components - AsusCertService.exe (32bit), wrapper dll and driver. In the AsIO3 driver implemented special check of requestor application during IRP_MJ_CREATE. Driver reads file from disk, calculates SHA256 for it and compares this value with hardcoded hash. If they do not match - STATUS_ACCESS_DENIED will be returned to the caller.

Pic 2. AsusCertService.exe SHA256 hardcoded in AsIO3 driver


Thus initially only AsusCertService.exe allowed to open and communicate with AsIO3 driver. Entire purpose of this executable is to manage connections for AsIO3 driver. This driver also provides a way to register "trusted application" that will be able to call AsIO3. AsusCertService setups named pipe (no SD set ROFL) called "asuscert". Now if another application want to use AsIO3 and should contact AsusCertService via named pipe. AsusCertService will validate client executable to be digitally signed and signer must be one of the hardcoded values as shown below.

Pic 3. AsusCertService client signer check.

After successful check service will register client process as trusted for AsIO3 driver by sending special IOCTL 0xA040A490 with input buffer set to client process id. Driver manage this list similar to GLCKIO2 where it was firstly introduced. Another IOCTL 0xA040A494 used to remove client process id from trusted process list. 

How to bypass this garbage and completely useless code and unlock this driver for your application:

  1. Make a copy of AsusCertService somewhere, make sure it is unmodified otherwise driver side hash check will fail;
  2. Create a zombie process from this copy, stop before calling entrypoint;
  3. Unmap original code and replace it with your own shellcode;
  4. Resume zombie process;
  5. In a shellcode -> open driver and register your parent process in trusted process list using 0xA040A490 IOCTL code;
  6. Make sure AsusCertService zombie process will be alive and kicking (put it into infinite wait for example in your shellcode) while your main process is working, this is to prevent AsIO3 driver from zeroing trusted processes list;
  7. Now from your process you can do whatever you want with AsIO3, for example BSOD it (since AsIO3 provides full set of unfixed WINIO vulnerabilities/bugs).



Pic 4. AsIO3 usual state.

Well, what can I say. A quantum supercomputer calculating for a thousand years could not even approach the number of fucks which ASUS do not give when it comes to security of their drivers.

AsIO3 unlock PoC can be found at -> https://github.com/hfiref0x/AsIo3Unlock

Disclaimer

Using KDU program might crash your computer with BSOD. Compiled binary and source code provided AS-IS in hope it will be useful BUT WITHOUT WARRANTY OF ANY KIND. Since KDU rely on completely bugged and vulnerable drivers security of computer where it executed maybe put at risk. Make sure you understand what you do.

KDU github with precompiled binaries -> https://github.com/hfiref0x/KDU

Monday, April 5, 2021

Trend Micro's Rootkit Buster - Blast From The Past? Nope.

Pic 1. TrendMicro abandonware.
 

Recently I came across an article "How to use Trend Micro’s Rootkit Remover to Install a Rootkit" by Bill Demirkapi. It covers TrendMicro out of date antirootkit called "RootkitBuster". TL;DR it is dangerous software full of hacks and potential kernel level vulnerabilities. My interest was attracted by the part about some pieces of code author of blogpost found weird. After reading it I thought that I can actually answer on questions made in this blogpost. A little introduction and small excursion into history are required before we can move on to answering questions.

Long time ago in a galaxy far away

I'm familiar with this software since... hmm decades? It just so happened that I probably know one of the guys who worked on this software and in general familiar with this software class, it design and reasons why it looks so terrible from this year perspective.

Rootkit Buster is a classic 3rd generation antirootkit created in the second half of the 200x in response to dominance of kernel mode rootkits on MS Windows. Almost every ISV created this kind of software in that times, some made standalone tools like TrendMicro, Kaspersky, Avast, BitDefender, Sophos, F-Secure (with their infamous by it uselessness BlackLight). Some ISV incorporated their functionality directly into their mainstream products like for example Dr.Web or later Avast (when they acquired author of freeware GMER). Almost all of them were useless and never bothered rootkit developers to address their detection's in rootkit updates. There is a few exceptions of course like Dr.Web antirootkit engine and Kaspersky TDSSKiller. Aside of this anything else were merely a jokes. Entire battlefront with rootkits of that era was up to freeware tools made by enthusiasts. Starting from Rutkowska PoC's (like system virginity verifier, klister) and following 2nd generation with IceSword from pjf, Darkspy from CardMagic and wowocock and ending up 3rd generation with various tools like KDetective, RootRepeal, GMER many many of them (I have complete museum collection of them, including various versions, which is about 200 mb archive).

While notorious malware families of that time largely utilized kernel mode rootkit components it were developed by a really small group of original authors. It was obvious for everyone who were familiar with their design and implementation (winking for those I know). Later in the beginning of 201x they left and market was flooded with copy-pasted, "renewed" junk copies. It quickly degenerated completely and moved into limited usage in the APT, like for example Turla rootkit which is heavily inspired by 200x solutions for antidetection.

Really, really bad code?

Both rootkits/antirootkits were using completely undocumented stuff, internal Windows structures, doing with kernel basically all what they want in a completely unsafe manner. Was it bad code? Obviously, for reference you can look on KSBinSword - a Chinese IceSword copy-paste clone with source code available. Solutions it used were widely used in any other antirootkits of that times. Or look on more recent Kernel Detective with also now available source code. Unfortunately there was no way to successfully counteract malware rootkits without going on their or deeper level. Which required going deeper into undocumented thing and unsafe solutions. So was it really "bad" code? BSOD-generators for sure. Have you ever saw Kaspersky AV 6.0-7.0 source code? It is a ridiculous mess and their drivers are dangerous bugfest by design. Does it mean Kaspesrky 6/7 were failures? Nope, they both were highly successful and actually delivered a lot of problems for malware authors of that time. It was bad but it was adequate solution to that time. Simple because everything else was ineffective. This mess required operation system vendor response at first place. And MS did the job so now we can look into the past and be horrified.

Rootkit Buster is a direct successor of those times (it both design and code) and has been really polished compared to most of other ISV tools of this kind. This does not mean it is highly effective against dedicated malware it only mean that others are can be worse.

Bruteforcing Processes

What is the point of it and why not use documented API here, as blogpost author stated? It is a simple answer if you somewhat familiar with rootkit/antirootkit development. 

Usually we use the ZwQuerySystemInformation function in the kernel to traverse the process module and obtain the process information. This is through the normal process traversal method. Therefore, multiple rootkits will intercept the ZwQuerySystemInformation function to filter the specified process to realize the hidden process. At the time, you couldn't trust in regular API call result because they can be easily faked through DKOM or manipulations with API hooks on various levels. Trust no one except yourself - is a main slogan for antirootkits of that era. One of the first tools implemented PID bruteforce for detecting hidden processes was, suprise-surprise, F-Secure Blacklight. There is nothing wrong with this method, it quickly became outdated as rootkits managed to go deeper and started modifying kernel objects structures, however it still has right to exist. Of course all this apply to 200x era.

Bruteforcing Offsets

Why not use ZwQueryInformatonProcess with ProcessImageFileName here?

Again if you familiar with things answer is simple. Using API in that case will ultimately lead into malicious hook where returned data will be faked. Aside from this it is not an Rootkit Buster innovation - in fact they simple used same code snipped with known for ages Russinovich RegMon source code (or maybe even earlier). In an effort to remain version-independent, rather than using a hard-coded offsets, it scan the process object structure memory looking for the name, which should match that of the GUI process, see RegMon source code.

EPROCESS PEB Offset

Same as above. You can't trust API here unless you want to jump into rootkit trap. Notorious hardcore rootkits of that era always played at the edge of system collapse, modifying anything until the limit where they can't keep system alive anymore. Besides, offset are required to direct access to the kernel structures (thus avoiding all API hooks). Process Environment Block location is one of the key things for every antirootkit.

ETHREAD StartAddress Offset

Same as above. This offset needed for direct access to the object structure field. Additionally such scans are somewhat version independent code thus you don't need to hardcode 10-15 versions of ETHREAD offsets for single structure member if you have to support multiple Windows versions. None of API calls here (ZwQueryInformationThread) does makes any sense.

Pretty much all of the questions author made can be answered by just taking a look in any of "Rootkits blah blah blah" books dated back to 200x.

So Why?

RootkitBuster is a combination of out-dated techniques, methods from Windows XP era, that (it is my guess) are just blatantly copied from x86-32 and compiled for x64 without any actual refactoring (except part for making it compilable and verifier friendly ROFL). Obviously parts of code highlighted by author has a little sense (if any) on 64 bit Windows version with PatchGuard and other fancy security features built-in. In general this software has no sense on x64 and looks completely abandoned. It version 5 was released in 2011, do you see any hints here?

Just reversing of drivers for exploits is not enough for their code complete understanding. You have to be familiar with what they actually do and how this is implemented, not to say about baggage of experience in that field.

From a malicious usage perspective RootkitBuster also has nothing to offer. Take it as a sort of unusual museum exponent. If you want to look at really dangerous software actively developed and distributed under multiple "best security" crapware brands - take Zemana (or any of it pseudonyms) driver as example of complete hack-o-rama, right here, right now on x64.