-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwinrm_client.py
130 lines (106 loc) · 4.72 KB
/
winrm_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""This class contains the implementation of the WinRM client."""
import logging
import winrm
from base_client import BaseClient
from enums import WindowsCommands, RegistryRootKey
logging.basicConfig(level=logging.INFO)
class WinRMClient(BaseClient):
"""This class serves as an abstraction of a WinRM client.
Note: The commands in this class are tested against Windows 7 Ultimate 6.1.7601 SP 1 Build 7601
so there could be differences with other Windows versions.
"""
def __init__(self, ip_address: str, username: str, password: str):
super().__init__(ip_address=ip_address, username=username, password=password)
self.client = self.log_in()
logging.info('Successfully logged in host %s!', self.ip_address)
def log_in(self) -> winrm.Session:
"""Logs in to the host via WinRM and returns the created winrm.Session object."""
try:
client = winrm.Session(self.ip_address, auth=(self.username, self.password))
except Exception as e:
logging.error('Could not log in host %s!', self.ip_address)
raise e
else:
logging.info('Successfully logged in host %s!', self.ip_address)
return client
def execute_command(self, command: str, is_power_shell: bool = False) -> str:
"""Executes a command against the connected host. Raises an exception if the command
execution was unsuccessful.
Parameters
----------
command : str
A command to execute, i.e. 'ipconfig', 'date/T', 'time/T', etc.
is_power_shell : bool
Determines whether the command is a PowerShell one or not. Defaults to False.
Returns
-------
str
The output of the command as a decoded string.
"""
if not is_power_shell:
response = self.client.run_cmd(command)
else:
response = self.client.run_ps(command)
# If the exit code is not 0, log an error message and raise an exception
if response.status_code:
logging.error(
'The command "%s" was not successful and returned exit code %s!',
command,
response.status_code,
)
raise UserWarning(f'The command "{command}" was not successful!')
logging.info(
'Successful execution of command "%s"!\n Command output: %s',
command,
response.std_out.decode('UTF-8'),
)
return response.std_out.decode('UTF-8')
def reboot(self, immediately: bool = False):
"""Reboots the host.
Parameters
----------
immediately : bool
Set to true in order to trigger a reboot immediately as Windows machines have a
1 minute delay before actually rebooting. Defaults to false.
"""
command = WindowsCommands.REBOOT.value
if immediately:
command += ' -t 0'
self.execute_command(command=command)
logging.info('Successfully rebooted host %s!', self.ip_address)
def shutdown(self, immediately: bool = False):
"""Shutdown the host.
Parameters
----------
immediately : bool
Set to true in order to trigger a shut down immediately as Windows machines have a
1 minute delay before actually shutting down. Defaults to false.
"""
command = WindowsCommands.SHUTDOWN.value
if immediately:
command += ' -t 0'
self.execute_command(command=command)
logging.info('Successfully shut down host %s!', self.ip_address)
def get_windows_defender_parameters(self):
"""Not implemented due to not understanding well what the goal is and not being able to
access Windows Defender from command-line on Windows 7."""
raise NotImplementedError
def get_subkeys_and_entries_for_root_registry_key(self, root_key: RegistryRootKey) -> str:
"""Retrieves and returns the subkeys and entries for a given root registry key.
Parameters
----------
root_key : RegistryRootKey
The root key to query for.
Returns
-------
str
All subkeys and entries for the given root key.
"""
return self.execute_command(WindowsCommands.REGISTER_QUERY.value + f' {root_key.value}')
# Example calls
winrm_client = WinRMClient(ip_address='192.168.100.20', username='Dummy', password='dummy')
ipconfig_output = winrm_client.execute_command('ipconfig')
winrm_client.execute_command('WmiObject Win32_ComputerSystem', is_power_shell=True)
winrm_client.get_subkeys_and_entries_for_root_registry_key(RegistryRootKey.HKEY_LOCAL_MACHINE)
# winrm_client.reboot()
winrm_client.shutdown(immediately=True)