exploitfarm 1.7.6__tar.gz → 1.7.7__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.
Files changed (47) hide show
  1. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/PKG-INFO +23 -9
  2. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/README.md +22 -8
  3. exploitfarm-1.7.7/exploitfarm/__init__.py +91 -0
  4. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/flags.py +1 -0
  5. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/xfarm.py +18 -17
  6. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/xploit.py +0 -3
  7. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm.egg-info/PKG-INFO +23 -9
  8. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/setup.py +1 -1
  9. exploitfarm-1.7.6/exploitfarm/__init__.py +0 -29
  10. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/MANIFEST.in +0 -0
  11. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/__main__.py +0 -0
  12. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/_init_exposed.py +0 -0
  13. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/__init__.py +0 -0
  14. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/client.py +0 -0
  15. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/dbtypes.py +0 -0
  16. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/enums.py +0 -0
  17. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/exploit.py +0 -0
  18. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/exploit_template.py +0 -0
  19. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/groups.py +0 -0
  20. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/response.py +0 -0
  21. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/service.py +0 -0
  22. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/submitter.py +0 -0
  23. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/models/teams.py +0 -0
  24. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/__init__.py +0 -0
  25. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/config.py +0 -0
  26. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/exploitdownload.py +0 -0
  27. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/exploitinit.py +0 -0
  28. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/group_prejoin.py +0 -0
  29. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/group_select.py +0 -0
  30. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/login.py +0 -0
  31. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/shared_attack_group.py +0 -0
  32. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/startxploit.py +0 -0
  33. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/tui/template.py +0 -0
  34. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/__init__.py +0 -0
  35. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/cmd.py +0 -0
  36. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/config.py +0 -0
  37. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/exploit.py +0 -0
  38. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/reqs.py +0 -0
  39. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/templates.py +0 -0
  40. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm/utils/windows_close_fix.py +0 -0
  41. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm.egg-info/SOURCES.txt +0 -0
  42. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm.egg-info/dependency_links.txt +0 -0
  43. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm.egg-info/requires.txt +0 -0
  44. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/exploitfarm.egg-info/top_level.txt +0 -0
  45. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/requirements.txt +0 -0
  46. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/setup.cfg +0 -0
  47. {exploitfarm-1.7.6 → exploitfarm-1.7.7}/xfarm +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exploitfarm
3
- Version: 1.7.6
3
+ Version: 1.7.7
4
4
  Summary: Exploit Farm client
5
5
  Home-page: https://github.com/pwnzer0tt1/exploitfarm
6
6
  Author: Pwnzer0tt1
@@ -98,15 +98,18 @@ submit_flags(flags)
98
98
  #### **Store Class**
99
99
 
100
100
  The `Store` class provides a key-value storage system for exploits, allowing you to save and retrieve centralized data during execution.
101
- The key value store is different for each exploit id. You can use it to store some data you need to save and change for every exploit execution.
101
+ The key value store is by default isolated per exploit id.
102
+ If you need data shared between exploits you should use a custom context_id that allows to access the same data from different exploits. The context_id can be set also in the constructor of the Store class, and will be used as default context_id for all the calls with that store instance.
102
103
 
103
104
  ```python
104
105
  from exploitfarm import Store
105
106
 
106
- store = Store()
107
+ # Initialize with an optional default context
108
+ store = Store(default_context_id="my_global_context_id")
107
109
 
108
- # Set a value
110
+ # Set a value (context_id can be overridden per call)
109
111
  store.set("example_key", {"example": "data"})
112
+ store.set("other_key", "value", context_id="explicit_ctx")
110
113
 
111
114
  # Get a value (if not exists returns None)
112
115
  data = store.get("example_key")
@@ -115,17 +118,28 @@ print(data)
115
118
  # Delete a key
116
119
  store.delete("example_key")
117
120
 
118
- # List all keys
121
+ # List all keys in the current context
119
122
  keys = store.keys()
120
123
  print(keys)
124
+
125
+ # List all available contexts
126
+ contexts = store.contexts()
127
+ print(contexts)
128
+
129
+ # Delete an entire context
130
+ store.delete_context(context_id="explicit_ctx")
121
131
  ```
122
132
 
123
133
  **Methods**:
124
134
 
125
- - `get(key: str, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a value by key.
126
- - `set(key: str, value: bytes, timeout: int = HTTP_TIMEOUT)`: Store a value by key.
127
- - `delete(key: str, timeout: int = HTTP_TIMEOUT)`: Delete a key.
128
- - `keys(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all stored keys.
135
+ - `get(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> any`: Retrieve and deserialize a value by key.
136
+ - `get_bytes(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a raw byte value.
137
+ - `set(key: str, value: any, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Serialize and store a value by key.
138
+ - `set_bytes(key: str, value: bytes, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Store a raw byte value.
139
+ - `delete(key: str, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete a key.
140
+ - `keys(timeout: int = HTTP_TIMEOUT, context_id: str | None = None) -> list[str]`: List all stored keys in a context.
141
+ - `contexts(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all available contexts.
142
+ - `delete_context(context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete an entire context and its keys.
129
143
 
130
144
  **Environment Variables Required**:
131
145
 
@@ -61,15 +61,18 @@ submit_flags(flags)
61
61
  #### **Store Class**
62
62
 
63
63
  The `Store` class provides a key-value storage system for exploits, allowing you to save and retrieve centralized data during execution.
64
- The key value store is different for each exploit id. You can use it to store some data you need to save and change for every exploit execution.
64
+ The key value store is by default isolated per exploit id.
65
+ If you need data shared between exploits you should use a custom context_id that allows to access the same data from different exploits. The context_id can be set also in the constructor of the Store class, and will be used as default context_id for all the calls with that store instance.
65
66
 
66
67
  ```python
67
68
  from exploitfarm import Store
68
69
 
69
- store = Store()
70
+ # Initialize with an optional default context
71
+ store = Store(default_context_id="my_global_context_id")
70
72
 
71
- # Set a value
73
+ # Set a value (context_id can be overridden per call)
72
74
  store.set("example_key", {"example": "data"})
75
+ store.set("other_key", "value", context_id="explicit_ctx")
73
76
 
74
77
  # Get a value (if not exists returns None)
75
78
  data = store.get("example_key")
@@ -78,17 +81,28 @@ print(data)
78
81
  # Delete a key
79
82
  store.delete("example_key")
80
83
 
81
- # List all keys
84
+ # List all keys in the current context
82
85
  keys = store.keys()
83
86
  print(keys)
87
+
88
+ # List all available contexts
89
+ contexts = store.contexts()
90
+ print(contexts)
91
+
92
+ # Delete an entire context
93
+ store.delete_context(context_id="explicit_ctx")
84
94
  ```
85
95
 
86
96
  **Methods**:
87
97
 
88
- - `get(key: str, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a value by key.
89
- - `set(key: str, value: bytes, timeout: int = HTTP_TIMEOUT)`: Store a value by key.
90
- - `delete(key: str, timeout: int = HTTP_TIMEOUT)`: Delete a key.
91
- - `keys(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all stored keys.
98
+ - `get(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> any`: Retrieve and deserialize a value by key.
99
+ - `get_bytes(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a raw byte value.
100
+ - `set(key: str, value: any, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Serialize and store a value by key.
101
+ - `set_bytes(key: str, value: bytes, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Store a raw byte value.
102
+ - `delete(key: str, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete a key.
103
+ - `keys(timeout: int = HTTP_TIMEOUT, context_id: str | None = None) -> list[str]`: List all stored keys in a context.
104
+ - `contexts(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all available contexts.
105
+ - `delete_context(context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete an entire context and its keys.
92
106
 
93
107
  **Environment Variables Required**:
94
108
 
@@ -0,0 +1,91 @@
1
+ def _get_version():
2
+ v = "1.7.7" if "{" not in "1.7.7" else "0.0.0"
3
+ if v == "0.0.0":
4
+ import os
5
+ env_v = os.getenv("EXPLOITFARM_VERSION")
6
+ if env_v:
7
+ return env_v
8
+ import re
9
+
10
+ def parse_version(ver):
11
+ ver = ver.lstrip("v")
12
+ parts = re.split(r'[^0-9]+', ver)
13
+ return tuple(int(p) if p.isdigit() else 0 for p in parts if p)
14
+
15
+ def find_git_dir(start_path):
16
+ current = start_path
17
+ while current and current != "/" and current != "":
18
+ gd = os.path.join(current, ".git")
19
+ if os.path.isdir(gd):
20
+ return gd
21
+ parent = os.path.dirname(current)
22
+ if parent == current:
23
+ break
24
+ current = parent
25
+ return None
26
+
27
+ try:
28
+ git_dir = find_git_dir(os.path.abspath(os.path.dirname(__file__)))
29
+ if not git_dir:
30
+ return v
31
+
32
+ branch = None
33
+ with open(os.path.join(git_dir, "HEAD"), "r") as f:
34
+ head = f.read().strip()
35
+ if head.startswith("ref: refs/heads/"):
36
+ branch = head.split("ref: refs/heads/")[1]
37
+
38
+ if branch != "main":
39
+ return v
40
+
41
+ tags = []
42
+ try:
43
+ with open(os.path.join(git_dir, "packed-refs"), "r") as f:
44
+ for line in f:
45
+ if " refs/tags/" in line:
46
+ tags.append(line.strip().split(" refs/tags/")[1])
47
+ except Exception:
48
+ pass
49
+
50
+ tags_dir = os.path.join(git_dir, "refs", "tags")
51
+ try:
52
+ for root, _, files in os.walk(tags_dir):
53
+ for file in files:
54
+ tags.append(os.path.relpath(os.path.join(root, file), tags_dir).replace(os.path.sep, "/"))
55
+ except Exception:
56
+ pass
57
+
58
+ version_tags = [t for t in set(tags) if any(c.isdigit() for c in t)]
59
+ if version_tags:
60
+ return max(version_tags, key=parse_version)
61
+ except Exception:
62
+ pass
63
+ return v
64
+
65
+ __version__ = _get_version()
66
+
67
+ from exploitfarm.utils import try_tcp_connection
68
+ from exploitfarm.models.enums import AttackMode, SetupStatus, FlagStatus
69
+ from exploitfarm.utils import DEV_MODE
70
+ from exploitfarm._init_exposed import get_host, Prio
71
+ from exploitfarm._init_exposed import nicenessify, get_config, random_str, print, Store
72
+ from exploitfarm._init_exposed import os_unix, os_windows, session
73
+
74
+ # Exported functions
75
+ __all__ = [
76
+ "try_tcp_connection",
77
+ "AttackMode",
78
+ "SetupStatus",
79
+ "get_host",
80
+ "get_config",
81
+ "random_str",
82
+ "session",
83
+ "print",
84
+ "nicenessify",
85
+ "Prio",
86
+ "FlagStatus",
87
+ "Store",
88
+ "DEV_MODE",
89
+ "os_unix",
90
+ "os_windows",
91
+ ]
@@ -21,6 +21,7 @@ class AttackExecutionDTO(BaseModel):
21
21
  executed_by: ClientID|None = Field(None, validation_alias=AliasChoices('executed_by_id'))
22
22
  executed_by_group: AttackGroupID|None = Field(None, validation_alias=AliasChoices('executed_by_group_id'))
23
23
  flags: list[FlagDTOSmall]
24
+ duplicate_flags: list[str] = []
24
25
  exploit_source: ExploitSourceID|None = Field(None, validation_alias=AliasChoices('exploit_source_id'))
25
26
 
26
27
  class FlagDTOAttackDetails(BaseModel):
@@ -123,28 +123,29 @@ def fast_check_exploit_conf_service(exploit_config: ExploitConfig) -> ExploitCon
123
123
 
124
124
 
125
125
  def auto_push_is_safe(exploit_config: ExploitConfig):
126
- no_latest_groups = (
127
- len(
128
- [
129
- g
130
- for g in g.config.reqs.groups()
131
- if g["exploit"] == str(exploit_config.uuid) and g["commit"] == "latest"
132
- ]
133
- )
134
- == 0
135
- )
136
- if no_latest_groups:
126
+ # Since groups always use the latest version, check if there are ANY groups using this exploit
127
+ active_groups = [
128
+ gr
129
+ for gr in g.config.reqs.groups()
130
+ if gr.get("exploit") == str(exploit_config.uuid)
131
+ ]
132
+
133
+ if len(active_groups) == 0:
137
134
  return True
138
135
  else:
139
136
  current_hash = exploit_config.hash()
140
- if current_hash in [
141
- ele["hash"] for ele in g.config.reqs.exploit_source_log(exploit_config.uuid)
142
- ]: # If the current commit is pushed
143
- return True
137
+ try:
138
+ # If the exact source version is already pushed, it's safe
139
+ pushed_hashes = [ele["hash"] for ele in g.config.reqs.exploit_source_log(exploit_config.uuid)]
140
+ if current_hash in pushed_hashes:
141
+ return True
142
+ except Exception:
143
+ pass
144
+
144
145
  if g.interactive:
145
146
  return typer.confirm(
146
- "There are attack groups that are using the latest commit, "
147
- "this command is trying to push a new version of the exploit. "
147
+ "There are active attack groups using this exploit. "
148
+ "Pushing a new version will update them to the new code. "
148
149
  "Do you want to continue?",
149
150
  default=False,
150
151
  )
@@ -55,7 +55,6 @@ class g:
55
55
  server_id = None
56
56
  thread_pool: ThreadPoolExecutor = None
57
57
  tot_teams: int = 0
58
- flag_cache: set = set()
59
58
  attack_round_deadline = dt_now()
60
59
  exploit_hash: str | None = None
61
60
  virtual_time_available = 0
@@ -198,8 +197,6 @@ class AttackStorage:
198
197
  stats: bool = True,
199
198
  ):
200
199
  with self._lock:
201
- flags = [flag for flag in flags if flag not in g.flag_cache]
202
- g.flag_cache.update(flags)
203
200
  execution_submit = {
204
201
  "start_time": start_time,
205
202
  "end_time": end_time,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exploitfarm
3
- Version: 1.7.6
3
+ Version: 1.7.7
4
4
  Summary: Exploit Farm client
5
5
  Home-page: https://github.com/pwnzer0tt1/exploitfarm
6
6
  Author: Pwnzer0tt1
@@ -98,15 +98,18 @@ submit_flags(flags)
98
98
  #### **Store Class**
99
99
 
100
100
  The `Store` class provides a key-value storage system for exploits, allowing you to save and retrieve centralized data during execution.
101
- The key value store is different for each exploit id. You can use it to store some data you need to save and change for every exploit execution.
101
+ The key value store is by default isolated per exploit id.
102
+ If you need data shared between exploits you should use a custom context_id that allows to access the same data from different exploits. The context_id can be set also in the constructor of the Store class, and will be used as default context_id for all the calls with that store instance.
102
103
 
103
104
  ```python
104
105
  from exploitfarm import Store
105
106
 
106
- store = Store()
107
+ # Initialize with an optional default context
108
+ store = Store(default_context_id="my_global_context_id")
107
109
 
108
- # Set a value
110
+ # Set a value (context_id can be overridden per call)
109
111
  store.set("example_key", {"example": "data"})
112
+ store.set("other_key", "value", context_id="explicit_ctx")
110
113
 
111
114
  # Get a value (if not exists returns None)
112
115
  data = store.get("example_key")
@@ -115,17 +118,28 @@ print(data)
115
118
  # Delete a key
116
119
  store.delete("example_key")
117
120
 
118
- # List all keys
121
+ # List all keys in the current context
119
122
  keys = store.keys()
120
123
  print(keys)
124
+
125
+ # List all available contexts
126
+ contexts = store.contexts()
127
+ print(contexts)
128
+
129
+ # Delete an entire context
130
+ store.delete_context(context_id="explicit_ctx")
121
131
  ```
122
132
 
123
133
  **Methods**:
124
134
 
125
- - `get(key: str, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a value by key.
126
- - `set(key: str, value: bytes, timeout: int = HTTP_TIMEOUT)`: Store a value by key.
127
- - `delete(key: str, timeout: int = HTTP_TIMEOUT)`: Delete a key.
128
- - `keys(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all stored keys.
135
+ - `get(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> any`: Retrieve and deserialize a value by key.
136
+ - `get_bytes(key: str, default=None, context_id: str | None = None, timeout: int = HTTP_TIMEOUT) -> bytes`: Retrieve a raw byte value.
137
+ - `set(key: str, value: any, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Serialize and store a value by key.
138
+ - `set_bytes(key: str, value: bytes, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Store a raw byte value.
139
+ - `delete(key: str, context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete a key.
140
+ - `keys(timeout: int = HTTP_TIMEOUT, context_id: str | None = None) -> list[str]`: List all stored keys in a context.
141
+ - `contexts(timeout: int = HTTP_TIMEOUT) -> list[str]`: List all available contexts.
142
+ - `delete_context(context_id: str | None = None, timeout: int = HTTP_TIMEOUT)`: Delete an entire context and its keys.
129
143
 
130
144
  **Environment Variables Required**:
131
145
 
@@ -10,7 +10,7 @@ with open("requirements.txt", "r", encoding="utf-8") as f:
10
10
  if not ele.strip().startswith("#") and ele.strip() != ""
11
11
  ]
12
12
 
13
- VERSION = "1.7.6"
13
+ VERSION = "1.7.7"
14
14
 
15
15
  setuptools.setup(
16
16
  name="exploitfarm",
@@ -1,29 +0,0 @@
1
- __version__ = (
2
- "1.7.6" if "{" not in "1.7.6" else "0.0.0"
3
- )
4
-
5
- from exploitfarm.utils import try_tcp_connection
6
- from exploitfarm.models.enums import AttackMode, SetupStatus, FlagStatus
7
- from exploitfarm.utils import DEV_MODE
8
- from exploitfarm._init_exposed import get_host, Prio
9
- from exploitfarm._init_exposed import nicenessify, get_config, random_str, print, Store
10
- from exploitfarm._init_exposed import os_unix, os_windows, session
11
-
12
- # Exported functions
13
- __all__ = [
14
- "try_tcp_connection",
15
- "AttackMode",
16
- "SetupStatus",
17
- "get_host",
18
- "get_config",
19
- "random_str",
20
- "session",
21
- "print",
22
- "nicenessify",
23
- "Prio",
24
- "FlagStatus",
25
- "Store",
26
- "DEV_MODE",
27
- "os_unix",
28
- "os_windows",
29
- ]
File without changes
File without changes
File without changes