exploitfarm 1.6.7__tar.gz → 1.6.8__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.
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/PKG-INFO +1 -1
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/__init__.py +1 -1
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/config.py +56 -64
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/xploit.py +10 -3
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm.egg-info/PKG-INFO +1 -1
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/setup.py +1 -1
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/MANIFEST.in +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/README.md +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/__main__.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/_init_exposed.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/__init__.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/client.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/dbtypes.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/enums.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/exploit.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/flags.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/groups.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/response.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/service.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/submitter.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/models/teams.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/__init__.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/exploitdownload.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/exploitinit.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/group_prejoin.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/group_select.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/login.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/shared_attack_group.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/tui/startxploit.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/__init__.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/cmd.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/config.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/exploit.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/reqs.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/utils/windows_close_fix.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm/xfarm.py +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm.egg-info/SOURCES.txt +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm.egg-info/dependency_links.txt +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm.egg-info/requires.txt +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/exploitfarm.egg-info/top_level.txt +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/requirements.txt +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/setup.cfg +0 -0
- {exploitfarm-1.6.7 → exploitfarm-1.6.8}/xfarm +0 -0
|
@@ -86,33 +86,19 @@ class InitialConfiguration(App[int]):
|
|
|
86
86
|
"[bold]Welcome to xFarm, please fill the following fields to configure the client",
|
|
87
87
|
classes="error-box",
|
|
88
88
|
)
|
|
89
|
-
yield Label("[bold]ExploitFarm Server
|
|
89
|
+
yield Label("[bold]ExploitFarm Server URL:[/]", classes="input-label")
|
|
90
90
|
yield Input(
|
|
91
|
-
placeholder="127.0.0.1",
|
|
92
|
-
value=self.config.server.address,
|
|
91
|
+
placeholder="http://127.0.0.1:5050",
|
|
92
|
+
value=f"{'https' if self.config.server.https else 'http'}://{self.config.server.address}:{self.config.server.port}",
|
|
93
93
|
validators=[Length(minimum=1)],
|
|
94
|
-
id="
|
|
94
|
+
id="url",
|
|
95
95
|
classes="form-input",
|
|
96
96
|
)
|
|
97
97
|
yield Horizontal(
|
|
98
98
|
Label("[bold]Errors:[/]"),
|
|
99
|
-
Pretty([], id="
|
|
99
|
+
Pretty([], id="url_errors"),
|
|
100
100
|
classes="error-box hidden",
|
|
101
|
-
id="
|
|
102
|
-
)
|
|
103
|
-
yield Label("[bold]ExploitFarm Server port:[/]", classes="input-label")
|
|
104
|
-
yield Input(
|
|
105
|
-
placeholder="5050",
|
|
106
|
-
value=str(self.config.server.port),
|
|
107
|
-
validators=[Number(minimum=1, maximum=65535)],
|
|
108
|
-
id="port",
|
|
109
|
-
classes="form-input",
|
|
110
|
-
)
|
|
111
|
-
yield Horizontal(
|
|
112
|
-
Label("[bold]Errors:[/]"),
|
|
113
|
-
Pretty([], id="port_errors"),
|
|
114
|
-
classes="error-box hidden",
|
|
115
|
-
id="port_errors_box",
|
|
101
|
+
id="url_errors_box",
|
|
116
102
|
)
|
|
117
103
|
yield Label("[bold]Nickname:[/]", classes="input-label")
|
|
118
104
|
yield Input(
|
|
@@ -128,18 +114,7 @@ class InitialConfiguration(App[int]):
|
|
|
128
114
|
classes="error-box hidden",
|
|
129
115
|
id="nickname_errors_box",
|
|
130
116
|
)
|
|
131
|
-
|
|
132
|
-
"Use HTTPS",
|
|
133
|
-
id="https",
|
|
134
|
-
value=self.config.server.https,
|
|
135
|
-
classes="input-label",
|
|
136
|
-
)
|
|
137
|
-
yield Checkbox(
|
|
138
|
-
"Ignore connection failed",
|
|
139
|
-
id="ign_conn_failed",
|
|
140
|
-
value=self.ignore_connection_failed,
|
|
141
|
-
classes="input-label",
|
|
142
|
-
)
|
|
117
|
+
|
|
143
118
|
yield Label(
|
|
144
119
|
self.initial_error,
|
|
145
120
|
classes=f"{'' if self.initial_error else 'hidden'}",
|
|
@@ -148,6 +123,9 @@ class InitialConfiguration(App[int]):
|
|
|
148
123
|
yield Horizontal(
|
|
149
124
|
Button("Save", id="save", variant="success"),
|
|
150
125
|
Button("Cancel", id="cancel", variant="error"),
|
|
126
|
+
Button(
|
|
127
|
+
"Ignore Connection Failed", id="ignore", variant="warning", classes="float-right"
|
|
128
|
+
),
|
|
151
129
|
Button(
|
|
152
130
|
"Test Connection", id="test", variant="primary", classes="float-right"
|
|
153
131
|
),
|
|
@@ -155,6 +133,35 @@ class InitialConfiguration(App[int]):
|
|
|
155
133
|
)
|
|
156
134
|
yield Footer()
|
|
157
135
|
|
|
136
|
+
def _update_url(self) -> bool:
|
|
137
|
+
try:
|
|
138
|
+
import urllib.parse
|
|
139
|
+
url_val = self.query_one("#url", Input).value.strip()
|
|
140
|
+
if not url_val:
|
|
141
|
+
return False
|
|
142
|
+
if "://" not in url_val:
|
|
143
|
+
url_val = "http://" + url_val
|
|
144
|
+
parsed = urllib.parse.urlparse(url_val)
|
|
145
|
+
hostname = parsed.hostname
|
|
146
|
+
port = parsed.port
|
|
147
|
+
if not hostname:
|
|
148
|
+
return False
|
|
149
|
+
if port is None:
|
|
150
|
+
port = 443 if parsed.scheme == "https" else 80
|
|
151
|
+
if ":" in hostname and not hostname.startswith("["):
|
|
152
|
+
hostname = f"[{hostname}]"
|
|
153
|
+
self.config.server.address = hostname
|
|
154
|
+
self.config.server.port = port
|
|
155
|
+
self.config.server.https = parsed.scheme == "https"
|
|
156
|
+
return True
|
|
157
|
+
except Exception:
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
@on(Button.Pressed, "#ignore")
|
|
161
|
+
def ignore_connection_failed_press(self):
|
|
162
|
+
self.ignore_connection_failed = True
|
|
163
|
+
self.save()
|
|
164
|
+
|
|
158
165
|
def action_save(self):
|
|
159
166
|
self.save()
|
|
160
167
|
|
|
@@ -176,12 +183,13 @@ class InitialConfiguration(App[int]):
|
|
|
176
183
|
if ele.failure_description
|
|
177
184
|
]
|
|
178
185
|
)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
self.
|
|
184
|
-
|
|
186
|
+
|
|
187
|
+
if not self._update_url():
|
|
188
|
+
errors.append("Invalid URL")
|
|
189
|
+
error_label = self.query_one("#url_errors", Pretty)
|
|
190
|
+
error_box = self.query_one("#url_errors_box", Horizontal)
|
|
191
|
+
error_box.remove_class("hidden")
|
|
192
|
+
error_label.update(["Invalid URL"])
|
|
185
193
|
|
|
186
194
|
if len(errors) == 0 and (self.ignore_connection_failed or self.test()):
|
|
187
195
|
self.config.write()
|
|
@@ -193,6 +201,12 @@ class InitialConfiguration(App[int]):
|
|
|
193
201
|
|
|
194
202
|
@on(Button.Pressed, "#test")
|
|
195
203
|
def test(self):
|
|
204
|
+
if not self._update_url():
|
|
205
|
+
error_label = self.query_one("#error", Label)
|
|
206
|
+
error_label.remove_class("hidden")
|
|
207
|
+
error_label.update("[bold red]Invalid URL[/]")
|
|
208
|
+
return False
|
|
209
|
+
|
|
196
210
|
error_label = self.query_one("#error", Label)
|
|
197
211
|
error_label.remove_class("hidden")
|
|
198
212
|
try:
|
|
@@ -208,37 +222,15 @@ class InitialConfiguration(App[int]):
|
|
|
208
222
|
)
|
|
209
223
|
return False
|
|
210
224
|
|
|
211
|
-
@on(
|
|
212
|
-
def
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
@on(Checkbox.Changed, "#ign_conn_failed")
|
|
216
|
-
def ignore_connection_failed_change(self, event: Checkbox.Changed):
|
|
217
|
-
self.ignore_connection_failed = event.value
|
|
218
|
-
|
|
219
|
-
@on(Input.Changed, "#address")
|
|
220
|
-
def address_check(self, event: Input.Changed) -> None:
|
|
221
|
-
# Updating the UI to show the reasons why validation failed
|
|
222
|
-
error_label = self.query_one("#address_errors", Pretty)
|
|
223
|
-
error_box = self.query_one("#address_errors_box", Horizontal)
|
|
224
|
-
if not event.validation_result.is_valid:
|
|
225
|
-
error_box.remove_class("hidden")
|
|
226
|
-
error_label.update(event.validation_result.failure_descriptions)
|
|
227
|
-
else:
|
|
228
|
-
error_box.add_class("hidden")
|
|
229
|
-
self.config.server.address = event.input.value
|
|
230
|
-
|
|
231
|
-
@on(Input.Changed, "#port")
|
|
232
|
-
def port_check(self, event: Input.Changed) -> None:
|
|
233
|
-
# Updating the UI to show the reasons why validation failed
|
|
234
|
-
error_label = self.query_one("#port_errors", Pretty)
|
|
235
|
-
error_box = self.query_one("#port_errors_box", Horizontal)
|
|
225
|
+
@on(Input.Changed, "#url")
|
|
226
|
+
def url_check(self, event: Input.Changed) -> None:
|
|
227
|
+
error_label = self.query_one("#url_errors", Pretty)
|
|
228
|
+
error_box = self.query_one("#url_errors_box", Horizontal)
|
|
236
229
|
if not event.validation_result.is_valid:
|
|
237
230
|
error_box.remove_class("hidden")
|
|
238
231
|
error_label.update(event.validation_result.failure_descriptions)
|
|
239
232
|
else:
|
|
240
233
|
error_box.add_class("hidden")
|
|
241
|
-
self.config.server.port = int(event.input.value)
|
|
242
234
|
|
|
243
235
|
@on(Input.Changed, "#nickname")
|
|
244
236
|
def nickname_check(self, event: Input.Changed) -> None:
|
|
@@ -361,7 +361,12 @@ def update_server_config(event):
|
|
|
361
361
|
|
|
362
362
|
def post_attacks(attacks, exploit_id):
|
|
363
363
|
try:
|
|
364
|
-
g.exec.config.reqs.submit_flags(attacks, exploit=exploit_id)
|
|
364
|
+
res = g.exec.config.reqs.submit_flags(attacks, exploit=exploit_id)
|
|
365
|
+
if isinstance(res, dict):
|
|
366
|
+
flags = res.get("flags", 0)
|
|
367
|
+
dups = res.get("duplicates", 0)
|
|
368
|
+
if flags > 0 or dups > 0:
|
|
369
|
+
qprint(f"Submitted {flags} flags ({dups} duplicates) to the server")
|
|
365
370
|
g.attack_storage.mark_as_sent(len(attacks))
|
|
366
371
|
g.exec.info.submitter_status = True
|
|
367
372
|
return True
|
|
@@ -1075,11 +1080,13 @@ def xploit_one(exec_info: AttackStartConfig, team: str, timeout: float = 30):
|
|
|
1075
1080
|
break
|
|
1076
1081
|
for attack in attacks:
|
|
1077
1082
|
if len(attack["flags"]) > 0:
|
|
1078
|
-
g.exec.config.reqs.submit_flags({"flags": attack["flags"]})
|
|
1083
|
+
res = g.exec.config.reqs.submit_flags({"flags": attack["flags"]})
|
|
1084
|
+
flags = res.get("flags", 0) if isinstance(res, dict) else len(attack["flags"])
|
|
1085
|
+
dups = res.get("duplicates", 0) if isinstance(res, dict) else 0
|
|
1079
1086
|
g.attack_storage.mark_as_sent(1)
|
|
1080
1087
|
if len(attack["flags"]) > 0:
|
|
1081
1088
|
qprint(
|
|
1082
|
-
f"Submitted {
|
|
1089
|
+
f"Submitted {flags} flags ({dups} duplicates) as manual submissions."
|
|
1083
1090
|
)
|
|
1084
1091
|
except Exception:
|
|
1085
1092
|
qprint("Can't submit flags due missing config")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|