-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
251 lines (204 loc) · 9.71 KB
/
Copy pathmain.py
File metadata and controls
251 lines (204 loc) · 9.71 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
import argparse
import sys
from core.logger import log, ReasoningLogger
from core.report import ReportGenerator
from core.bloodhound import BloodHoundGenerator
from modules import ad_enum, ad_attacks, ad_post, ad_acl, ad_gpo, ad_cs, ad_lateral, ad_defense, ad_exchange
def main():
parser = argparse.ArgumentParser(description="RedReason - Autonomous Red Team Operation Tool")
parser.add_argument("--target", required=True, help="Target Domain or IP")
parser.add_argument("--user", help="Username for authentication")
parser.add_argument("--password", help="Password for authentication")
parser.add_argument("--hashes", help="NTLM hashes (LM:NT)")
parser.add_argument("--domain", help="Domain Name (if different from target)")
parser.add_argument("--module", choices=["enum", "attack", "post", "acl", "gpo", "cs", "lateral", "defense", "exchange", "virt", "all"], default="all", help="Operation module to run")
parser.add_argument("-v", "--verbose", action="count", default=0, help="Increase verbosity (-v, -vv, -vvv)")
parser.add_argument('--bloodhound', action='store_true', help='Generate BloodHound compatible output files')
parser.add_argument('--stealth', action='store_true', help='Enable Stealth Mode (Passive Checks Only)')
args = parser.parse_args()
# Re-init logger with appropriate level
# Verbosity: 0=WARNING, 1=INFO (default), 2=DEBUG, 3+=TRACE (very verbose)
if args.verbose >= 2:
log.logger.setLevel("DEBUG")
if args.verbose == 0:
log.logger.setLevel("WARNING")
# Set verbosity level in logger for internal tracking
log.set_verbosity(args.verbose)
log.info(f"Starting RedReason against {args.target}")
# Display settings
if args.stealth:
log.info("🥷 STEALTH MODE ENABLED: Passive checks only (no active exploitation)")
if args.verbose > 0:
log.debug(f"Verbosity Level: {args.verbose} (0=quiet, 1=normal, 2=verbose, 3+=very verbose)")
if args.bloodhound:
log.debug("BloodHound output will be generated")
log.hypothesis(f"Baseline: Assuming we have network access to {args.target}")
# Determine target domain for AD operations
target_domain = args.domain if args.domain else args.target
try:
# Enforce execution ceiling based on the --stealth flag (Proposition 4)
max_level = 1 if args.stealth else 3
log.info(f"Stealth Mode: {'Enabled (Ceiling L1)' if args.stealth else 'Disabled (Ceiling L3)'}")
# Try to load session first to populate context if we skipped enum
from core.session import SessionManager
sm = SessionManager(args.target)
cached_users, cached_computers = sm.load_state()
if args.module in ["enum", "all"]:
log.info("Running Enumeration Module...")
enumerator = ad_enum.ADEnumerator(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes
)
enumerator.max_level = max_level
if not enumerator.run_all():
log.fail("Critical Failure: Initial LDAP connection failed. Aborting operations.")
sys.exit(1)
if args.bloodhound:
log.info("Generating BloodHound files...")
bh = BloodHoundGenerator()
if hasattr(enumerator, 'collected_users'):
bh.generate_users(target_domain, enumerator.collected_users)
if hasattr(enumerator, 'collected_computers'):
bh.generate_computers(target_domain, enumerator.collected_computers)
if args.module in ["attack", "all"]:
log.info("Running Attack Module...")
# If we didn't run enumeration just now, but we loaded a session, create a dummy enumerator to hold state
if 'enumerator' not in locals():
# Create a shell enumerator just to hold the data
enumerator = ad_enum.ADEnumerator(args.target, target_domain, args.user, args.password, args.hashes)
if cached_users: enumerator.collected_users = cached_users
if cached_computers: enumerator.collected_computers = cached_computers
current_state = enumerator if 'enumerator' in locals() else None
attacker = ad_attacks.ADAttacker(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
attacker.max_level = max_level
attacker.run(args)
if args.module in ["post", "all"]:
log.info("Running Post-Exploitation Module...")
current_state = enumerator if 'enumerator' in locals() else None
post_ex = ad_post.ADPostExploitation(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
post_ex.max_level = max_level
post_ex.run(args)
if args.module in ["acl", "all"]:
log.info("Running ACL & Authorization Module...")
current_state = enumerator if 'enumerator' in locals() else None
acl_mod = ad_acl.ADACLAbuse(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
acl_mod.max_level = max_level
acl_mod.run(args)
if args.module in ["gpo", "all"]:
log.info("Running GPO Abuse Module...")
current_state = enumerator if 'enumerator' in locals() else None
gpo_mod = ad_gpo.ADGPOAbuse(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
gpo_mod.max_level = max_level
gpo_mod.run(args)
if args.module in ["cs", "all"]:
log.info("Running ADCS Abuse Module...")
current_state = enumerator if 'enumerator' in locals() else None
cs_mod = ad_cs.ADCSAbuse(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
cs_mod.max_level = max_level
cs_mod.run(args)
if args.module in ["lateral", "all"]:
log.info("Running Lateral Movement Exposure Module...")
current_state = enumerator if 'enumerator' in locals() else None
lat_mod = ad_lateral.ADLateralMovement(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
lat_mod.max_level = max_level
lat_mod.run(args)
if args.module in ["defense", "all"]:
log.info("Running Defensive Posture Module...")
current_state = enumerator if 'enumerator' in locals() else None
def_mod = ad_defense.ADDefenseAwareness(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
def_mod.max_level = max_level
def_mod.run(args)
if args.module in ["exchange", "all"]:
log.info("Running Exchange Operations Module...")
current_state = enumerator if 'enumerator' in locals() else None
exch_mod = ad_exchange.ADExchangeOps(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
exch_mod.max_level = max_level
exch_mod.run(args)
if args.module in ["virt", "all"]:
log.info("Running Virtualization Operations Module...")
current_state = enumerator if 'enumerator' in locals() else None
from modules.ad_virt import ADVirtualizationOps
virt_mod = ADVirtualizationOps(
target=args.target,
domain=target_domain,
user=args.user,
password=args.password,
hashes=args.hashes,
enumeration_data=current_state
)
virt_mod.max_level = max_level
virt_mod.run(args)
except KeyboardInterrupt:
log.fail("Operation interrupted by user")
except Exception as e:
log.fail(f"Unhandled Exception: {str(e)}")
if args.verbose >= 3:
import traceback
tb_str = traceback.format_exc()
log.trace(f"Exception Traceback:\n{tb_str}")
# Generate Report
reporter = ReportGenerator(log)
report_file = reporter.generate_markdown(args.target)
json_file = reporter.generate_json(args.target)
log.success(f"Reports generated: {report_file}, {json_file}")
if __name__ == "__main__":
main()