mantis_api_client 5.5.0__py3-none-any.whl
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.
- mantis_api_client/__init__.py +21 -0
- mantis_api_client/cli_parser/account_parser.py +451 -0
- mantis_api_client/cli_parser/attack_parser.py +317 -0
- mantis_api_client/cli_parser/bas_parser.py +1204 -0
- mantis_api_client/cli_parser/basebox_parser.py +258 -0
- mantis_api_client/cli_parser/dataset_parser.py +200 -0
- mantis_api_client/cli_parser/lab_parser.py +805 -0
- mantis_api_client/cli_parser/labs_parser.py +87 -0
- mantis_api_client/cli_parser/log_collector_parser.py +71 -0
- mantis_api_client/cli_parser/redteam_parser.py +375 -0
- mantis_api_client/cli_parser/scenario_parser.py +311 -0
- mantis_api_client/cli_parser/signature_parser.py +147 -0
- mantis_api_client/cli_parser/topology_parser.py +255 -0
- mantis_api_client/cli_parser/user_parser.py +225 -0
- mantis_api_client/config.py +73 -0
- mantis_api_client/dataset_api.py +267 -0
- mantis_api_client/exceptions.py +27 -0
- mantis_api_client/mantis.py +186 -0
- mantis_api_client/oidc.py +302 -0
- mantis_api_client/scenario_api.py +1196 -0
- mantis_api_client/user_api.py +282 -0
- mantis_api_client/utils.py +130 -0
- mantis_api_client-5.5.0.dist-info/AUTHORS +1 -0
- mantis_api_client-5.5.0.dist-info/LICENSE +19 -0
- mantis_api_client-5.5.0.dist-info/METADATA +33 -0
- mantis_api_client-5.5.0.dist-info/RECORD +28 -0
- mantis_api_client-5.5.0.dist-info/WHEEL +4 -0
- mantis_api_client-5.5.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import argparse
|
|
3
|
+
import datetime
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
from mantis_common_model.pagination import Pagination
|
|
11
|
+
from mantis_scenario_model.api_scenario_model import LabListReply
|
|
12
|
+
from mantis_scenario_model.lab_model import Lab
|
|
13
|
+
|
|
14
|
+
import mantis_api_client.scenario_api as scenario_api
|
|
15
|
+
from mantis_api_client import user_api
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# 'labs_handler' handler
|
|
20
|
+
#
|
|
21
|
+
def labs_handler(args: Any) -> None:
|
|
22
|
+
all_labs = args.all_labs
|
|
23
|
+
offset = 100
|
|
24
|
+
labs_to_list: List[Lab] = []
|
|
25
|
+
try:
|
|
26
|
+
page: int = 1
|
|
27
|
+
pagination: Pagination = Pagination(**{"page": page, "limit": offset})
|
|
28
|
+
labs: LabListReply = scenario_api.fetch_labs(
|
|
29
|
+
all_labs=all_labs, pagination=pagination
|
|
30
|
+
)
|
|
31
|
+
labs_to_list = labs_to_list + [Lab(**lab) for lab in labs["data"]]
|
|
32
|
+
while pagination.page * pagination.limit < labs["pagination"]["total_records"]:
|
|
33
|
+
page = page + 1
|
|
34
|
+
pagination = Pagination(**{"page": page, "limit": offset})
|
|
35
|
+
labs = scenario_api.fetch_labs(all_labs=all_labs, pagination=pagination)
|
|
36
|
+
labs_to_list = labs_to_list + [Lab(**lab) for lab in labs["data"]]
|
|
37
|
+
|
|
38
|
+
except Exception as e:
|
|
39
|
+
print(f"Error when fetching labs: '{e}'")
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
|
|
42
|
+
if args.json:
|
|
43
|
+
print(json.dumps(labs))
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
# Maintain a local cache of user_id and user_info, to avoid unecessary calls to Account API
|
|
47
|
+
cache_created_by: Dict[str, Any] = {}
|
|
48
|
+
|
|
49
|
+
print("[+] Available labs:")
|
|
50
|
+
for lab in labs_to_list:
|
|
51
|
+
lab_creation_timestamp = (
|
|
52
|
+
datetime.datetime.fromtimestamp(
|
|
53
|
+
lab.lab_creation_timestamp, datetime.timezone.utc
|
|
54
|
+
).strftime("%Y-%m-%d %H:%M:%S")
|
|
55
|
+
+ " UTC"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if lab.created_by in cache_created_by.keys():
|
|
59
|
+
created_by = cache_created_by[lab.created_by]
|
|
60
|
+
else:
|
|
61
|
+
created_by = user_api.fetch_user(lab.created_by)
|
|
62
|
+
cache_created_by[lab.created_by] = created_by
|
|
63
|
+
|
|
64
|
+
print(f" [+] \033[1mContent\033[0m: {lab.name}")
|
|
65
|
+
print(f" - \033[1mType\033[0m: {lab.content_type.value}")
|
|
66
|
+
print(f" - \033[1mLab ID\033[0m: {lab.runner_id}")
|
|
67
|
+
print(f" - \033[1mCreation time\033[0m: {lab_creation_timestamp}")
|
|
68
|
+
print(
|
|
69
|
+
f" - \033[1mCreated by\033[0m: {created_by['given_name']} {created_by['last_name']} ({lab.created_by})"
|
|
70
|
+
)
|
|
71
|
+
print(f" - \033[1mStatus\033[0m: {lab.status.value}")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def add_labs_parser(root_parser: argparse.ArgumentParser, subparsers: Any) -> None:
|
|
75
|
+
# Subparser labs
|
|
76
|
+
parser_labs = subparsers.add_parser(
|
|
77
|
+
"labs", help="List current labs", formatter_class=root_parser.formatter_class
|
|
78
|
+
)
|
|
79
|
+
parser_labs.set_defaults(func=labs_handler)
|
|
80
|
+
parser_labs.add_argument(
|
|
81
|
+
"-a",
|
|
82
|
+
"--all",
|
|
83
|
+
action="store_true",
|
|
84
|
+
dest="all_labs",
|
|
85
|
+
help="Include stopped labs",
|
|
86
|
+
)
|
|
87
|
+
parser_labs.add_argument("--json", help="Return JSON result.", action="store_true")
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic.json import pydantic_encoder
|
|
8
|
+
|
|
9
|
+
from mantis_api_client import scenario_api
|
|
10
|
+
from mantis_api_client.utils import colored
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# 'log_collector_list_handler' handler
|
|
15
|
+
#
|
|
16
|
+
def log_collector_list_handler(args: Any) -> None:
|
|
17
|
+
try:
|
|
18
|
+
|
|
19
|
+
log_collectors = scenario_api.get_log_collectors()
|
|
20
|
+
log_collectors = sorted(log_collectors, key=lambda k: (k["collector_name"]))
|
|
21
|
+
|
|
22
|
+
if args.json:
|
|
23
|
+
print(json.dumps(log_collectors, default=pydantic_encoder))
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
print("[+] Available Logs collectors:")
|
|
27
|
+
for lg in log_collectors:
|
|
28
|
+
print(f" [+] \033[1mName\033[0m: {lg['collector_name']}")
|
|
29
|
+
print(f" [+] \033[1mType\033[0m: {lg['collector_type']}")
|
|
30
|
+
print(f" [+] \033[1mDescription\033[0m: {lg['description']}")
|
|
31
|
+
cpes = lg["cpe_os_constraints"]
|
|
32
|
+
if len(cpes) > 0:
|
|
33
|
+
print(" [+] \033[1mCPE OS constraints\033[0m:")
|
|
34
|
+
for cpe in cpes:
|
|
35
|
+
print(f" [+] {cpe}")
|
|
36
|
+
print()
|
|
37
|
+
|
|
38
|
+
except Exception as e:
|
|
39
|
+
print(
|
|
40
|
+
colored(
|
|
41
|
+
f"Error when fetching log collectors data: '{e}'", "red", "on_white"
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
sys.exit(1)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def add_log_collector_parser(root_parser: argparse.ArgumentParser, subparsers: Any):
|
|
48
|
+
|
|
49
|
+
# --------------------
|
|
50
|
+
# --- Scenario API options (log_collector)
|
|
51
|
+
# --------------------
|
|
52
|
+
|
|
53
|
+
parser_log_collector = subparsers.add_parser(
|
|
54
|
+
"log_collector",
|
|
55
|
+
help="Scenario API related commands (log_collector)",
|
|
56
|
+
formatter_class=root_parser.formatter_class,
|
|
57
|
+
)
|
|
58
|
+
subparsers_log_collector = parser_log_collector.add_subparsers()
|
|
59
|
+
|
|
60
|
+
# 'log_collector_list' command
|
|
61
|
+
parser_log_collector_list = subparsers_log_collector.add_parser(
|
|
62
|
+
"list",
|
|
63
|
+
help="List log collectors configuration information",
|
|
64
|
+
formatter_class=root_parser.formatter_class,
|
|
65
|
+
)
|
|
66
|
+
parser_log_collector_list.set_defaults(func=log_collector_list_handler)
|
|
67
|
+
parser_log_collector_list.add_argument(
|
|
68
|
+
"--json", help="Return JSON result.", action="store_true"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
parser_log_collector.set_defaults(func=lambda _: parser_log_collector.print_help())
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
from colorama import Fore
|
|
11
|
+
from colorama import Style
|
|
12
|
+
|
|
13
|
+
from cr_api_client import redteam_api # type: ignore[attr-defined]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def select_attack_session() -> Dict:
|
|
17
|
+
|
|
18
|
+
attack_sessions = redteam_api.attack_sessions()
|
|
19
|
+
print("Choose one attack session in list:")
|
|
20
|
+
|
|
21
|
+
list_sessions(attack_sessions)
|
|
22
|
+
|
|
23
|
+
id_session = input("Select attack session index: ")
|
|
24
|
+
try:
|
|
25
|
+
attack_session = attack_sessions[int(id_session)]
|
|
26
|
+
except Exception as e:
|
|
27
|
+
print(f"Error when fetching command: '{e}'")
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
|
|
30
|
+
return attack_session
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def list_sessions(attack_sessions: List[Dict]) -> None:
|
|
34
|
+
i = 0
|
|
35
|
+
for a_s in attack_sessions:
|
|
36
|
+
|
|
37
|
+
# Check attack session link
|
|
38
|
+
if a_s.get("is_up", False):
|
|
39
|
+
connected = "UP"
|
|
40
|
+
else:
|
|
41
|
+
connected = "DOWN"
|
|
42
|
+
|
|
43
|
+
if a_s["privilege_level"] == 0:
|
|
44
|
+
privilege = "user"
|
|
45
|
+
elif a_s["privilege_level"] == 1:
|
|
46
|
+
privilege = "user UAC"
|
|
47
|
+
else:
|
|
48
|
+
privilege = "administrator"
|
|
49
|
+
print(
|
|
50
|
+
f""" [{connected}] {i} : {a_s["identifier"]}, {a_s["username"]} (privilege {privilege}) on {a_s["target"]["host"]["hostname"]} ({a_s["target"]["ip"]})"""
|
|
51
|
+
)
|
|
52
|
+
i = i + 1
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def redteam_session_list_handler(args: Any) -> None:
|
|
56
|
+
sessions = redteam_api.attack_sessions()
|
|
57
|
+
list_sessions(sessions)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def redteam_command_history_handler(args: Any) -> None:
|
|
61
|
+
show_output = args.show_output
|
|
62
|
+
|
|
63
|
+
commands = redteam_api.get_commands()
|
|
64
|
+
|
|
65
|
+
for command in commands:
|
|
66
|
+
print(f"""[+] {command["id"]} ({command["status"]}): '{command["command"]}'""")
|
|
67
|
+
|
|
68
|
+
if show_output:
|
|
69
|
+
print(command["output"])
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def redteam_command_get_handler(args: Any) -> None:
|
|
73
|
+
command_id = args.command_id
|
|
74
|
+
show_output = args.show_output
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
command = redteam_api.get_command(command_id=command_id)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(f"Error when fetching command: '{e}'")
|
|
80
|
+
sys.exit(1)
|
|
81
|
+
|
|
82
|
+
print(f"""[+] {command["id"]}: '{command["command"]}'""")
|
|
83
|
+
|
|
84
|
+
if show_output:
|
|
85
|
+
print(command["output"])
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def redteam_command_execute_handler(args: Any) -> None:
|
|
89
|
+
|
|
90
|
+
if args.session_id is None:
|
|
91
|
+
attack_session = select_attack_session()
|
|
92
|
+
else:
|
|
93
|
+
attack_session = {}
|
|
94
|
+
attack_session["identifier"] = args.session_id
|
|
95
|
+
|
|
96
|
+
if args.command is None:
|
|
97
|
+
command = input("Command to execute (one line): ")
|
|
98
|
+
else:
|
|
99
|
+
command = args.command
|
|
100
|
+
|
|
101
|
+
if args.background is None:
|
|
102
|
+
background_input = (
|
|
103
|
+
input("Command need to be executed in background, y or n ? (n by default) ")
|
|
104
|
+
or "n"
|
|
105
|
+
)
|
|
106
|
+
if background_input not in ["y", "n"]:
|
|
107
|
+
print("You need to answer y or n.")
|
|
108
|
+
sys.exit(1)
|
|
109
|
+
|
|
110
|
+
if "y" in background_input:
|
|
111
|
+
background = True
|
|
112
|
+
else:
|
|
113
|
+
background = False
|
|
114
|
+
else:
|
|
115
|
+
if args.background.lower() == "true":
|
|
116
|
+
background = True
|
|
117
|
+
elif args.background.lower() == "false":
|
|
118
|
+
background = False
|
|
119
|
+
else:
|
|
120
|
+
print("Background argument is boolean (true or false)")
|
|
121
|
+
sys.exit(1)
|
|
122
|
+
|
|
123
|
+
if args.timeout is None:
|
|
124
|
+
max_time = (
|
|
125
|
+
input("Max waiting time for command result in seconds ? (60 by default) ")
|
|
126
|
+
or 60
|
|
127
|
+
)
|
|
128
|
+
try:
|
|
129
|
+
max_time = int(max_time)
|
|
130
|
+
except ValueError:
|
|
131
|
+
print("Error max waiting time is not an integer.")
|
|
132
|
+
sys.exit(1)
|
|
133
|
+
else:
|
|
134
|
+
try:
|
|
135
|
+
max_time = int(args.timeout)
|
|
136
|
+
except ValueError:
|
|
137
|
+
print("Timeout argument must be an integer.")
|
|
138
|
+
sys.exit(1)
|
|
139
|
+
|
|
140
|
+
manage_command(
|
|
141
|
+
command=command,
|
|
142
|
+
attack_session_identifier=attack_session["identifier"],
|
|
143
|
+
background=background,
|
|
144
|
+
max_time=max_time,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def redteam_shell_handler(args: Any) -> None:
|
|
149
|
+
|
|
150
|
+
print(f"{Style.BRIGHT}M{Fore.RED}&{Fore.RESET}NTIS SHELL{Style.NORMAL}")
|
|
151
|
+
|
|
152
|
+
attack_session = select_attack_session()
|
|
153
|
+
|
|
154
|
+
max_time = (
|
|
155
|
+
input("Max waiting time for command result in secondes ? (60 by default)") or 60
|
|
156
|
+
)
|
|
157
|
+
try:
|
|
158
|
+
max_time = int(max_time)
|
|
159
|
+
except ValueError:
|
|
160
|
+
print("Error max waiting time is not an integer.")
|
|
161
|
+
sys.exit(1)
|
|
162
|
+
|
|
163
|
+
stop = False
|
|
164
|
+
|
|
165
|
+
while not stop:
|
|
166
|
+
command = input("> ")
|
|
167
|
+
if command == "exit":
|
|
168
|
+
stop = True
|
|
169
|
+
break
|
|
170
|
+
manage_command(
|
|
171
|
+
command=command,
|
|
172
|
+
attack_session_identifier=attack_session["identifier"],
|
|
173
|
+
background=False,
|
|
174
|
+
max_time=max_time,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def manage_command(
|
|
179
|
+
command: str, attack_session_identifier: str, background: bool, max_time: int
|
|
180
|
+
) -> None:
|
|
181
|
+
result, output = redteam_api.execute_command(
|
|
182
|
+
command, attack_session_identifier, background=background
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
id_command = output["idResultCommand"]
|
|
186
|
+
|
|
187
|
+
output = None
|
|
188
|
+
i = 0
|
|
189
|
+
|
|
190
|
+
while i < max_time:
|
|
191
|
+
result = redteam_api.get_command(id_command)
|
|
192
|
+
if result.get("output", "") != "":
|
|
193
|
+
output = result["output"]
|
|
194
|
+
break
|
|
195
|
+
time.sleep(1)
|
|
196
|
+
i = i + 1
|
|
197
|
+
|
|
198
|
+
if not output:
|
|
199
|
+
print(f"""Command timeout (more than {max_time} seconds)""")
|
|
200
|
+
print(output)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def redteam_upload_handler(args: Any) -> None:
|
|
204
|
+
|
|
205
|
+
attack_session = select_attack_session()
|
|
206
|
+
|
|
207
|
+
path = input("Local path for the file : ")
|
|
208
|
+
filename = Path(path).name
|
|
209
|
+
|
|
210
|
+
success = redteam_api.upload_file(
|
|
211
|
+
filepath=path, attack_session_identifier=attack_session["identifier"]
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
if success:
|
|
215
|
+
if attack_session["type"] == "powershell":
|
|
216
|
+
upload_path = f"""C:\\Users\\{attack_session["username"]}\\AppData\\Local\\Temp\\{filename}"""
|
|
217
|
+
else:
|
|
218
|
+
upload_path = f"""/tmp/{filename}"""
|
|
219
|
+
|
|
220
|
+
print(f"File upload successfully on {upload_path}")
|
|
221
|
+
else:
|
|
222
|
+
print("Upload failed.")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def redteam_atomic_handler(args: Any):
|
|
226
|
+
filepath = args.atr_file # Atomic Red Team file
|
|
227
|
+
session_id = args.session_id
|
|
228
|
+
|
|
229
|
+
if not Path(filepath).exists():
|
|
230
|
+
print(f"File {filepath} doesn't exist")
|
|
231
|
+
sys.exit(1)
|
|
232
|
+
|
|
233
|
+
success = redteam_api.execute_atomic(filepath=filepath, attack_session_identifier=session_id)
|
|
234
|
+
if success:
|
|
235
|
+
print("[+] Execution started")
|
|
236
|
+
else:
|
|
237
|
+
print("Error in script execution")
|
|
238
|
+
sys.exit(1)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def add_redteam_parser(root_parser: argparse.ArgumentParser, subparsers: Any) -> None:
|
|
242
|
+
# Subparser redteam
|
|
243
|
+
parser_redteam = subparsers.add_parser(
|
|
244
|
+
"redteam",
|
|
245
|
+
help="Redteam actions in running labs",
|
|
246
|
+
formatter_class=root_parser.formatter_class,
|
|
247
|
+
)
|
|
248
|
+
subparsers_redteam = parser_redteam.add_subparsers()
|
|
249
|
+
parser_redteam.set_defaults(func=lambda _: parser_redteam.print_help())
|
|
250
|
+
|
|
251
|
+
# Redteam command parser
|
|
252
|
+
parser_redteam_script = subparsers_redteam.add_parser(
|
|
253
|
+
name="atomic",
|
|
254
|
+
help="Execute atomic test on redteam session",
|
|
255
|
+
formatter_class=root_parser.formatter_class,
|
|
256
|
+
)
|
|
257
|
+
parser_redteam_script.set_defaults(func=redteam_atomic_handler)
|
|
258
|
+
parser_redteam_script.add_argument(
|
|
259
|
+
"--session_id",
|
|
260
|
+
"-s",
|
|
261
|
+
help="Attack session identifier",
|
|
262
|
+
required=True,
|
|
263
|
+
)
|
|
264
|
+
parser_redteam_script.add_argument(
|
|
265
|
+
"--atr_file",
|
|
266
|
+
"-f",
|
|
267
|
+
type=str,
|
|
268
|
+
help="Import and execute an ATR (Atomic Red Team) file containing commands",
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
# Redteam session parser
|
|
272
|
+
parser_redteam_session = subparsers_redteam.add_parser(
|
|
273
|
+
name="session",
|
|
274
|
+
help="Redteam session information",
|
|
275
|
+
formatter_class=root_parser.formatter_class,
|
|
276
|
+
)
|
|
277
|
+
subparsers_session = parser_redteam_session.add_subparsers()
|
|
278
|
+
parser_redteam_session_list = subparsers_session.add_parser(
|
|
279
|
+
"list",
|
|
280
|
+
help="List all redteam sessions.",
|
|
281
|
+
formatter_class=root_parser.formatter_class,
|
|
282
|
+
)
|
|
283
|
+
parser_redteam_session_list.set_defaults(func=redteam_session_list_handler)
|
|
284
|
+
parser_redteam_session.set_defaults(
|
|
285
|
+
func=lambda _: parser_redteam_session.print_help()
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Redteam command parser
|
|
289
|
+
parser_redteam_command = subparsers_redteam.add_parser(
|
|
290
|
+
name="command",
|
|
291
|
+
help="Custom command execution on redteam session",
|
|
292
|
+
formatter_class=root_parser.formatter_class,
|
|
293
|
+
)
|
|
294
|
+
subparsers_command = parser_redteam_command.add_subparsers()
|
|
295
|
+
parser_redteam_command.set_defaults(
|
|
296
|
+
func=lambda _: parser_redteam_command.print_help()
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
parser_redteam_command_history = subparsers_command.add_parser(
|
|
300
|
+
"history",
|
|
301
|
+
help="Custom command execution history",
|
|
302
|
+
formatter_class=root_parser.formatter_class,
|
|
303
|
+
)
|
|
304
|
+
parser_redteam_command_history.add_argument(
|
|
305
|
+
"--show_output",
|
|
306
|
+
"-o",
|
|
307
|
+
help="Display attack output (can result in lengthy output)",
|
|
308
|
+
action="store_true",
|
|
309
|
+
)
|
|
310
|
+
parser_redteam_command_history.set_defaults(func=redteam_command_history_handler)
|
|
311
|
+
|
|
312
|
+
parser_redteam_command_get = subparsers_command.add_parser(
|
|
313
|
+
"get",
|
|
314
|
+
help="Get information regarding a specific command",
|
|
315
|
+
formatter_class=root_parser.formatter_class,
|
|
316
|
+
)
|
|
317
|
+
parser_redteam_command_get.set_defaults(func=redteam_command_get_handler)
|
|
318
|
+
parser_redteam_command_get.add_argument(
|
|
319
|
+
"--command_id",
|
|
320
|
+
"-i",
|
|
321
|
+
help="The command id",
|
|
322
|
+
type=str,
|
|
323
|
+
required=True,
|
|
324
|
+
)
|
|
325
|
+
parser_redteam_command_get.add_argument(
|
|
326
|
+
"--show_output",
|
|
327
|
+
"-o",
|
|
328
|
+
help="Display attack output (can result in lengthy output)",
|
|
329
|
+
action="store_true",
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
parser_redteam_command_execute = subparsers_command.add_parser(
|
|
333
|
+
"execute",
|
|
334
|
+
help="Execute command on attack session",
|
|
335
|
+
formatter_class=root_parser.formatter_class,
|
|
336
|
+
)
|
|
337
|
+
parser_redteam_command_execute.add_argument(
|
|
338
|
+
"--background",
|
|
339
|
+
"-b",
|
|
340
|
+
help="Execute command in background or not (Invoke-WmiMethod on Windows and & on Linux.)",
|
|
341
|
+
default=None,
|
|
342
|
+
)
|
|
343
|
+
parser_redteam_command_execute.add_argument(
|
|
344
|
+
"--timeout",
|
|
345
|
+
"-t",
|
|
346
|
+
help="Maximum time (seconds) to wait result command before timeout",
|
|
347
|
+
default=None,
|
|
348
|
+
)
|
|
349
|
+
parser_redteam_command_execute.add_argument(
|
|
350
|
+
"--session_id",
|
|
351
|
+
"-id",
|
|
352
|
+
help="Attack session identifier",
|
|
353
|
+
default=None,
|
|
354
|
+
)
|
|
355
|
+
parser_redteam_command_execute.add_argument(
|
|
356
|
+
"--command",
|
|
357
|
+
"-c",
|
|
358
|
+
help="Command to execute, must be surrounded by quotation marks",
|
|
359
|
+
default=None,
|
|
360
|
+
)
|
|
361
|
+
parser_redteam_command_execute.set_defaults(func=redteam_command_execute_handler)
|
|
362
|
+
|
|
363
|
+
parser_redteam_upload = subparsers_redteam.add_parser(
|
|
364
|
+
"upload",
|
|
365
|
+
help="Upload a file on target with attack session",
|
|
366
|
+
formatter_class=root_parser.formatter_class,
|
|
367
|
+
)
|
|
368
|
+
parser_redteam_upload.set_defaults(func=redteam_upload_handler)
|
|
369
|
+
|
|
370
|
+
parser_redteam_shell = subparsers_redteam.add_parser(
|
|
371
|
+
"shell",
|
|
372
|
+
help="Redteam shell on attack session",
|
|
373
|
+
formatter_class=root_parser.formatter_class,
|
|
374
|
+
)
|
|
375
|
+
parser_redteam_shell.set_defaults(func=redteam_shell_handler)
|