Here Microsoft’s control.exe is used to load the library, however, it can also be loaded via node js (and using the fs-module it’s possible to create the ADS).
Another possibility is to overwrite an existing library if application whitelisting was configured only based on paths (because of updates).
Here are some additional methods which I tried to avoide the file write at all:
Some methods which I tried for in-memory files
A good explanation why these paths work can be found at .
However, both path formats are not allowed inside node.js (the code later calls lstat which throws a file not found exception). Moreover, Microsoft internally writes the file to %localappdata%, making the approach useless to achieve file-less exploitation.
Another idea was to abuse named pipes which can be created with node.js code, however, named pipes are not seekable and therefore LoadLibrary() / require() fail.
For people wondering why NVIDIA ships with node.js
At startup, NVIDIA starts a webserver via node.js (providing functionality like the above mentioned webcam control) on a randomized port. To protect against attacks a random secret cookie is created and must be passed to interact with the service. The information about the used port number and cookie value can be extracted from the following file:
Node.js itself can be started via one of the public known techniques (see our slides at ), for example .chm, .lnk, .js, .jse, Java applets, macros, from an exploited process, pass-the-hash and so on.
Standard obfuscation tricks can be used to further hide the invocation. For example, the following code starts calc.exe but tries to further hide:
echo "outdated settings;set colors=";c=
specialChars='/*&^"|;"%ProgramFiles(x86)%\NVIDIA Corporation\NvNode\NVIDIA Web Helper.exe"
Such code can be used as persistence mechanism (auto start) because the called binary is signed by NVIDIA and will be considered as safe. Of course, additional anti-monitoring tricks such as ^ or %programdata:~0,-20% can be used somewhere inside the above command line to further prevent detection, however, such code is in my opinion traitorous.
For security consultants, it’s recommended to search for node.js binaries (file size > 10 MB and binary contains Node.js strings) during client security audits to identify other vendors which ship node.js to clients.
For blue teamers, it’s recommended to remove the file from the whitelist (if possible) or at least monitor it’s invocation.
This research was done by René Freingruber (@ReneFreingruber) on behalf of SEC Consult Vulnerability Lab.