Skip to content

Commit c9eb353

Browse files
committed
0.13.0 version
1 parent ea9b0a8 commit c9eb353

7 files changed

Lines changed: 230 additions & 9 deletions

File tree

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
setup(
33
name = 'tuoni',
44
packages = ['tuoni'],
5-
version = '0.11.1-1',
5+
version = '0.13.0',
66
license='MIT',
77
description = 'Library to interact with Tuoni C2 API',
88
author = 'Shelldot',
99
author_email = 'info@shelldot.com',
1010
url = 'https://github.com/shell-dot/tuoni-pip',
11-
download_url = 'https://github.com/shell-dot/tuoni-pip/archive/refs/tags/v_11_1-1.tar.gz',
11+
download_url = 'https://github.com/shell-dot/tuoni-pip/archive/refs/tags/v_13_0.tar.gz',
1212
keywords = ['tuoni'],
1313
install_requires=['requests'],
1414
classifiers=[

tuoni/TuoniAgent.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,11 @@ def set_custom_property(self, name, value):
221221
"""
222222
self.metadata['customProperties'][name] = value
223223
self.c2.request_put(f"/api/v1/agents/{self.guid}/metadata", self.metadata)
224+
225+
def clear_queue(self):
226+
"""
227+
Clears the agent's command queue.
228+
"""
229+
if self.guid is None:
230+
raise ExceptionTuoniDeleted("")
231+
self.c2.request_post(f"/api/v1/agents/{self.guid}/commands/queue/clear")

tuoni/TuoniC2.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ def download_payload(self, payload_id: int, file_name: str):
300300
"""
301301
self.request_get_file(f"/api/v1/payloads/{payload_id}/download", file_name)
302302

303+
def rename_payload(self, payload_id: int, new_name: str):
304+
"""
305+
Rename a payload.
306+
307+
Args:
308+
payload_id (int): The unique ID of the payload to rename.
309+
new_name (str): The new name for the payload.
310+
"""
311+
self.request_patch(f"/api/v1/payloads/{payload_id}", {"name": new_name})
312+
303313
def load_agents(self, active = True, unactive = False):
304314
"""
305315
Retrieve a list of agents.

tuoni/TuoniCommand.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,11 @@ def get_template(self):
238238
TuoniCommandTemplate: The command template object, or None if the template could not be found.
239239
"""
240240
return self.c2.load_command_template(self.commandTemplateId)
241+
242+
def stop(self):
243+
"""
244+
Stops the command execution on the agent or if it is not yet sent then cancel it.
245+
"""
246+
if self.command_id is None:
247+
raise ExceptionTuoniDeleted("")
248+
self.c2.request_put(f"/api/v1/commands/{self.command_id}/stop")

tuoni/TuoniDefaultCommands.py

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,18 @@ def __init__(self, cmdline, output = True, stdin = None, unicode = None, outputE
147147
super().__init__("run", {"cmdline": cmdline, "output": output, "stdin": stdin, "unicode": unicode, "outputEncoding": outputEncoding})
148148

149149

150+
class TuoniCommandRunas(TuoniDefaultPluginCommand):
151+
"""
152+
Default command type "runas" helper class
153+
"""
154+
_class_base_type = "run"
155+
def __init__(self, cmdline, username, password, output = True, stdin = None, unicode = None, outputEncoding = None):
156+
super().__init__("run", {"cmdline": cmdline, "username": username, "password": password, "output": output, "stdin": stdin, "unicode": unicode, "outputEncoding": outputEncoding})
157+
158+
150159
class TuoniCommandPowershell(TuoniDefaultPluginCommand):
151160
"""
152-
Default command type "powerhsell" helper class
161+
Default command type "powershell" helper class
153162
"""
154163
_class_base_type = "powershell"
155164
def __init__(self, command = None, stdin = None, outputEncoding = None):
@@ -187,11 +196,11 @@ def __init__(self):
187196

188197
class TuoniCommandTokenDelete(TuoniDefaultPluginCommand):
189198
"""
190-
Default command type "token-add" helper class
199+
Default command type "token-del" helper class
191200
"""
192-
_class_base_type = "token-add"
201+
_class_base_type = "token-del"
193202
def __init__(self, nr):
194-
super().__init__("token-add", {"nr": nr})
203+
super().__init__("token-del", {"nr": nr})
195204

196205

197206
class TuoniCommandTokenList(TuoniDefaultPluginCommand):
@@ -221,6 +230,15 @@ def __init__(self, nr):
221230
super().__init__("token-use", {"nr": nr})
222231

223232

233+
class TuoniCommandTokenFromHandle(TuoniDefaultPluginCommand):
234+
"""
235+
Default command type "token-from-handle" helper class
236+
"""
237+
_class_base_type = "token-from-handle"
238+
def __init__(self, handle):
239+
super().__init__("token-from-handle", {"handle": handle})
240+
241+
224242
#########################
225243
## Plugin FS commands
226244
#########################
@@ -233,6 +251,13 @@ class TuoniCommandRm(TuoniDefaultPluginCommand):
233251
def __init__(self, filepath, execution_conf = None):
234252
super().__init__("rm", {"filepath": filepath}, execution_conf)
235253

254+
class TuoniCommandRmdir(TuoniDefaultPluginCommand):
255+
"""
256+
Default command type "rmdir" helper class
257+
"""
258+
_class_base_type = "rmdir"
259+
def __init__(self, dirpath, execution_conf = None):
260+
super().__init__("rmdir", {"dirpath": dirpath}, execution_conf)
236261

237262
class TuoniCommandDownload(TuoniDefaultPluginCommand):
238263
"""
@@ -301,6 +326,24 @@ class TuoniCommandConnectTcp(TuoniDefaultPluginCommand):
301326
def __init__(self, host, port, execution_conf = None):
302327
super().__init__("connect-tcp", {"host": host, "port": port}, execution_conf)
303328

329+
330+
class TuoniCommandConnectSmb(TuoniDefaultPluginCommand):
331+
"""
332+
Default command type "connect-smb" helper class
333+
"""
334+
_class_base_type = "connect-smb"
335+
def __init__(self, host, pipename, execution_conf = None):
336+
super().__init__("connect-smb", {"host": host, "pipename": pipename}, execution_conf)
337+
338+
339+
class TuoniCommandConnectRportfwd(TuoniDefaultPluginCommand):
340+
"""
341+
Default command type "rportfwd" helper class
342+
"""
343+
_class_base_type = "rportfwd"
344+
def __init__(self, bindPort, forwardHost, forwardPort, bindIp = None, execution_conf = None):
345+
super().__init__("rportfwd", {"bindPort": bindPort, "forwardHost": forwardHost, "forwardPort": forwardPort, "bindIp": bindIp}, execution_conf)
346+
304347
#########################
305348
## Plugin OS commands
306349
#########################
@@ -399,3 +442,136 @@ class TuoniCommandReverseShellCommunication(TuoniDefaultCommand):
399442
def __init__(self, input):
400443
super().__init__("reverse-shell-communication", {"input": input})
401444

445+
446+
#########################
447+
## Commercial native commands
448+
#########################
449+
class TuoniCommandChmod(TuoniDefaultCommand):
450+
"""
451+
Commercial command type "chmod" helper class
452+
"""
453+
_class_base_type = "chmod"
454+
def __init__(self, path, access):
455+
super().__init__("chmod", {"path": path, "access": access})
456+
457+
class TuoniCommandSh(TuoniDefaultPluginCommand):
458+
"""
459+
Commercial command type "sh" helper class
460+
"""
461+
_class_base_type = "sh"
462+
def __init__(self, command, stdin = None):
463+
super().__init__("sh", {"command": command, "stdin": stdin})
464+
465+
#########################
466+
## Commercial plugin commands
467+
#########################
468+
469+
class TuoniCommandAmsibypass(TuoniDefaultPluginCommand):
470+
"""
471+
Commercial command type "amsi-bypass" helper class
472+
"""
473+
_class_base_type = "amsi-bypass"
474+
def __init__(self, execution_conf = None):
475+
super().__init__("amsi-bypass", {}, execution_conf)
476+
477+
class TuoniCommandEnvvarset(TuoniDefaultPluginCommand):
478+
"""
479+
Commercial command type "env-var-set" helper class
480+
"""
481+
_class_base_type = "env-var-set"
482+
def __init__(self, name, value, envVarScope, execution_conf = None):
483+
super().__init__("env-var-set", {"name": name, "value": value, "envVarScope": envVarScope}, execution_conf)
484+
485+
class TuoniCommandEnvvarunset(TuoniDefaultPluginCommand):
486+
"""
487+
Commercial command type "env-var-unset" helper class
488+
"""
489+
_class_base_type = "env-var-unset"
490+
def __init__(self, name, envVarScope, execution_conf = None):
491+
super().__init__("env-var-unset", {"name": name, "envVarScope": envVarScope}, execution_conf)
492+
493+
class TuoniCommandKeylogger(TuoniDefaultPluginCommand):
494+
"""
495+
Commercial command type "keylogger" helper class
496+
"""
497+
_class_base_type = "keylogger"
498+
def __init__(self, execution_conf = None):
499+
super().__init__("keylogger", {}, execution_conf)
500+
501+
class TuoniCommandKill(TuoniDefaultPluginCommand):
502+
"""
503+
Commercial command type "kill" helper class
504+
"""
505+
_class_base_type = "kill"
506+
def __init__(self, pid, execution_conf = None):
507+
super().__init__("kill", {"pid": pid}, execution_conf)
508+
509+
class TuoniCommandLoaddll(TuoniDefaultPluginCommand):
510+
"""
511+
Commercial command type "load-dll" helper class
512+
"""
513+
_class_base_type = "load-dll"
514+
def __init__(self, methodName, localDllPath = None, parameterTypes = None, parameterValues = None, returnType = None, dll = None, execution_conf = None):
515+
super().__init__("load-dll", {"localDllPath": localDllPath, "methodName": methodName, "parameterTypes": parameterTypes, "parameterValues": parameterValues, "returnType": returnType}, execution_conf)
516+
if dll is not None:
517+
self.files = {"dll": ["filename.dll", dll]}
518+
519+
class TuoniCommandLoadelf(TuoniDefaultPluginCommand):
520+
"""
521+
Commercial command type "load-elf" helper class
522+
"""
523+
_class_base_type = "load-elf"
524+
def __init__(self, localExecutable = None, commandline = None, maxWaitTime = None, executable = None, execution_conf = None):
525+
super().__init__("load-elf", {"localExecutable": localExecutable, "commandline": commandline, "maxWaitTime": maxWaitTime}, execution_conf)
526+
if executable is not None:
527+
self.files = {"executable": ["executable", executable]}
528+
529+
class TuoniCommandLoadpe(TuoniDefaultPluginCommand):
530+
"""
531+
Commercial command type "load-pe" helper class
532+
"""
533+
_class_base_type = "load-pe"
534+
def __init__(self, localExecutable = None, commandline = None, imageName = None, maxWaitTime = None, executable = None, execution_conf = None):
535+
super().__init__("load-pe", {"localExecutable": localExecutable, "commandline": commandline, "imageName": imageName, "maxWaitTime": maxWaitTime}, execution_conf)
536+
if executable is not None:
537+
self.files = {"executable": ["executable.exe", executable]}
538+
539+
class TuoniCommandMemorylayout(TuoniDefaultPluginCommand):
540+
"""
541+
Commercial command type "memory-layout" helper class
542+
"""
543+
_class_base_type = "memory-layout"
544+
def __init__(self, pid = None, execution_conf = None):
545+
super().__init__("memory-layout", {"pid": pid}, execution_conf)
546+
547+
class TuoniCommandMimikatz(TuoniDefaultPluginCommand):
548+
"""
549+
Commercial command type "mimikatz" helper class
550+
"""
551+
_class_base_type = "mimikatz"
552+
def __init__(self, command, execution_conf = None):
553+
super().__init__("mimikatz", {"command": command}, execution_conf)
554+
555+
class TuoniCommandScreentracker(TuoniDefaultPluginCommand):
556+
"""
557+
Commercial command type "screen-tracker" helper class
558+
"""
559+
_class_base_type = "screen-tracker"
560+
def __init__(self, interval = None, timeout = None, difference = None, difference_pixels = None, execution_conf = None):
561+
super().__init__("screen-tracker", {"interval": interval, "timeout": timeout, "difference": difference, "difference_pixels": difference_pixels}, execution_conf)
562+
563+
class TuoniCommandSuspend(TuoniDefaultPluginCommand):
564+
"""
565+
Commercial command type "suspend" helper class
566+
"""
567+
_class_base_type = "suspend"
568+
def __init__(self, pid, execution_conf = None):
569+
super().__init__("suspend", {"pid": pid}, execution_conf)
570+
571+
class TuoniCommandWebcam(TuoniDefaultPluginCommand):
572+
"""
573+
Commercial command type "webcam" helper class
574+
"""
575+
_class_base_type = "webcam"
576+
def __init__(self, deviceNr = 0, execution_conf = None):
577+
super().__init__("webcam", {"deviceNr": deviceNr}, execution_conf)

tuoni/TuoniListener.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _load_conf(self, conf):
3131
self.status = conf["status"]
3232
self.plugin = conf["plugin"]
3333
self.configuration = conf["configuration"]
34-
self.configuration_files = conf.get("configurationFiles", {})
34+
self.configuration_files = conf.get("configurationFiles", [])
3535

3636

3737
def stop(self):

tuoni/__init__.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from .TuoniEvent import TuoniEvent
2828
from .TuoniCommandPlugin import TuoniCommandPlugin
2929
from .TuoniCommandTemplate import TuoniCommandTemplate
30+
from .TuoniPayload import TuoniPayload
31+
from .TuoniPayloadTemplate import TuoniPayloadTemplate
3032

3133

3234
__all__ = [
@@ -48,7 +50,8 @@
4850
"TuoniEvent",
4951
"TuoniCommandPlugin",
5052
"TuoniCommandTemplate",
51-
53+
"TuoniPayload",
54+
"TuoniPayloadTemplate",
5255
'ExceptionTuoniAuthentication',
5356
'ExceptionTuoniRequestFailed',
5457
'ExceptionTuoniDeleted',
@@ -88,5 +91,21 @@
8891
'TuoniCommandJumpWinrm',
8992
'TuoniCommandJumpWmi',
9093
'TuoniCommandJumpSsh',
91-
'TuoniCommandReverseShellCommunication'
94+
'TuoniCommandReverseShellCommunication',
95+
96+
'TuoniCommandChmod',
97+
'TuoniCommandSh',
98+
'TuoniCommandAmsibypass',
99+
'TuoniCommandEnvvarset',
100+
'TuoniCommandEnvvarunset',
101+
'TuoniCommandKeylogger',
102+
'TuoniCommandKill',
103+
'TuoniCommandLoaddll',
104+
'TuoniCommandLoadelf',
105+
'TuoniCommandLoadpe',
106+
'TuoniCommandMemorylayout',
107+
'TuoniCommandMimikatz',
108+
'TuoniCommandScreentracker',
109+
'TuoniCommandSuspend',
110+
'TuoniCommandWebcam'
92111
]

0 commit comments

Comments
 (0)