exploitfarm 1.7.9__tar.gz → 2.1.0__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.7.9/exploitfarm.egg-info → exploitfarm-2.1.0}/PKG-INFO +111 -12
- exploitfarm-1.7.9/PKG-INFO → exploitfarm-2.1.0/README.md +102 -40
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/__init__.py +1 -1
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/_init_exposed.py +38 -28
- exploitfarm-2.1.0/exploitfarm/attack_storage.py +225 -0
- exploitfarm-2.1.0/exploitfarm/autotune.py +165 -0
- exploitfarm-2.1.0/exploitfarm/connection.py +252 -0
- exploitfarm-2.1.0/exploitfarm/core_orchestration.py +709 -0
- exploitfarm-2.1.0/exploitfarm/local_executor.py +940 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/enums.py +4 -2
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/exploit.py +6 -6
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/groups.py +8 -3
- exploitfarm-2.1.0/exploitfarm/team_provider.py +93 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/config.py +1 -13
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/exploitinit.py +13 -12
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/group_prejoin.py +26 -7
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/group_select.py +3 -3
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/shared_attack_group.py +1 -1
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/startxploit.py +213 -84
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/__init__.py +59 -15
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/config.py +17 -7
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/reqs.py +102 -12
- exploitfarm-2.1.0/exploitfarm/utils/threadpool.py +90 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/xfarm.py +168 -30
- exploitfarm-2.1.0/exploitfarm/xploit.py +590 -0
- exploitfarm-1.7.9/README.md → exploitfarm-2.1.0/exploitfarm.egg-info/PKG-INFO +139 -3
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm.egg-info/SOURCES.txt +7 -0
- exploitfarm-2.1.0/exploitfarm.egg-info/requires.txt +15 -0
- exploitfarm-2.1.0/requirements.txt +16 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/setup.py +1 -1
- exploitfarm-1.7.9/exploitfarm/xploit.py +0 -1238
- exploitfarm-1.7.9/exploitfarm.egg-info/requires.txt +0 -15
- exploitfarm-1.7.9/requirements.txt +0 -15
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/MANIFEST.in +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/__main__.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/__init__.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/client.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/dbtypes.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/exploit_template.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/flags.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/response.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/service.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/submitter.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/models/teams.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/__init__.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/exploitdownload.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/login.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/tui/template.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/cmd.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/exploit.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/paths.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/templates.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm/utils/windows_close_fix.py +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm.egg-info/dependency_links.txt +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/exploitfarm.egg-info/top_level.txt +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/setup.cfg +0 -0
- {exploitfarm-1.7.9 → exploitfarm-2.1.0}/xfarm +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exploitfarm
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Exploit Farm client
|
|
5
5
|
Home-page: https://github.com/pwnzer0tt1/exploitfarm
|
|
6
6
|
Author: Pwnzer0tt1
|
|
@@ -12,18 +12,18 @@ Requires-Python: >=3.10
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
Requires-Dist: requests>=2.32.5
|
|
14
14
|
Requires-Dist: urllib3>=2.5.0
|
|
15
|
-
Requires-Dist: python-dateutil
|
|
15
|
+
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
16
16
|
Requires-Dist: pydantic>=2
|
|
17
17
|
Requires-Dist: typing-extensions>=4.7.1
|
|
18
|
-
Requires-Dist: fasteners
|
|
19
|
-
Requires-Dist: toml
|
|
20
|
-
Requires-Dist: psutil
|
|
21
|
-
Requires-Dist: dirhash
|
|
22
|
-
Requires-Dist: requests-toolbelt
|
|
23
|
-
Requires-Dist: python-socketio[
|
|
18
|
+
Requires-Dist: fasteners>=0.20
|
|
19
|
+
Requires-Dist: toml>=0.10.2
|
|
20
|
+
Requires-Dist: psutil>=7.2.2
|
|
21
|
+
Requires-Dist: dirhash>=0.5.0
|
|
22
|
+
Requires-Dist: requests-toolbelt>=1.0.0
|
|
23
|
+
Requires-Dist: python-socketio[asyncio_client]>=5.14.1
|
|
24
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
24
25
|
Requires-Dist: textual>=3.0.0
|
|
25
26
|
Requires-Dist: typer>=0.16
|
|
26
|
-
Requires-Dist: xfarm
|
|
27
27
|
Requires-Dist: platformdirs>=4.0
|
|
28
28
|
Dynamic: author
|
|
29
29
|
Dynamic: author-email
|
|
@@ -203,6 +203,14 @@ xfarm start [OPTIONS] PATH
|
|
|
203
203
|
xfarm start ./my_exploit --pool-size 20 --test
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
+
### Exploit Execution Environment
|
|
207
|
+
|
|
208
|
+
To protect your exploit source code and maintain a clean workspace, exploits are never executed directly in their project directory. Instead, `xfarm` starts the execution by copying your exploit files into a temporary `__xfarm_run__` folder and runs the exploit from there. This guarantees:
|
|
209
|
+
- **Clean Execution**: Your original directory isn't polluted by runtime artifacts, logs, or temporary files generated by the exploit.
|
|
210
|
+
- **Isolation**: Changes made by the exploit script (e.g., dropping files, compiling binaries) remain isolated.
|
|
211
|
+
|
|
212
|
+
A Git-like ignores system is available: You can use a `.ignore` (only in the root of the exploit folder) to specify files/directories that shouldn't be copied into the `__xfarm_run__` directory and when using `xfarm push`.
|
|
213
|
+
|
|
206
214
|
---
|
|
207
215
|
|
|
208
216
|
### **Configuration Commands**
|
|
@@ -273,7 +281,6 @@ xfarm init [OPTIONS]
|
|
|
273
281
|
|
|
274
282
|
**Options**:
|
|
275
283
|
|
|
276
|
-
- `--edit, -e`: Edit the configuration interactively.
|
|
277
284
|
- `--name`: Exploit name.
|
|
278
285
|
- `--service`: Associated service UUID.
|
|
279
286
|
- `--language`: Programming language.
|
|
@@ -320,13 +327,55 @@ xfarm pull [OPTIONS]
|
|
|
320
327
|
Download the exploit source:
|
|
321
328
|
|
|
322
329
|
```bash
|
|
323
|
-
xfarm clone [OPTIONS]
|
|
330
|
+
xfarm clone [OPTIONS] [exploit_id] [commit_uuid]
|
|
324
331
|
```
|
|
325
332
|
|
|
333
|
+
**Arguments**:
|
|
334
|
+
|
|
335
|
+
- `exploit_id`: The exploit ID to download.
|
|
336
|
+
- `commit_uuid`: The commit UUID to take the source from (default: latest).
|
|
337
|
+
|
|
326
338
|
**Options**:
|
|
327
339
|
|
|
328
340
|
- `--folder, -f`: Specify target folder.
|
|
329
|
-
|
|
341
|
+
|
|
342
|
+
#### **Edit Exploit Configuration**
|
|
343
|
+
|
|
344
|
+
Edit the exploit configuration (e.g. language, service):
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
xfarm edit [OPTIONS]
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Options**:
|
|
351
|
+
|
|
352
|
+
- `--name`: The name of the exploit.
|
|
353
|
+
- `--service`: The service UUID of the exploit.
|
|
354
|
+
- `--language`: The programming language of the exploit.
|
|
355
|
+
|
|
356
|
+
#### **Checkout Exploit Commit**
|
|
357
|
+
|
|
358
|
+
Download the specified exploit commit and switch to it:
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
xfarm checkout [OPTIONS] {commit_uuid}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Options**:
|
|
365
|
+
|
|
366
|
+
- `--force, -f`: Force the move even if the current commit is not pushed.
|
|
367
|
+
|
|
368
|
+
#### **Flush Flag Queue**
|
|
369
|
+
|
|
370
|
+
Flush the local flag queue to the backend (used if manual submissions were queued locally due to network failure):
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
xfarm flush [OPTIONS] [path]
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Options**:
|
|
377
|
+
|
|
378
|
+
- `path`: Optional path to a specific directory or `.flag_queue.json` file.
|
|
330
379
|
|
|
331
380
|
---
|
|
332
381
|
|
|
@@ -343,6 +392,7 @@ xfarm group create [OPTIONS]
|
|
|
343
392
|
**Options**:
|
|
344
393
|
|
|
345
394
|
- `--name`: Group name.
|
|
395
|
+
- `--submit-pool-timeout`: The timeout for the submit pool to wait for new attack results and send flags (default: 3).
|
|
346
396
|
|
|
347
397
|
|
|
348
398
|
#### **Join Attack Group**
|
|
@@ -374,6 +424,55 @@ Shows a table with all existing groups, their IDs, and if there is a worker runn
|
|
|
374
424
|
|
|
375
425
|
---
|
|
376
426
|
|
|
427
|
+
### **Template Commands**
|
|
428
|
+
|
|
429
|
+
Manage exploit templates for quickly starting new exploits:
|
|
430
|
+
|
|
431
|
+
#### **List Templates**
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
xfarm template list
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### **Add Template**
|
|
438
|
+
|
|
439
|
+
Add a new template from an existing folder:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
xfarm template add [path]
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### **Edit Template**
|
|
446
|
+
|
|
447
|
+
Edit an existing template interactively:
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
xfarm template edit
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
### **Submitter Commands**
|
|
456
|
+
|
|
457
|
+
#### **Test Submitter**
|
|
458
|
+
|
|
459
|
+
Test your submitter python script against the backend's flag extraction:
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
xfarm submitter-test [OPTIONS] {path} {output}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Arguments**:
|
|
466
|
+
|
|
467
|
+
- `path`: Submitter python script.
|
|
468
|
+
- `output`: Text containing flags according to server REGEX.
|
|
469
|
+
|
|
470
|
+
**Options**:
|
|
471
|
+
|
|
472
|
+
- `--kwargs`: Submitter key-words args (json) (default: {}).
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
377
476
|
## **Environment Variables**
|
|
378
477
|
|
|
379
478
|
Environment variables can simplify configuration:
|
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: exploitfarm
|
|
3
|
-
Version: 1.7.9
|
|
4
|
-
Summary: Exploit Farm client
|
|
5
|
-
Home-page: https://github.com/pwnzer0tt1/exploitfarm
|
|
6
|
-
Author: Pwnzer0tt1
|
|
7
|
-
Author-email: pwnzer0tt1@poliba.it
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.10
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
Requires-Dist: requests>=2.32.5
|
|
14
|
-
Requires-Dist: urllib3>=2.5.0
|
|
15
|
-
Requires-Dist: python-dateutil==2.9.0.post0
|
|
16
|
-
Requires-Dist: pydantic>=2
|
|
17
|
-
Requires-Dist: typing-extensions>=4.7.1
|
|
18
|
-
Requires-Dist: fasteners==0.20
|
|
19
|
-
Requires-Dist: toml==0.10.2
|
|
20
|
-
Requires-Dist: psutil==7.2.1
|
|
21
|
-
Requires-Dist: dirhash==0.5.0
|
|
22
|
-
Requires-Dist: requests-toolbelt==1.0.0
|
|
23
|
-
Requires-Dist: python-socketio[client]>=5.14.1
|
|
24
|
-
Requires-Dist: textual>=3.0.0
|
|
25
|
-
Requires-Dist: typer>=0.16
|
|
26
|
-
Requires-Dist: xfarm
|
|
27
|
-
Requires-Dist: platformdirs>=4.0
|
|
28
|
-
Dynamic: author
|
|
29
|
-
Dynamic: author-email
|
|
30
|
-
Dynamic: classifier
|
|
31
|
-
Dynamic: description
|
|
32
|
-
Dynamic: description-content-type
|
|
33
|
-
Dynamic: home-page
|
|
34
|
-
Dynamic: requires-dist
|
|
35
|
-
Dynamic: requires-python
|
|
36
|
-
Dynamic: summary
|
|
37
|
-
|
|
38
1
|
# ExploitFarm Python Library and CLI
|
|
39
2
|
|
|
40
3
|
**ExploitFarm** is an advanced tool designed to manage exploits and flag submissions in Attack-Defense CTF competitions. It combines a Python library with a command-line interface (CLI), providing flexibility and efficiency for managing CTF tasks. This documentation provides a comprehensive overview of its features, installation, and usage.
|
|
@@ -203,6 +166,14 @@ xfarm start [OPTIONS] PATH
|
|
|
203
166
|
xfarm start ./my_exploit --pool-size 20 --test
|
|
204
167
|
```
|
|
205
168
|
|
|
169
|
+
### Exploit Execution Environment
|
|
170
|
+
|
|
171
|
+
To protect your exploit source code and maintain a clean workspace, exploits are never executed directly in their project directory. Instead, `xfarm` starts the execution by copying your exploit files into a temporary `__xfarm_run__` folder and runs the exploit from there. This guarantees:
|
|
172
|
+
- **Clean Execution**: Your original directory isn't polluted by runtime artifacts, logs, or temporary files generated by the exploit.
|
|
173
|
+
- **Isolation**: Changes made by the exploit script (e.g., dropping files, compiling binaries) remain isolated.
|
|
174
|
+
|
|
175
|
+
A Git-like ignores system is available: You can use a `.ignore` (only in the root of the exploit folder) to specify files/directories that shouldn't be copied into the `__xfarm_run__` directory and when using `xfarm push`.
|
|
176
|
+
|
|
206
177
|
---
|
|
207
178
|
|
|
208
179
|
### **Configuration Commands**
|
|
@@ -273,7 +244,6 @@ xfarm init [OPTIONS]
|
|
|
273
244
|
|
|
274
245
|
**Options**:
|
|
275
246
|
|
|
276
|
-
- `--edit, -e`: Edit the configuration interactively.
|
|
277
247
|
- `--name`: Exploit name.
|
|
278
248
|
- `--service`: Associated service UUID.
|
|
279
249
|
- `--language`: Programming language.
|
|
@@ -320,13 +290,55 @@ xfarm pull [OPTIONS]
|
|
|
320
290
|
Download the exploit source:
|
|
321
291
|
|
|
322
292
|
```bash
|
|
323
|
-
xfarm clone [OPTIONS]
|
|
293
|
+
xfarm clone [OPTIONS] [exploit_id] [commit_uuid]
|
|
324
294
|
```
|
|
325
295
|
|
|
296
|
+
**Arguments**:
|
|
297
|
+
|
|
298
|
+
- `exploit_id`: The exploit ID to download.
|
|
299
|
+
- `commit_uuid`: The commit UUID to take the source from (default: latest).
|
|
300
|
+
|
|
326
301
|
**Options**:
|
|
327
302
|
|
|
328
303
|
- `--folder, -f`: Specify target folder.
|
|
329
|
-
|
|
304
|
+
|
|
305
|
+
#### **Edit Exploit Configuration**
|
|
306
|
+
|
|
307
|
+
Edit the exploit configuration (e.g. language, service):
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
xfarm edit [OPTIONS]
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Options**:
|
|
314
|
+
|
|
315
|
+
- `--name`: The name of the exploit.
|
|
316
|
+
- `--service`: The service UUID of the exploit.
|
|
317
|
+
- `--language`: The programming language of the exploit.
|
|
318
|
+
|
|
319
|
+
#### **Checkout Exploit Commit**
|
|
320
|
+
|
|
321
|
+
Download the specified exploit commit and switch to it:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
xfarm checkout [OPTIONS] {commit_uuid}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**Options**:
|
|
328
|
+
|
|
329
|
+
- `--force, -f`: Force the move even if the current commit is not pushed.
|
|
330
|
+
|
|
331
|
+
#### **Flush Flag Queue**
|
|
332
|
+
|
|
333
|
+
Flush the local flag queue to the backend (used if manual submissions were queued locally due to network failure):
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
xfarm flush [OPTIONS] [path]
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Options**:
|
|
340
|
+
|
|
341
|
+
- `path`: Optional path to a specific directory or `.flag_queue.json` file.
|
|
330
342
|
|
|
331
343
|
---
|
|
332
344
|
|
|
@@ -343,6 +355,7 @@ xfarm group create [OPTIONS]
|
|
|
343
355
|
**Options**:
|
|
344
356
|
|
|
345
357
|
- `--name`: Group name.
|
|
358
|
+
- `--submit-pool-timeout`: The timeout for the submit pool to wait for new attack results and send flags (default: 3).
|
|
346
359
|
|
|
347
360
|
|
|
348
361
|
#### **Join Attack Group**
|
|
@@ -374,6 +387,55 @@ Shows a table with all existing groups, their IDs, and if there is a worker runn
|
|
|
374
387
|
|
|
375
388
|
---
|
|
376
389
|
|
|
390
|
+
### **Template Commands**
|
|
391
|
+
|
|
392
|
+
Manage exploit templates for quickly starting new exploits:
|
|
393
|
+
|
|
394
|
+
#### **List Templates**
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
xfarm template list
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### **Add Template**
|
|
401
|
+
|
|
402
|
+
Add a new template from an existing folder:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
xfarm template add [path]
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### **Edit Template**
|
|
409
|
+
|
|
410
|
+
Edit an existing template interactively:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
xfarm template edit
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
### **Submitter Commands**
|
|
419
|
+
|
|
420
|
+
#### **Test Submitter**
|
|
421
|
+
|
|
422
|
+
Test your submitter python script against the backend's flag extraction:
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
xfarm submitter-test [OPTIONS] {path} {output}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Arguments**:
|
|
429
|
+
|
|
430
|
+
- `path`: Submitter python script.
|
|
431
|
+
- `output`: Text containing flags according to server REGEX.
|
|
432
|
+
|
|
433
|
+
**Options**:
|
|
434
|
+
|
|
435
|
+
- `--kwargs`: Submitter key-words args (json) (default: {}).
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
377
439
|
## **Environment Variables**
|
|
378
440
|
|
|
379
441
|
Environment variables can simplify configuration:
|
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
import functools
|
|
3
4
|
import random
|
|
4
5
|
import os
|
|
5
|
-
from exploitfarm.utils.config import ClientConfig
|
|
6
|
-
from exploitfarm.tui.config import inital_config_setup
|
|
7
|
-
from exploitfarm.tui.login import login_required
|
|
8
6
|
from enum import Enum
|
|
9
|
-
import psutil
|
|
10
7
|
import traceback
|
|
11
8
|
import pickle
|
|
12
|
-
from exploitfarm.utils import DEV_MODE
|
|
13
9
|
from posixpath import join as urljoin
|
|
14
|
-
from exploitfarm.utils.reqs import (
|
|
15
|
-
requests_check_json,
|
|
16
|
-
HTTP_TIMEOUT,
|
|
17
|
-
check_req,
|
|
18
|
-
get_session,
|
|
19
|
-
)
|
|
20
|
-
from requests import Session
|
|
21
10
|
import re
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
import requests
|
|
15
|
+
from requests import Session
|
|
22
16
|
|
|
23
17
|
os_windows = os.name == "nt"
|
|
24
18
|
os_unix = os.name == "posix"
|
|
@@ -39,6 +33,7 @@ class Prio(Enum):
|
|
|
39
33
|
|
|
40
34
|
def nicenessify(priority: Prio = Prio.low, pid: int | None = None):
|
|
41
35
|
try:
|
|
36
|
+
import psutil
|
|
42
37
|
pid = os.getpid() if pid is None else pid
|
|
43
38
|
ps = psutil.Process(pid)
|
|
44
39
|
if not isinstance(priority, Prio):
|
|
@@ -67,12 +62,16 @@ def nicenessify(priority: Prio = Prio.low, pid: int | None = None):
|
|
|
67
62
|
nice_value = psutil.BELOW_NORMAL_PRIORITY_CLASS
|
|
68
63
|
ps.nice(nice_value)
|
|
69
64
|
except Exception as e:
|
|
65
|
+
from exploitfarm.utils import DEV_MODE
|
|
70
66
|
error = traceback.format_exc() if DEV_MODE else ""
|
|
71
67
|
print(f"Error setting priority: {e} {error}")
|
|
72
68
|
pass
|
|
73
69
|
|
|
74
70
|
|
|
75
71
|
def get_config():
|
|
72
|
+
from exploitfarm.utils.config import ClientConfig
|
|
73
|
+
from exploitfarm.tui.config import inital_config_setup
|
|
74
|
+
from exploitfarm.tui.login import login_required
|
|
76
75
|
config = ClientConfig.read()
|
|
77
76
|
if not inital_config_setup(config):
|
|
78
77
|
raise ValueError("It's required to setup the client first")
|
|
@@ -137,6 +136,7 @@ def session(
|
|
|
137
136
|
"Accept-Language": "en-GB,en;q=0.8,it;q=0.7,en-US;q=0.6",
|
|
138
137
|
**additional_headers,
|
|
139
138
|
}
|
|
139
|
+
import requests
|
|
140
140
|
s = requests.Session()
|
|
141
141
|
s.headers.update(headers)
|
|
142
142
|
return s
|
|
@@ -155,7 +155,9 @@ class Store:
|
|
|
155
155
|
if not self.exploit_id:
|
|
156
156
|
raise ValueError("this exploit has to be run with xfarm")
|
|
157
157
|
self.login_token = os.getenv("XFARM_LOGIN_TOKEN", None)
|
|
158
|
-
self.
|
|
158
|
+
self.default_context_id = default_context_id
|
|
159
|
+
from exploitfarm.utils.reqs import get_session
|
|
160
|
+
self.session = get_session(self.login_token)
|
|
159
161
|
if default_context_id is not None:
|
|
160
162
|
self._keycheck(default_context_id, "default_context_id")
|
|
161
163
|
self.default_context_id = default_context_id
|
|
@@ -168,6 +170,14 @@ class Store:
|
|
|
168
170
|
return self.default_context_id
|
|
169
171
|
return None
|
|
170
172
|
|
|
173
|
+
def _requests_check_json(self, *args, **kwargs):
|
|
174
|
+
from exploitfarm.utils.reqs import requests_check_json
|
|
175
|
+
return requests_check_json(*args, **kwargs)
|
|
176
|
+
|
|
177
|
+
def _check_req(self, *args, **kwargs):
|
|
178
|
+
from exploitfarm.utils.reqs import check_req
|
|
179
|
+
return check_req(*args, **kwargs)
|
|
180
|
+
|
|
171
181
|
def _keycheck(self, key: str, what: str = "key"):
|
|
172
182
|
if not isinstance(key, str):
|
|
173
183
|
raise ValueError(f"{what} must be a string")
|
|
@@ -176,7 +186,7 @@ class Store:
|
|
|
176
186
|
if not re.match(r"^[A-Za-z0-9\-\._~()'!*:@,;]+$", key):
|
|
177
187
|
raise ValueError(rf"{what} must match this regex: ^[A-Za-z0-9\-\._~()'!*:@,;$]+$")
|
|
178
188
|
|
|
179
|
-
def get_bytes(self, key: str, default=None, context_id: str | None = None, timeout: int =
|
|
189
|
+
def get_bytes(self, key: str, default=None, context_id: str | None = None, timeout: int = 30) -> bytes:
|
|
180
190
|
context_id = self._get_context_id(context_id)
|
|
181
191
|
self._keycheck(key)
|
|
182
192
|
r = self.session.get(
|
|
@@ -186,9 +196,9 @@ class Store:
|
|
|
186
196
|
)
|
|
187
197
|
if r.status_code == 404:
|
|
188
198
|
return default
|
|
189
|
-
return
|
|
199
|
+
return self._check_req(r).content
|
|
190
200
|
|
|
191
|
-
def get(self, key: str, default=None, context_id: str | None = None, timeout: int =
|
|
201
|
+
def get(self, key: str, default=None, context_id: str | None = None, timeout: int = 30) -> bytes:
|
|
192
202
|
class TmpNotFound:
|
|
193
203
|
pass
|
|
194
204
|
data = self.get_bytes(key, context_id=context_id, default=TmpNotFound, timeout=timeout)
|
|
@@ -196,10 +206,10 @@ class Store:
|
|
|
196
206
|
return default
|
|
197
207
|
return pickle.loads(data)
|
|
198
208
|
|
|
199
|
-
def set_bytes(self, key: str, value: bytes, context_id: str | None = None, timeout: int =
|
|
209
|
+
def set_bytes(self, key: str, value: bytes, context_id: str | None = None, timeout: int = 30):
|
|
200
210
|
self._keycheck(key)
|
|
201
211
|
context_id = self._get_context_id(context_id)
|
|
202
|
-
return
|
|
212
|
+
return self._requests_check_json(
|
|
203
213
|
self.session.put(
|
|
204
214
|
urljoin(self.base_url, f"exploits/{self.exploit_id}/store/key/{key}"),
|
|
205
215
|
data=value,
|
|
@@ -209,14 +219,14 @@ class Store:
|
|
|
209
219
|
)
|
|
210
220
|
)
|
|
211
221
|
|
|
212
|
-
def set(self, key: str, value, context_id: str | None = None, timeout: int =
|
|
222
|
+
def set(self, key: str, value, context_id: str | None = None, timeout: int = 30):
|
|
213
223
|
value = pickle.dumps(value)
|
|
214
224
|
return self.set_bytes(key, value, context_id=context_id, timeout=timeout)
|
|
215
225
|
|
|
216
|
-
def delete(self, key: str, context_id: str | None = None, timeout: int =
|
|
226
|
+
def delete(self, key: str, context_id: str | None = None, timeout: int = 30):
|
|
217
227
|
self._keycheck(key)
|
|
218
228
|
context_id = self._get_context_id(context_id)
|
|
219
|
-
return
|
|
229
|
+
return self._requests_check_json(
|
|
220
230
|
self.session.delete(
|
|
221
231
|
urljoin(self.base_url, f"exploits/{self.exploit_id}/store/key/{key}"),
|
|
222
232
|
params={"context_id": context_id} if context_id else None,
|
|
@@ -224,9 +234,9 @@ class Store:
|
|
|
224
234
|
)
|
|
225
235
|
)
|
|
226
236
|
|
|
227
|
-
def keys(self, timeout: int =
|
|
237
|
+
def keys(self, timeout: int = 30, context_id: str | None = None) -> list[str]:
|
|
228
238
|
context_id = self._get_context_id(context_id)
|
|
229
|
-
return
|
|
239
|
+
return self._requests_check_json(
|
|
230
240
|
self.session.get(
|
|
231
241
|
urljoin(self.base_url, f"exploits/{self.exploit_id}/store/keys"),
|
|
232
242
|
params={ "context_id": context_id } if context_id else None,
|
|
@@ -234,20 +244,20 @@ class Store:
|
|
|
234
244
|
)
|
|
235
245
|
)
|
|
236
246
|
|
|
237
|
-
def contexts(self, timeout: int =
|
|
238
|
-
return
|
|
247
|
+
def contexts(self, timeout: int = 30) -> list[str]:
|
|
248
|
+
return self._requests_check_json(
|
|
239
249
|
self.session.get(
|
|
240
250
|
urljoin(self.base_url, f"exploits/{self.exploit_id}/store/contexts"),
|
|
241
251
|
timeout=timeout,
|
|
242
252
|
)
|
|
243
253
|
)
|
|
244
254
|
|
|
245
|
-
def delete_context(self, context_id: str | None = None, timeout: int =
|
|
255
|
+
def delete_context(self, context_id: str | None = None, timeout: int = 30):
|
|
246
256
|
context_id = self._get_context_id(context_id)
|
|
247
257
|
if not context_id:
|
|
248
258
|
raise ValueError("context_id must be provided to delete it")
|
|
249
259
|
self._keycheck(context_id, "context_id")
|
|
250
|
-
return
|
|
260
|
+
return self._requests_check_json(
|
|
251
261
|
self.session.delete(
|
|
252
262
|
urljoin(self.base_url, f"exploits/{self.exploit_id}/store/context/{context_id}"),
|
|
253
263
|
timeout=timeout,
|