evil-winrm-py 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aditya Telange
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.4
2
+ Name: evil-winrm-py
3
+ Version: 0.0.1
4
+ Summary: Rewrite of popular tool evil-winrm in python
5
+ Home-page: https://github.com/adityatelange/evil-winrm-py
6
+ Download-URL: https://github.com/adityatelange/evil-winrm-py/archive/v0.0.1.zip
7
+ Author: adityatelange
8
+ License: MIT
9
+ Classifier: Topic :: Security
10
+ Classifier: Operating System :: Unix
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: certifi==2025.1.31
17
+ Requires-Dist: cffi==1.17.1
18
+ Requires-Dist: charset-normalizer==3.4.1
19
+ Requires-Dist: cryptography==44.0.2
20
+ Requires-Dist: idna==3.10
21
+ Requires-Dist: pycparser==2.22
22
+ Requires-Dist: pypsrp==0.8.1
23
+ Requires-Dist: pyspnego==0.11.2
24
+ Requires-Dist: requests==2.32.3
25
+ Requires-Dist: setuptools==78.1.0
26
+ Requires-Dist: urllib3==2.4.0
27
+ Dynamic: author
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: download-url
32
+ Dynamic: home-page
33
+ Dynamic: license
34
+ Dynamic: license-file
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # evil-winrm-py
40
+
41
+ Rewrite of popular tool evil-winrm in python
42
+
43
+ ![](assets/terminal.png)
44
+
45
+ ## Motivation
46
+
47
+ The original evil-winrm is written in Ruby, which can be a hurdle for some users. Rewriting it in Python makes it more accessible and easier to use, while also allowing us to leverage Python’s rich ecosystem for added features and flexibility.
48
+
49
+ I also wanted to learn more about winrm and its internals, so this project will also serve as a learning experience for me.
50
+
51
+ ## Installation (on Linux)
52
+
53
+ ```bash
54
+ git clone https://github.com/adityatelange/evil-winrm-py
55
+ cd evil-winrm-py
56
+ pipx install .
57
+ ```
58
+
59
+ ## Features
60
+
61
+ - Run commands on remote Windows machines.
62
+ - Upload and download files.
63
+
64
+
65
+ ## Usage
66
+
67
+ ```bash
68
+ usage: evil-winrm-py [-h] -i IP -u USER [-p PASSWORD] [--port PORT] [--version]
69
+
70
+ options:
71
+ -h, --help show this help message and exit
72
+ -i IP, --ip IP remote host IP or hostname
73
+ -u USER, --user USER username
74
+ -p PASSWORD, --password PASSWORD
75
+ password
76
+ --port PORT remote host port (default 5985)
77
+ --version show version
78
+ ```
@@ -0,0 +1,40 @@
1
+ # evil-winrm-py
2
+
3
+ Rewrite of popular tool evil-winrm in python
4
+
5
+ ![](assets/terminal.png)
6
+
7
+ ## Motivation
8
+
9
+ The original evil-winrm is written in Ruby, which can be a hurdle for some users. Rewriting it in Python makes it more accessible and easier to use, while also allowing us to leverage Python’s rich ecosystem for added features and flexibility.
10
+
11
+ I also wanted to learn more about winrm and its internals, so this project will also serve as a learning experience for me.
12
+
13
+ ## Installation (on Linux)
14
+
15
+ ```bash
16
+ git clone https://github.com/adityatelange/evil-winrm-py
17
+ cd evil-winrm-py
18
+ pipx install .
19
+ ```
20
+
21
+ ## Features
22
+
23
+ - Run commands on remote Windows machines.
24
+ - Upload and download files.
25
+
26
+
27
+ ## Usage
28
+
29
+ ```bash
30
+ usage: evil-winrm-py [-h] -i IP -u USER [-p PASSWORD] [--port PORT] [--version]
31
+
32
+ options:
33
+ -h, --help show this help message and exit
34
+ -i IP, --ip IP remote host IP or hostname
35
+ -u USER, --user USER username
36
+ -p PASSWORD, --password PASSWORD
37
+ password
38
+ --port PORT remote host port (default 5985)
39
+ --version show version
40
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "0.0.1"
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import argparse
4
+ import logging
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ import pypsrp
9
+ import pypsrp.client
10
+
11
+ from evil_winrm_py import __version__
12
+
13
+ # --- Logging Setup ---
14
+ full_logging_path = Path.cwd().joinpath("evil_winrm_py.log")
15
+ log = logging.getLogger(__name__)
16
+ logging.basicConfig(
17
+ level=logging.INFO,
18
+ format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
19
+ filename=full_logging_path,
20
+ )
21
+
22
+
23
+ # --- Helper Functions ---
24
+ def get_prompt(client: pypsrp.client.Client):
25
+ try:
26
+ output, streams, had_errors = client.execute_ps(
27
+ "$pwd.Path"
28
+ ) # Get current working directory
29
+ if not had_errors:
30
+ return f"PS {output}> "
31
+ except Exception as e:
32
+ log.error("Error in interactive shell loop: {}".format(e))
33
+ return "PS ?> " # Fallback prompt
34
+
35
+
36
+ def upload_file(client: pypsrp.client.Client, local_path: str, remote_path: str):
37
+ """Uploads a file to the remote host."""
38
+ print(local_path)
39
+ if not Path(local_path).is_file():
40
+ log.error("Local file not found: {}".format(local_path))
41
+ return
42
+
43
+ file_name = local_path.split("/")[-1]
44
+
45
+ if remote_path == ".":
46
+ remote_path = file_name
47
+
48
+ log.info("Uploading '{}' to '{}'".format(local_path, remote_path))
49
+ try:
50
+ client.copy(src=local_path, dest=remote_path)
51
+ log.info("Upload completed.")
52
+ except Exception as e:
53
+ log.error("Upload failed: {}".format(e))
54
+
55
+
56
+ def download_file(client: pypsrp.client.Client, remote_path: str, local_path: str):
57
+ """Downloads a file from the remote host."""
58
+ file_name = remote_path.split("\\")[-1]
59
+
60
+ if local_path == ".":
61
+ local_path = Path.cwd().joinpath(file_name)
62
+ elif Path(local_path).is_dir():
63
+ local_path = Path(local_path).joinpath(file_name)
64
+
65
+ log.info("Downloading '{}' to '{}'".format(remote_path, local_path))
66
+ try:
67
+ client.fetch(src=remote_path, dest=local_path)
68
+ log.info("Download completed.")
69
+ except Exception as e:
70
+ log.error("Download failed: {e}".format(e))
71
+
72
+
73
+ def show_menu():
74
+ """Displays the help menu for interactive commands."""
75
+ print("[+] upload /path/to/local/file C:\\path\\to\\remote\\file\t- Upload a file")
76
+ print(
77
+ "[+] download C:\\path\\to\\remote\\file /path/to/local/file\t- Download a file"
78
+ )
79
+ print("[+] menu\t\t\t\t\t\t- Show this menu")
80
+ print("[+] exit\t\t\t\t\t\t- Exit the shell")
81
+ print("Note: Use absolute paths for upload/download for reliability.\n")
82
+
83
+
84
+ def interactive_shell(client: pypsrp.client.Client):
85
+ """Runs the interactive pseudo-shell."""
86
+ log.info("Starting interactive PowerShell session...")
87
+ while True:
88
+ try:
89
+ prompt_text = get_prompt(client)
90
+ cmd_input = input(prompt_text).strip() # Get user input
91
+
92
+ if not cmd_input:
93
+ continue
94
+
95
+ # Check for exit command
96
+ if cmd_input.lower() == "exit":
97
+ break
98
+ elif cmd_input.lower() == "menu":
99
+ show_menu()
100
+ continue
101
+ elif cmd_input.lower().startswith("download"):
102
+ parts = cmd_input.split(maxsplit=2)
103
+ if len(parts) == 3:
104
+ remote_path = parts[1]
105
+ local_path = parts[2]
106
+ download_file(client, remote_path, local_path)
107
+ else:
108
+ print(
109
+ "Usage: download C:\\path\\to\\remote\\file /path/to/local/file"
110
+ )
111
+ continue # Go to next cmd_input
112
+ elif cmd_input.lower().startswith("upload"):
113
+ parts = cmd_input.split(maxsplit=2)
114
+ if len(parts) == 3:
115
+ local_path = parts[1]
116
+ remote_path = parts[2]
117
+ upload_file(client, local_path, remote_path)
118
+ else:
119
+ print(
120
+ "Usage: upload /path/to/local/file C:\\path\\to\\remote\\file"
121
+ )
122
+ continue # Go to next cmd_input
123
+
124
+ # Otherwise, execute the command
125
+ output, streams, had_errors = client.execute_ps(cmd_input)
126
+ if had_errors:
127
+ print("ERROR: {}".format(output))
128
+ else:
129
+ print(output)
130
+ except KeyboardInterrupt:
131
+ print("\nCaught Ctrl+C. Type 'exit' to quit.")
132
+ continue # Allow user to continue or type exit
133
+ except EOFError:
134
+ print("\nEOF received, exiting.")
135
+ break # Exit on Ctrl+D
136
+ except Exception as e:
137
+ print(f"Error in interactive shell loop: {e}")
138
+ # Decide whether to break or continue
139
+ break
140
+
141
+
142
+ # --- Main Function ---
143
+ def main():
144
+ log.info(
145
+ "--- Evil-WinRM-Py v{} started ---".format(__version__)
146
+ ) # Log the start of the program
147
+ print(
148
+ """ ▘▜ ▘
149
+ █▌▌▌▌▐ ▄▖▌▌▌▌▛▌▛▘▛▛▌▄▖▛▌▌▌
150
+ ▙▖▚▘▌▐▖ ▚▚▘▌▌▌▌ ▌▌▌ ▙▌▙▌
151
+ ▌ ▄▌ v{}""".format(
152
+ __version__
153
+ )
154
+ ) # Print the banner
155
+ parser = argparse.ArgumentParser()
156
+
157
+ parser.add_argument(
158
+ "-i",
159
+ "--ip",
160
+ required=True,
161
+ help="remote host IP or hostname",
162
+ )
163
+ parser.add_argument("-u", "--user", required=True, help="username")
164
+ parser.add_argument("-p", "--password", help="password")
165
+ parser.add_argument(
166
+ "--port", type=int, default=5985, help="remote host port (default 5985)"
167
+ )
168
+ parser.add_argument(
169
+ "--version", action="version", version=__version__, help="show version"
170
+ )
171
+
172
+ args = parser.parse_args()
173
+
174
+ # --- Initialize WinRM Session ---
175
+ try:
176
+ log.info("Connecting to {}:{} as {}".format(args.ip, args.port, args.user))
177
+ # Create a client instance
178
+ client = pypsrp.client.Client(
179
+ server=args.ip,
180
+ port=args.port,
181
+ auth="ntlm",
182
+ username=args.user,
183
+ password=args.password,
184
+ ssl=False,
185
+ cert_validation=False,
186
+ )
187
+
188
+ # run the interactive shell
189
+ interactive_shell(client)
190
+ except Exception as e:
191
+ log.exception("An unexpected error occurred: {}".format(e))
192
+ sys.exit(1)
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.4
2
+ Name: evil-winrm-py
3
+ Version: 0.0.1
4
+ Summary: Rewrite of popular tool evil-winrm in python
5
+ Home-page: https://github.com/adityatelange/evil-winrm-py
6
+ Download-URL: https://github.com/adityatelange/evil-winrm-py/archive/v0.0.1.zip
7
+ Author: adityatelange
8
+ License: MIT
9
+ Classifier: Topic :: Security
10
+ Classifier: Operating System :: Unix
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: certifi==2025.1.31
17
+ Requires-Dist: cffi==1.17.1
18
+ Requires-Dist: charset-normalizer==3.4.1
19
+ Requires-Dist: cryptography==44.0.2
20
+ Requires-Dist: idna==3.10
21
+ Requires-Dist: pycparser==2.22
22
+ Requires-Dist: pypsrp==0.8.1
23
+ Requires-Dist: pyspnego==0.11.2
24
+ Requires-Dist: requests==2.32.3
25
+ Requires-Dist: setuptools==78.1.0
26
+ Requires-Dist: urllib3==2.4.0
27
+ Dynamic: author
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: download-url
32
+ Dynamic: home-page
33
+ Dynamic: license
34
+ Dynamic: license-file
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # evil-winrm-py
40
+
41
+ Rewrite of popular tool evil-winrm in python
42
+
43
+ ![](assets/terminal.png)
44
+
45
+ ## Motivation
46
+
47
+ The original evil-winrm is written in Ruby, which can be a hurdle for some users. Rewriting it in Python makes it more accessible and easier to use, while also allowing us to leverage Python’s rich ecosystem for added features and flexibility.
48
+
49
+ I also wanted to learn more about winrm and its internals, so this project will also serve as a learning experience for me.
50
+
51
+ ## Installation (on Linux)
52
+
53
+ ```bash
54
+ git clone https://github.com/adityatelange/evil-winrm-py
55
+ cd evil-winrm-py
56
+ pipx install .
57
+ ```
58
+
59
+ ## Features
60
+
61
+ - Run commands on remote Windows machines.
62
+ - Upload and download files.
63
+
64
+
65
+ ## Usage
66
+
67
+ ```bash
68
+ usage: evil-winrm-py [-h] -i IP -u USER [-p PASSWORD] [--port PORT] [--version]
69
+
70
+ options:
71
+ -h, --help show this help message and exit
72
+ -i IP, --ip IP remote host IP or hostname
73
+ -u USER, --user USER username
74
+ -p PASSWORD, --password PASSWORD
75
+ password
76
+ --port PORT remote host port (default 5985)
77
+ --version show version
78
+ ```
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ evil_winrm_py/__init__.py
5
+ evil_winrm_py/evil_winrm_py.py
6
+ evil_winrm_py.egg-info/PKG-INFO
7
+ evil_winrm_py.egg-info/SOURCES.txt
8
+ evil_winrm_py.egg-info/dependency_links.txt
9
+ evil_winrm_py.egg-info/entry_points.txt
10
+ evil_winrm_py.egg-info/requires.txt
11
+ evil_winrm_py.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ evil-winrm-py = evil_winrm_py.evil_winrm_py:main
@@ -0,0 +1,11 @@
1
+ certifi==2025.1.31
2
+ cffi==1.17.1
3
+ charset-normalizer==3.4.1
4
+ cryptography==44.0.2
5
+ idna==3.10
6
+ pycparser==2.22
7
+ pypsrp==0.8.1
8
+ pyspnego==0.11.2
9
+ requests==2.32.3
10
+ setuptools==78.1.0
11
+ urllib3==2.4.0
@@ -0,0 +1 @@
1
+ evil_winrm_py
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,45 @@
1
+ import io
2
+ from os import path
3
+
4
+ from setuptools import find_packages, setup
5
+
6
+ pwd = path.abspath(path.dirname(__file__))
7
+ with io.open(path.join(pwd, "README.md"), encoding="utf-8") as readme:
8
+ desc = readme.read()
9
+
10
+ setup(
11
+ name="evil-winrm-py",
12
+ version=__import__("evil_winrm_py").__version__,
13
+ description="Rewrite of popular tool evil-winrm in python",
14
+ long_description=desc,
15
+ long_description_content_type="text/markdown",
16
+ author="adityatelange",
17
+ license="MIT",
18
+ url="https://github.com/adityatelange/evil-winrm-py",
19
+ download_url="https://github.com/adityatelange/evil-winrm-py/archive/v%s.zip"
20
+ % __import__("evil_winrm_py").__version__,
21
+ packages=find_packages(),
22
+ classifiers=[
23
+ "Topic :: Security",
24
+ "Operating System :: Unix",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Programming Language :: Python :: 3",
27
+ ],
28
+ install_requires=[
29
+ "certifi==2025.1.31",
30
+ "cffi==1.17.1",
31
+ "charset-normalizer==3.4.1",
32
+ "cryptography==44.0.2",
33
+ "idna==3.10",
34
+ "pycparser==2.22",
35
+ "pypsrp==0.8.1",
36
+ "pyspnego==0.11.2",
37
+ "requests==2.32.3",
38
+ "setuptools==78.1.0",
39
+ "urllib3==2.4.0",
40
+ ],
41
+ python_requires=">=3.6",
42
+ entry_points={
43
+ "console_scripts": ["evil-winrm-py = evil_winrm_py.evil_winrm_py:main"]
44
+ },
45
+ )