sandbox-cli 0.2.41__tar.gz → 0.2.43__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 (37) hide show
  1. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/PKG-INFO +4 -4
  2. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/pyproject.toml +4 -4
  3. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/__init__.py +4 -1
  4. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/reporter.py +7 -4
  5. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/downloader/__init__.py +18 -0
  6. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/unpack/plugins/correlation.py +3 -3
  7. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/unpack/plugins/sort_by_plugins.py +1 -1
  8. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/.gitignore +0 -0
  9. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/LICENSE +0 -0
  10. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/NOTICE +0 -0
  11. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/README.md +0 -0
  12. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/__main__.py +0 -0
  13. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/downloader.py +0 -0
  14. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/images.py +0 -0
  15. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/rules/__init__.py +0 -0
  16. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/scanner/__init__.py +0 -0
  17. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/cli/unpack.py +0 -0
  18. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/console.py +0 -0
  19. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/internal/__init__.py +0 -0
  20. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/internal/config.py +0 -0
  21. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/internal/helpers.py +0 -0
  22. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/models/__init__.py +0 -0
  23. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/models/detections.py +0 -0
  24. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/models/sandbox_arguments.py +0 -0
  25. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/__init__.py +0 -0
  26. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/compiler/__init__.py +0 -0
  27. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/compiler/abc.py +0 -0
  28. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/compiler/docker.py +0 -0
  29. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/compiler/ssh.py +0 -0
  30. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/extractors.py +0 -0
  31. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/merge_dll_hooks.py +0 -0
  32. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/scanner/__init__.py +0 -0
  33. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/scanner/advanced.py +0 -0
  34. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/scanner/rescan.py +0 -0
  35. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/unpack/__init__.py +0 -0
  36. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/unpack/plugins/__init__.py +0 -0
  37. {sandbox_cli-0.2.41 → sandbox_cli-0.2.43}/sandbox_cli/utils/unpack/plugins/abc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sandbox-cli
3
- Version: 0.2.41
3
+ Version: 0.2.43
4
4
  Summary: Command line tool for interaction with sandboxes
5
5
  Project-URL: Homepage, https://github.com/Security-Experts-Community/sandbox-cli
6
6
  Project-URL: Documentation, https://security-experts-community.github.io/sandbox-cli
@@ -12,10 +12,10 @@ License-File: LICENSE
12
12
  License-File: NOTICE
13
13
  Requires-Python: >=3.11
14
14
  Requires-Dist: aiofiles>=24.1.0
15
- Requires-Dist: asyncssh>=2.21.0
15
+ Requires-Dist: asyncssh>=2.21.1
16
16
  Requires-Dist: colorama>=0.4.6
17
- Requires-Dist: cryptography>=45.0.4
18
- Requires-Dist: cyclopts>=3.22.5
17
+ Requires-Dist: cryptography>=46.0.2
18
+ Requires-Dist: cyclopts>=4.2.5
19
19
  Requires-Dist: docker>=7.1.0
20
20
  Requires-Dist: ptsandbox>=5.0.6
21
21
  Requires-Dist: pyzipper>=0.3.6
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sandbox-cli"
3
- version = "0.2.41"
3
+ version = "0.2.43"
4
4
  description = "Command line tool for interaction with sandboxes"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -9,10 +9,10 @@ license-files = ["LICENSE", "NOTICE"]
9
9
  authors = [{ name = "Alexey Kolesnikov" }]
10
10
  dependencies = [
11
11
  "aiofiles>=24.1.0",
12
- "asyncssh>=2.21.0",
12
+ "asyncssh>=2.21.1",
13
13
  "colorama>=0.4.6",
14
- "cryptography>=45.0.4",
15
- "cyclopts>=3.22.5",
14
+ "cryptography>=46.0.2",
15
+ "cyclopts>=4.2.5",
16
16
  "docker>=7.1.0",
17
17
  "ptsandbox>=5.0.6",
18
18
  "pyzipper>=0.3.6",
@@ -10,7 +10,8 @@ from sandbox_cli.cli.unpack import unpack_logs
10
10
  from sandbox_cli.console import console
11
11
  from sandbox_cli.internal.config import configpath, settings
12
12
 
13
- init() # colorama stuff for working on windows
13
+ init() # colorama stuff for working on windows
14
+
14
15
 
15
16
  def get_version() -> str:
16
17
  import importlib.metadata
@@ -32,6 +33,8 @@ app = App(
32
33
  console=console,
33
34
  )
34
35
 
36
+ app.register_install_completion_command(add_to_startup=False)
37
+
35
38
  app.command(name=["conv", "unpack"])(unpack_logs)
36
39
  app.command(name="report")(generate_report)
37
40
  app.command(name="browser")(open_browser)
@@ -69,7 +69,7 @@ def generate_report(
69
69
  data: list[TableData] = []
70
70
  match mode:
71
71
  case "md":
72
- delimeter = " "
72
+ delimeter = "<br/>"
73
73
  case _:
74
74
  delimeter = "\n"
75
75
 
@@ -130,7 +130,8 @@ def generate_report(
130
130
  "static": delimeter.join(extract_static(report)),
131
131
  "memory": delimeter.join(extract_memory(report)),
132
132
  "network": delimeter.join(extract_network_from_trace(corr_trace)),
133
- "sandbox": f"[link={link}]{link}[/link]",
133
+ # "sandbox": f"[link={link}]{link}[/link]",
134
+ "sandbox": link,
134
135
  }
135
136
  )
136
137
 
@@ -142,7 +143,7 @@ def generate_report(
142
143
  | --- | --- | --- | --- | --- | --- | --- |"""
143
144
  ).strip()
144
145
 
145
- md_report_base = "|{sample}|{image}|{verdict}|{static}|{memory}|{network}|"
146
+ md_report_base = "|{sample}|{image}|{verdict}|{static}|{memory}|{network}|{sandbox}|"
146
147
  table_md = md_report_head + "\n"
147
148
  table_md += "\n".join(md_report_base.format(**d) for d in data)
148
149
  print(table_md)
@@ -157,6 +158,7 @@ def generate_report(
157
158
  table.add_column("Sandbox", overflow="fold")
158
159
 
159
160
  for d in data:
161
+ sandbox = f"[link={d['sandbox']}]{d['sandbox']}[/link]"
160
162
  table.add_row(
161
163
  d["sample"],
162
164
  d["image"],
@@ -164,7 +166,8 @@ def generate_report(
164
166
  d["static"],
165
167
  d["memory"],
166
168
  d["network"],
167
- d["sandbox"],
169
+ # special case for sandbox link
170
+ sandbox,
168
171
  )
169
172
  console.print(table)
170
173
  case _:
@@ -22,6 +22,17 @@ from sandbox_cli.console import console
22
22
 
23
23
  semaphore = asyncio.Semaphore(value=16)
24
24
 
25
+ # At first glance, it's counter-intuitive, but ArtifactType can contain not only predefined fields in it, but also newly added.
26
+ # This usually happens when a new feature is released in the sandbox.
27
+ _KNOWN_ARTIFACT_TYPES = {
28
+ ArtifactType.ARCHIVE,
29
+ ArtifactType.COMPRESSED,
30
+ ArtifactType.EMAIL,
31
+ ArtifactType.FILE,
32
+ ArtifactType.PROCESS_DUMP,
33
+ ArtifactType.URL,
34
+ }
35
+
25
36
 
26
37
  async def _save_artifact(
27
38
  scan_id: UUID,
@@ -202,6 +213,13 @@ async def download(
202
213
  decompress=decompress,
203
214
  )
204
215
 
216
+ if all and artifact.type not in _KNOWN_ARTIFACT_TYPES:
217
+ add_task(
218
+ output / "other",
219
+ artifact.file_info.sha256,
220
+ artifact.file_info.file_uri,
221
+ )
222
+
205
223
  if not tasks:
206
224
  console.info(f"Nothing to download from {report.scan_id}")
207
225
 
@@ -35,16 +35,16 @@ class CorrelatedRules(BasePlugin):
35
35
  pass
36
36
 
37
37
  if len(malware) > 0:
38
- with open(f"{file}.malware", "w", encoding="utf-8") as fd:
38
+ with open(base_path / "malware.log", "w", encoding="utf-8") as fd:
39
39
  for line in malware:
40
40
  fd.write(line)
41
41
 
42
42
  for key, lines in silent.items():
43
- with open(f"{file}.silent.{key}", "w", encoding="utf-8") as fd:
43
+ with open(base_path / f"{key}.silent.log", "w", encoding="utf-8") as fd:
44
44
  for line in lines:
45
45
  fd.write(line)
46
46
 
47
47
  for key, lines in suspicious.items():
48
- with open(f"{file}.suspicious.{key}", "w", encoding="utf-8") as fd:
48
+ with open(base_path / f"{key}.suspicious.log", "w", encoding="utf-8") as fd:
49
49
  for line in lines:
50
50
  fd.write(line)
@@ -23,6 +23,6 @@ class SortByPlugins(BasePlugin):
23
23
  plugins[data["plugin"]].append(line)
24
24
 
25
25
  for plugin, lines in plugins.items():
26
- with open(f"{file}.{plugin}", "w", encoding="utf-8") as fd:
26
+ with open(base_path / f"{plugin}.log", "w", encoding="utf-8") as fd:
27
27
  for line in lines:
28
28
  fd.write(line)
File without changes
File without changes
File without changes
File without changes