254 lines
14 KiB
PHP
254 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class WinRMClient
|
|
{
|
|
private $ip;
|
|
private $username;
|
|
private $password;
|
|
private $url;
|
|
private $auth;
|
|
|
|
public function __construct($ip, $username, $password)
|
|
{
|
|
$this->ip = $ip;
|
|
$this->username = $username;
|
|
$this->password = $password;
|
|
$this->url = "http://{$this->ip}:53389/wsman";
|
|
$this->auth = base64_encode("{$this->username}:{$this->password}");
|
|
}
|
|
|
|
private function send_winrm_request($headers, $body)
|
|
{
|
|
try {
|
|
// Make the HTTP POST request
|
|
$response = Http::withHeaders($headers)
|
|
->withBasicAuth('administrator', 'Thegioiso@123**$$8899TgTk2')
|
|
->timeout(20) // Timeout in seconds
|
|
->withBody($body, 'application/soap+xml;charset=UTF-8') // Ensure the correct content type
|
|
->withoutVerifying() // Disable SSL verification
|
|
->post($this->url);
|
|
|
|
// Check for a successful response
|
|
if ($response->successful()) {
|
|
return $response->body();
|
|
}
|
|
// Handle response errors
|
|
return 'Error: ' . $response->status() . ' - ' . $response->body();
|
|
} catch (\Exception $e) {
|
|
// Handle exceptions
|
|
return 'Exception: ' . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
private function get_headers()
|
|
{
|
|
return [
|
|
"Host: {$this->ip}:53389",
|
|
"User-Agent: PHP WinRM client",
|
|
"Accept-Encoding: gzip, deflate, br",
|
|
"Accept: */*",
|
|
"Connection: keep-alive",
|
|
"Content-Type: application/soap+xml;charset=UTF-8",
|
|
"Authorization: Basic {$this->auth}"
|
|
];
|
|
}
|
|
|
|
public function execute_command($command)
|
|
{
|
|
$headers = $this->get_headers();
|
|
|
|
// Step 1: Create Shell
|
|
$create_shell_body = $this->get_create_shell_body();
|
|
$response = $this->send_winrm_request($headers, $create_shell_body);
|
|
$shell_id = preg_match('/<rsp:ShellId>(.*?)<\/rsp:ShellId>/s', $response, $matches) ? $matches[1] : null;
|
|
|
|
if (!$shell_id) {
|
|
return "Failed to create shell session.";
|
|
}
|
|
|
|
// Step 2: Execute Command
|
|
$execute_command_body = $this->get_execute_command_body($shell_id, $command);
|
|
$response = $this->send_winrm_request($headers, $execute_command_body);
|
|
$command_id = preg_match('/<rsp:CommandId>(.*?)<\/rsp:CommandId>/s', $response, $matches) ? $matches[1] : null;
|
|
|
|
if (!$command_id) {
|
|
return "Failed to execute command.";
|
|
}
|
|
|
|
// Step 3: Receive Command Output
|
|
$receive_output_body = $this->get_receive_output_body($shell_id, $command_id);
|
|
$response = $this->send_winrm_request($headers, $receive_output_body);
|
|
$output = $this->parse_command_output($response, $command_id);
|
|
|
|
// Step 4: Signal Termination
|
|
$signal_termination_body = $this->get_signal_termination_body($shell_id, $command_id);
|
|
$this->send_winrm_request($headers, $signal_termination_body);
|
|
|
|
// Step 5: Delete Shell Session
|
|
$delete_shell_body = $this->get_delete_shell_body($shell_id);
|
|
$this->send_winrm_request($headers, $delete_shell_body);
|
|
|
|
return $output;
|
|
}
|
|
|
|
private function get_create_shell_body()
|
|
{
|
|
// XML body for creating a shell
|
|
return '<?xml version="1.0" encoding="utf-8"?>
|
|
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:b="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:cfg="http://schemas.microsoft.com/wbem/wsman/1/config">
|
|
<env:Header>
|
|
<a:To>http://' . $this->ip . ':53389/wsman</a:To>
|
|
<a:ReplyTo>
|
|
<a:Address mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<w:MaxEnvelopeSize mustUnderstand="true">153600</w:MaxEnvelopeSize>
|
|
<a:MessageID>uuid:' . uniqid() . '</a:MessageID>
|
|
<w:Locale mustUnderstand="false" xml:lang="en-US"/>
|
|
<p:DataLocale mustUnderstand="false" xml:lang="en-US"/>
|
|
<w:OperationTimeout>PT60S</w:OperationTimeout>
|
|
<w:ResourceURI mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd</w:ResourceURI>
|
|
<a:Action mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action>
|
|
<w:OptionSet>
|
|
<w:Option Name="WINRS_NOPROFILE">FALSE</w:Option>
|
|
<w:Option Name="WINRS_CODEPAGE">437</w:Option>
|
|
</w:OptionSet>
|
|
</env:Header>
|
|
<env:Body>
|
|
<rsp:Shell>
|
|
<rsp:InputStreams>stdin</rsp:InputStreams>
|
|
<rsp:OutputStreams>stdout stderr</rsp:OutputStreams>
|
|
</rsp:Shell>
|
|
</env:Body>
|
|
</env:Envelope>';
|
|
}
|
|
|
|
private function get_execute_command_body($shell_id, $command)
|
|
{
|
|
// XML body for executing a command
|
|
return '<?xml version="1.0" encoding="utf-8"?>
|
|
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:b="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:cfg="http://schemas.microsoft.com/wbem/wsman/1/config">
|
|
<env:Header>
|
|
<a:To>http://' . $this->ip . ':53389/wsman</a:To>
|
|
<a:ReplyTo>
|
|
<a:Address mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<w:MaxEnvelopeSize mustUnderstand="true">153600</w:MaxEnvelopeSize>
|
|
<a:MessageID>uuid:' . uniqid() . '</a:MessageID>
|
|
<w:Locale mustUnderstand="false" xml:lang="en-US"/>
|
|
<p:DataLocale mustUnderstand="false" xml:lang="en-US"/>
|
|
<w:OperationTimeout>PT60S</w:OperationTimeout>
|
|
<w:ResourceURI mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd</w:ResourceURI>
|
|
<a:Action mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command</a:Action>
|
|
<w:SelectorSet>
|
|
<w:Selector Name="ShellId">' . $shell_id . '</w:Selector>
|
|
</w:SelectorSet>
|
|
</env:Header>
|
|
<env:Body>
|
|
<rsp:CommandLine>
|
|
<rsp:Command>' . $command . '</rsp:Command>
|
|
</rsp:CommandLine>
|
|
</env:Body>
|
|
</env:Envelope>';
|
|
}
|
|
|
|
private function get_receive_output_body($shell_id, $command_id)
|
|
{
|
|
// XML body for receiving command output
|
|
return '<?xml version="1.0" encoding="utf-8"?>
|
|
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:b="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:cfg="http://schemas.microsoft.com/wbem/wsman/1/config">
|
|
<env:Header>
|
|
<a:To>http://' . $this->ip . ':53389/wsman</a:To>
|
|
<a:ReplyTo>
|
|
<a:Address mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<w:MaxEnvelopeSize mustUnderstand="true">153600</w:MaxEnvelopeSize>
|
|
<a:MessageID>uuid:' . uniqid() . '</a:MessageID>
|
|
<w:Locale mustUnderstand="false" xml:lang="en-US"/>
|
|
<p:DataLocale mustUnderstand="false" xml:lang="en-US"/>
|
|
<w:OperationTimeout>PT60S</w:OperationTimeout>
|
|
<w:ResourceURI mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd</w:ResourceURI>
|
|
<a:Action mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive</a:Action>
|
|
<w:SelectorSet>
|
|
<w:Selector Name="ShellId">' . $shell_id . '</w:Selector>
|
|
</w:SelectorSet>
|
|
</env:Header>
|
|
<env:Body>
|
|
<rsp:Receive>
|
|
<rsp:DesiredStream CommandId="' . $command_id . '">stdout stderr</rsp:DesiredStream>
|
|
</rsp:Receive>
|
|
</env:Body>
|
|
</env:Envelope>';
|
|
}
|
|
|
|
private function parse_command_output($response, $command_id)
|
|
{
|
|
preg_match_all('/<rsp:Stream Name="stdout" CommandId="' . $command_id . '">(.*?)<\/rsp:Stream>/s', $response, $matches);
|
|
$output = '';
|
|
foreach ($matches[1] as $base64_output) {
|
|
$decoded = base64_decode($base64_output);
|
|
// Normalize line endings to \n
|
|
$decoded = preg_replace('/\r\n|\r/', "\n", $decoded);
|
|
$output .= $decoded;
|
|
}
|
|
return trim($output); // Remove any leading/trailing whitespace
|
|
}
|
|
|
|
private function get_signal_termination_body($shell_id, $command_id)
|
|
{
|
|
// XML body for signaling termination
|
|
return '<?xml version="1.0" encoding="utf-8"?>
|
|
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:b="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:cfg="http://schemas.microsoft.com/wbem/wsman/1/config">
|
|
<env:Header>
|
|
<a:To>http://' . $this->ip . ':53389/wsman</a:To>
|
|
<a:ReplyTo>
|
|
<a:Address mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<w:MaxEnvelopeSize mustUnderstand="true">153600</w:MaxEnvelopeSize>
|
|
<a:MessageID>uuid:' . uniqid() . '</a:MessageID>
|
|
<w:Locale mustUnderstand="false" xml:lang="en-US"/>
|
|
<p:DataLocale mustUnderstand="false" xml:lang="en-US"/>
|
|
<w:OperationTimeout>PT60S</w:OperationTimeout>
|
|
<w:ResourceURI mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd</w:ResourceURI>
|
|
<a:Action mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Signal</a:Action>
|
|
<w:SelectorSet>
|
|
<w:Selector Name="ShellId">' . $shell_id . '</w:Selector>
|
|
</w:SelectorSet>
|
|
</env:Header>
|
|
<env:Body>
|
|
<rsp:Signal CommandId="' . $command_id . '">
|
|
<rsp:Code>http://schemas.microsoft.com/wbem/wsman/1/windows/shell/signal/terminate</rsp:Code>
|
|
</rsp:Signal>
|
|
</env:Body>
|
|
</env:Envelope>';
|
|
}
|
|
|
|
private function get_delete_shell_body($shell_id)
|
|
{
|
|
// XML body for deleting the shell session
|
|
return '<?xml version="1.0" encoding="utf-8"?>
|
|
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:b="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:cfg="http://schemas.microsoft.com/wbem/wsman/1/config">
|
|
<env:Header>
|
|
<a:To>http://' . $this->ip . ':53389/wsman</a:To>
|
|
<a:ReplyTo>
|
|
<a:Address mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<w:MaxEnvelopeSize mustUnderstand="true">153600</w:MaxEnvelopeSize>
|
|
<a:MessageID>uuid:' . uniqid() . '</a:MessageID>
|
|
<w:Locale mustUnderstand="false" xml:lang="en-US"/>
|
|
<p:DataLocale mustUnderstand="false" xml:lang="en-US"/>
|
|
<w:OperationTimeout>PT60S</w:OperationTimeout>
|
|
<w:ResourceURI mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd</w:ResourceURI>
|
|
<a:Action mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action>
|
|
<w:SelectorSet>
|
|
<w:Selector Name="ShellId">' . $shell_id . '</w:Selector>
|
|
</w:SelectorSet>
|
|
</env:Header>
|
|
<env:Body></env:Body>
|
|
</env:Envelope>';
|
|
}
|
|
}
|