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
gitextract_68h61zmj/ ├── CppWSManWinRM.cpp ├── LICENSE ├── README.md ├── SharpWSManWinRM.cs ├── WSManWinRM.js ├── WSManWinRM.ps1 └── WSManWinRM.vbs
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.