Bring your own Trusted DLL

Harsh Thakur
Harsh Thakur
Published in
3 min readJul 9, 2019

Introduction

Living off the land when attacking Windows machines has been the key to evading the defenses. The idea behind it is to perform malicious tasks with components which are trusted on the system but really, attackers can get away with components which are trusted by the system and I believe Marcello Salvati has demonstrated it the best. In his recent presentation at Hack in Paris, he mentioned about using ClearScript( Microsoft signed DLL which is made to add scripting to .NET applications) to perform the malicious tasks. He wrote a powershell script to demonstrate that.

Before I begin with my crazy idea, let’s see why Marcello’s script works. Windows has come up with AMSI (Anti Malware Scanner Interface) to make the scripting languages secure.

source: https://twitter.com/KyleHanslovan/status/965938932797132800

So the powershell script(below is a snippet of it) which Marcello wrote loads the ClearScript library into memory dynamically and then accesses the .NET’s Common Language Runtime which lacks security features(at least till version 4.7) and to make all this better, the malicious part happens in jscript/vbscript.

If we were to run malicious jscript with cscript/wscript.exe, it would detected by AMSI.

The “Crazy idea” part

Marcello had mentioned that this doesn’t seem to go through Windows Scripting host but he wasn’t sure. In my head that transalted to

“this doesn’t go through Windows Scripting Host, period”

At this point, I wondered what would happen if a C# equivalent of the powershell script is converted into Jscript using DotnetToJs by James Forshaw and ran it with Wscript. Essentially, we can run malicious jscript without triggering AMSI. This would be preferred as using jscript as a dropper is easier than using powershell. So I wrote the C# equivalent . You can find it here.

I was able to load the clearscript library dynamically and execute Jscript which was accessing CLR and practically script in CLR :) . I have done it using Assembly.Load() which seems to be triggering Defender. I will test using AppDomain.Assembly.Resolve which hopefully solves that problem. Anyway, I proceeded with my plan.

I convereted the csharp to js using DotnetToJs and ran the js file with wscript.exe. Well, the process died instantly :/ .

I have Defender disabled at this point(reason: signature for Assembly.Load()). The exe version works but the js fails. Why? Following Mark Russinovich’s advice:

“When in doubt, run Process Monitor”

I saw that it does utilize Windows Scripting Host and also loads AMSI. This occured in both the scenarios(exe and js). AMSI has signatures for jscript/vbscript but it couldn’t possibly have signatures for CLR being scripted in jscript. I doubt the process died due to AMSI. I have taken the procmon logs of both of them to compare what went wrong. I will describe what I find in another post.

Conclusion

Although my crazy idea failed miserably, loading a trusted DLL into memory and executing malicious code can be considered as a win. I wonder what happens when we manually host a V8 engine.That would test whether AMSI has been integrated into WSH or just the engines. “I have questions” as Casey Smith would say.

--

--

Harsh Thakur
Harsh Thakur

I explore tech. Currently occupied in cloud native landscape.