-
Notifications
You must be signed in to change notification settings - Fork 1
/
ret.py
127 lines (92 loc) · 5.15 KB
/
ret.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
import argparse
from os.path import dirname, realpath
from helper.utils import get_tool_banner
def positive_float(value):
ivalue = float(value)
if ivalue < 0:
raise argparse.ArgumentTypeError(f"{value} is not a valid inter attack delay value")
return ivalue
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog = "ret",
description = "Redis Exploitation Toolkit")
parser.add_argument("-s", "--host", action = "store",
dest = "redis_server_hostname", default = "127.0.0.1",
help = "Redis Server Hostname/IP (default: 127.0.0.1)")
parser.add_argument("-p", "--port", action = "store", type = int,
dest = "redis_server_port", default = 6379,
help = "Redis Server Port (default: 6379)")
parser.add_argument("-U", "--user", action = "store",
dest = "redis_user", default = "default",
help = "Redis User (default: 'default')")
parser.add_argument("-P", "--pass", action = "store",
dest = "redis_user_password", default = "",
help = "Redis User Password (default: '')")
parser.add_argument("-q", "--quiet", action = "store_true",
dest = "quiet", default = False,
help = "Do not show the tool banner")
parser.add_argument("-y", "--assume-defaults", action = "store_true",
dest = "assume_defaults", default = False,
help = "Assume the default option for the answers " \
"requested by the tool (default: False)")
parser.add_argument("-seq", "--attack-sequence-file", type = str,
dest = "attack_sequence_file",
default = dirname(realpath(__file__)) + "/" + \
"./sequence.json",
help = "For 'mode=auto', specify the file containing " \
"the sequence of attacks to be launched " \
"(default: './sequence.json')")
parser.add_argument("-d", "--delay", type = positive_float,
dest = "inter_attack_delay", default = 0.7,
help = "Delay (in seconds) between the attacks in " \
"auto mode (default: 0.3)")
parser.add_argument("-t", "--exec-timeout", type = positive_float,
dest = "exec_timeout", default = 60,
help = "Timeout (in seconds) for executed system commands " \
"(default: 60)")
parser.add_argument("-v", "--verbose", dest = "verbose",
action = "store_true", default = False,
help = "Enable verbose mode (default: False)")
interactive_group = parser.add_mutually_exclusive_group()
interactive_group.add_argument("-i", "--interactive", dest = "interactive_mode",
action = "store_true", default = False,
help = "Run in interactive mode (default: False)")
interactive_group.add_argument("-r", "--run", type = str,
dest = "attack_path", default = None,
help = "Launch specified attack [format: module/sub-module/attack] " \
"(example: 'rce/exec/ssh')")
interactive_group.add_argument("-a", "--auto", dest = "automated_mode",
action = "store_true", default = False,
help = "Run in automated mode (default: False)")
args = parser.parse_args()
from config import settings
settings.connection_options["host"] = args.redis_server_hostname
settings.connection_options["port"] = args.redis_server_port
settings.connection_options["username"] = args.redis_user
settings.connection_options["password"] = args.redis_user_password
settings.ATTACK_SEQUENCE_FILE = args.attack_sequence_file
settings.ASSUME_DEFAULTS = args.assume_defaults
settings.INTER_ATTACK_DELAY = args.inter_attack_delay
settings.EXEC_TIMEOUT = args.exec_timeout
settings.VERBOSE = args.verbose
if not args.quiet:
print(get_tool_banner())
print("\n[*] Target Information:")
print("HOST:", f"\"{settings.connection_options['host']}\"")
print("PORT:", settings.connection_options["port"])
print("USERNAME:", f"\"{settings.connection_options['username']}\"")
print("PASSWORD:", f"\"{settings.connection_options['password']}\"")
if args.automated_mode:
# Run in automated mode.
# This will run all the attacks in a sequential fashion.
# The sequence has to be well-thought and must be a natural
# progression...
from automated import launch_in_automated_mode
launch_in_automated_mode()
elif args.attack_path:
# Launch the specified attack
from common import launch_exploit
launch_exploit(args.attack_path.split("/"))
else:
# Run in interactive mode - that will always be the default case...
from interactive import launch_in_interactive_mode
launch_in_interactive_mode()