The Vault
Tuesday, March 1, 2022
~
Saturday, February 19, 2022
KDU v1.2 release and the wonderful world of Microsoft incoherency
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)
Providers description
(number is ID in KDU database)HVCI blocklist or welcome to wonderful world of Microsoft incoherency
- There are exist alternatives with much simpler (or none at all) verification logic, using them you can achieve the same "terminator" features;
- 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.
Pic 5. The old the new thing |
Thursday, April 22, 2021
KDU v1.1 release and bonus (AsIO3.sys unlock)
KDU stands for Kernel Driver Utility. It was developed mainly to assist in some other projects, like for example VBoxHardenedLoader. Since release in the beginning of 2020 it supported various vulnerable drivers as "functionality providers".
Overall these are the major 1.1 version changes:
- Driver mapping shellcode has been updated, two additional shellcode variants have been added;
- More vulnerable drivers from Huawei, Realtek, MSI, LG, ASUSTeK have been added.
Details about changes are below.
Shellcode variants
Overall shellcode has been redesigned to work with mapped section instead of registry. Previous version read payload driver image from Windows registry specific key. It was quick and cheap solution as I didn't bother with it and just re-used Stryker bootstrap shellcode variant. Now KDU will allocate special section with random name to store payload driver image, additional parameters and to query result uppon shellcode execution completion.
There are three variants of driver mapping shellcode available for selection via -scv <number> command. The difference between them is how they handle payload execution part. First variant uses newly created system thread to run payload entry point. It is pretty much the same method as original KDU/TDL/Stryker use. Second allocates work item and runs payload entry point within existing system worker thread. Third is more complex as it is designed for a small limited usage with drivers that are unaware of preconditions required for manual mapping. Preciously they require their DriverEntry parameters to be valid. This shellcode variant will allocate driver object, fill it common part and pass it together with supplied registry path to the payload DriverEntry as parameters. This is something like Dustman copy-pasters did with Eldos RawDisk however it also provides valid registry path parameter which is can be used by payload driver. While using 3rd shellcode version you need to supply driver object name using command -drvn <ObjectName> and optionally registry key name -drvr <RegName>. If no registry key name specified KDU will assume registry key name is the same as driver object name. Examples of usage -> https://github.com/hfiref0x/KDU#usage.
New providers
- Huawei PhyMemx64 driver from Huawei MateBook Manager of various versions. This driver is a blatant copy-paste from infamous WINIO source code;
- Realtek RtkIo64 driver from Realtek Dash Client Utility of various versions. This driver based on PHYMEM open-source project code, which is a wormhole by design;
- EneTechIo64 from MSI Dragon Center, it is similar to previously added EneTech variants (all based on WINIO), however it utilizes "unique" unlocking algorithm (see https://swapcontext.blogspot.com/2020/08/ene-technology-inc-vulnerable-drivers.html for a complete overview) and freshly signed so that is why I decided to add this variant too;
- LG LHA driver from LG Device Manager, which is explained in Jackson_T blogpost. This driver is semi-original with some influence of open-source projects;
- ASUSTeK AsIO2 driver from ASUS GPU Tweak utility, this driver also described in my blogpost about EneTech drivers derivatives.
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:
- They have been forced to make it pass Driver Verifier checks; 👏
- New driver lock, no more TinyAES with keys found by devs in Google search;
- 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:
- Make a copy of AsusCertService somewhere, make sure it is unmodified otherwise driver side hash check will fail;
- Create a zombie process from this copy, stop before calling entrypoint;
- Unmap original code and replace it with your own shellcode;
- Resume zombie process;
- In a shellcode -> open driver and register your parent process in trusted process list using 0xA040A490 IOCTL code;
- 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;
- Now from your process you can do whatever you want with AsIO3, for example BSOD it (since AsIO3 provides full set of unfixed WINIO vulnerabilities/bugs).
Pic 4. AsIO3 usual state. |
Well, what can I say. A quantum supercomputer calculating for a thousand years could not even approach the number of fucks which ASUS do not give when it comes to security of their drivers.
AsIO3 unlock PoC can be found at -> https://github.com/hfiref0x/AsIo3Unlock
Disclaimer
Using KDU program might crash your computer with BSOD. Compiled binary
and source code provided AS-IS in hope it will be useful BUT WITHOUT
WARRANTY OF ANY KIND. Since KDU rely on completely bugged and vulnerable drivers security of computer where it executed maybe put at risk. Make sure you understand what you do.
KDU github with precompiled binaries -> https://github.com/hfiref0x/KDU
Monday, April 5, 2021
Trend Micro's Rootkit Buster - Blast From The Past? Nope.
Pic 1. TrendMicro abandonware.
Recently I came across an article "How to use Trend Micro’s Rootkit Remover to Install a Rootkit" by Bill Demirkapi. It covers TrendMicro out of date antirootkit called "RootkitBuster". TL;DR it is dangerous software full of hacks and potential kernel level vulnerabilities. My interest was attracted by the part about some pieces of code author of blogpost found weird. After reading it I thought that I can actually answer on questions made in this blogpost. A little introduction and small excursion into history are required before we can move on to answering questions.
Long time ago in a galaxy far away
I'm familiar with this software since... hmm decades? It just so happened that I probably know one of the guys who worked on this software and in general familiar with this software class, it design and reasons why it looks so terrible from this year perspective.
Rootkit Buster is a classic 3rd generation antirootkit created in the second half of the 200x in response to dominance of kernel mode rootkits on MS Windows. Almost every ISV created this kind of software in that times, some made standalone tools like TrendMicro, Kaspersky, Avast, BitDefender, Sophos, F-Secure (with their infamous by it uselessness BlackLight). Some ISV incorporated their functionality directly into their mainstream products like for example Dr.Web or later Avast (when they acquired author of freeware GMER). Almost all of them were useless and never bothered rootkit developers to address their detection's in rootkit updates. There is a few exceptions of course like Dr.Web antirootkit engine and Kaspersky TDSSKiller. Aside of this anything else were merely a jokes. Entire battlefront with rootkits of that era was up to freeware tools made by enthusiasts. Starting from Rutkowska PoC's (like system virginity verifier, klister) and following 2nd generation with IceSword from pjf, Darkspy from CardMagic and wowocock and ending up 3rd generation with various tools like KDetective, RootRepeal, GMER many many of them (I have complete museum collection of them, including various versions, which is about 200 mb archive).
While notorious malware families of that time largely utilized kernel mode rootkit components it were developed by a really small group of original authors. It was obvious for everyone who were familiar with their design and implementation (winking for those I know). Later in the beginning of 201x they left and market was flooded with copy-pasted, "renewed" junk copies. It quickly degenerated completely and moved into limited usage in the APT, like for example Turla rootkit which is heavily inspired by 200x solutions for antidetection.
Really, really bad code?
Both rootkits/antirootkits were using completely undocumented stuff, internal Windows structures, doing with kernel basically all what they want in a completely unsafe manner. Was it bad code? Obviously, for reference you can look on KSBinSword - a Chinese IceSword copy-paste clone with source code available. Solutions it used were widely used in any other antirootkits of that times. Or look on more recent Kernel Detective with also now available source code. Unfortunately there was no way to successfully counteract malware rootkits without going on their or deeper level. Which required going deeper into undocumented thing and unsafe solutions. So was it really "bad" code? BSOD-generators for sure. Have you ever saw Kaspersky AV 6.0-7.0 source code? It is a ridiculous mess and their drivers are dangerous bugfest by design. Does it mean Kaspesrky 6/7 were failures? Nope, they both were highly successful and actually delivered a lot of problems for malware authors of that time. It was bad but it was adequate solution to that time. Simple because everything else was ineffective. This mess required operation system vendor response at first place. And MS did the job so now we can look into the past and be horrified.
Rootkit Buster is a direct successor of those times (it both design and code) and has been really polished compared to most of other ISV tools of this kind. This does not mean it is highly effective against dedicated malware it only mean that others are can be worse.
Bruteforcing Processes
What is the point of it and why not use documented API here, as blogpost author stated? It is a simple answer if you somewhat familiar with rootkit/antirootkit development.
Usually we use the ZwQuerySystemInformation function in the kernel to traverse the process module and obtain the process information. This is through the normal process traversal method. Therefore, multiple rootkits will intercept the ZwQuerySystemInformation function to filter the specified process to realize the hidden process. At the time, you couldn't trust in regular API call result because they can be easily faked through DKOM or manipulations with API hooks on various levels. Trust no one except yourself - is a main slogan for antirootkits of that era. One of the first tools implemented PID bruteforce for detecting hidden processes was, suprise-surprise, F-Secure Blacklight. There is nothing wrong with this method, it quickly became outdated as rootkits managed to go deeper and started modifying kernel objects structures, however it still has right to exist. Of course all this apply to 200x era.
Bruteforcing Offsets
Why not use ZwQueryInformatonProcess with ProcessImageFileName here?
Again if you familiar with things answer is simple. Using API in that case will ultimately lead into malicious hook where returned data will be faked. Aside from this it is not an Rootkit Buster innovation - in fact they simple used same code snipped with known for ages Russinovich RegMon source code (or maybe even earlier). In an effort to remain version-independent, rather than using a hard-coded offsets, it scan the process object structure memory looking for the name, which should match that of the GUI process, see RegMon source code.
EPROCESS PEB Offset
Same as above. You can't trust API here unless you want to jump into rootkit trap. Notorious hardcore rootkits of that era always played at the edge of system collapse, modifying anything until the limit where they can't keep system alive anymore. Besides, offset are required to direct access to the kernel structures (thus avoiding all API hooks). Process Environment Block location is one of the key things for every antirootkit.
ETHREAD StartAddress Offset
Same as above. This offset needed for direct access to the object structure field. Additionally such scans are somewhat version independent code thus you don't need to hardcode 10-15 versions of ETHREAD offsets for single structure member if you have to support multiple Windows versions. None of API calls here (ZwQueryInformationThread) does makes any sense.
Pretty much all of the questions author made can be answered by just taking a look in any of "Rootkits blah blah blah" books dated back to 200x.
So Why?
RootkitBuster is a combination of out-dated techniques, methods from Windows XP era, that (it is my guess) are just blatantly copied from x86-32 and compiled for x64 without any actual refactoring (except part for making it compilable and verifier friendly ROFL). Obviously parts of code highlighted by author has a little sense (if any) on 64 bit Windows version with PatchGuard and other fancy security features built-in. In general this software has no sense on x64 and looks completely abandoned. It version 5 was released in 2011, do you see any hints here?
Just reversing of drivers for exploits is not enough for their code complete understanding. You have to be familiar with what they actually do and how this is implemented, not to say about baggage of experience in that field.
From a malicious usage perspective RootkitBuster also has nothing to offer. Take it as a sort of unusual museum exponent. If you want to look at really dangerous software actively developed and distributed under multiple "best security" crapware brands - take Zemana (or any of it pseudonyms) driver as example of complete hack-o-rama, right here, right now on x64.
Wednesday, November 4, 2020
People That
Succ
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 Byp@$$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.
Conclusions:
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.
Monday, November 2, 2020
UAC bypasses from COMAutoApprovalList
Intro
(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:
HKEY_CLASSES_ROOT\CLSID
{CLSID}
Elevation
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\
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.
- IexAxiAdminInstaller
- 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:
- Allocate elevated object of IEAxiAdminInstaller (CLSID: {BDB57FF2-79B9-4205-9447-F5FE85F37312}, IID: {9AEA8A59-E0C9-
40F1-87DD-757061D56177}). - Initialize admin installation by calling IEAxiAdminInstaller->InitializeAdminInstaller. This will give us unique string GUID that is used in further calls.
- Query IEAxiInstaller2 broker object with QueryInterface from IEAxiAdminInstaller. (IID: {BC0EC710-A3ED-4F99-B14F-5FD59FDACEA3})
- 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.
- 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.
- Same as before.
- Same as before.
- Same as before.
- 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).
- Allocate IFileOperation object and use it to replace [1]consent.exe with our payload executable. Name must be the same -> [1]consent.exe.
- Run IEAxiInstaller2->RunSetupCommand with parameter set to the forged file.
- ...
- 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:
- Create registry protocol entry somewhere in HKEY_CURRENT_USER\Software\Classes.
- Query UserAssocSet function address from shell32.dll .text section using known patterns.
- Register new association for "http" by calling UserAssocSet with first parameter set to UASET_PROGID.
- Allocate elevated object IWscAdmin (CLSID: {E9495B87-D950-4AB5-87A5-FF6D70BF3E90}, IID: {49ACAA99-F009-4524-9D2A-D751C9A38F60}).
- Call IWscAdmin->Initialize (it is required for interface to work as it contain some GUI stuff).
- Call IWscAdmin->DoModalSecurityAction with "action" parameter set to 103 to trigger ShellExecuteEx call.
- ...
- 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.
P.S.
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.
References
- UACMe, https://github.com/hfiref0x/UACME
- ByeIntegrity2, https://github.com/AzAgarampur/byeintegrity2-uac
- ByeIntegrity3, https://github.com/AzAgarampur/byeintegrity3-uac
- Digging for Sandbox Escapes, https://www.blackhat.com/docs/us-14/materials/us-14-Forshaw-Digging-For_IE11-Sandbox-Escapes.pdf
- OleView, https://docs.microsoft.com/en-us/windows/win32/com/ole-com-object-viewer
- OleView.NET, https://github.com/tyranid/oleviewdotnet
- 如何绕过Win8、Win10的systemsetting与注册表校验设置默认浏览器, https://www.freebuf.com/articles/system/130288.html