sandbox-cli 0.2.40__tar.gz → 0.2.42__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.40 → sandbox_cli-0.2.42}/PKG-INFO +4 -4
  2. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/pyproject.toml +4 -4
  3. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/reporter.py +6 -3
  4. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/scanner/__init__.py +9 -0
  5. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/downloader/__init__.py +18 -0
  6. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/scanner/advanced.py +3 -0
  7. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/.gitignore +0 -0
  8. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/LICENSE +0 -0
  9. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/NOTICE +0 -0
  10. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/README.md +0 -0
  11. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/__main__.py +0 -0
  12. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/__init__.py +0 -0
  13. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/downloader.py +0 -0
  14. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/images.py +0 -0
  15. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/rules/__init__.py +0 -0
  16. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/cli/unpack.py +0 -0
  17. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/console.py +0 -0
  18. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/internal/__init__.py +0 -0
  19. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/internal/config.py +0 -0
  20. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/internal/helpers.py +0 -0
  21. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/models/__init__.py +0 -0
  22. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/models/detections.py +0 -0
  23. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/models/sandbox_arguments.py +0 -0
  24. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/__init__.py +0 -0
  25. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/compiler/__init__.py +0 -0
  26. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/compiler/abc.py +0 -0
  27. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/compiler/docker.py +0 -0
  28. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/compiler/ssh.py +0 -0
  29. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/extractors.py +0 -0
  30. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/merge_dll_hooks.py +0 -0
  31. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/scanner/__init__.py +0 -0
  32. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/scanner/rescan.py +0 -0
  33. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/unpack/__init__.py +0 -0
  34. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/unpack/plugins/__init__.py +0 -0
  35. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/unpack/plugins/abc.py +0 -0
  36. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/unpack/plugins/correlation.py +0 -0
  37. {sandbox_cli-0.2.40 → sandbox_cli-0.2.42}/sandbox_cli/utils/unpack/plugins/sort_by_plugins.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sandbox-cli
3
- Version: 0.2.40
3
+ Version: 0.2.42
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.1
18
+ Requires-Dist: cyclopts>=3.24.0
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.40"
3
+ version = "0.2.42"
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.1",
15
+ "cyclopts>=3.24.0",
16
16
  "docker>=7.1.0",
17
17
  "ptsandbox>=5.0.6",
18
18
  "pyzipper>=0.3.6",
@@ -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,6 +130,7 @@ 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
134
  "sandbox": link,
134
135
  }
135
136
  )
@@ -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 _:
@@ -465,6 +465,14 @@ async def scan_new(
465
465
  validator=validators.Number(gt=0),
466
466
  ),
467
467
  ] = 300,
468
+ wait_timeout: Annotated[
469
+ int | None,
470
+ Parameter(
471
+ name=["--wait-timeout", "-W"],
472
+ help="Task waiting time in seconds (useful for heavy samples)",
473
+ validator=validators.Number(gt=0),
474
+ ),
475
+ ] = None,
468
476
  fake_name: Annotated[
469
477
  str | None,
470
478
  Parameter(
@@ -735,6 +743,7 @@ async def scan_new(
735
743
  vnc_mode=vnc_mode,
736
744
  extra_files=extra_files,
737
745
  upload_timeout=upload_timeout,
746
+ wait_timeout=wait_timeout,
738
747
  all=all,
739
748
  debug=debug,
740
749
  artifacts=artifacts,
@@ -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
 
@@ -219,6 +219,7 @@ async def scan_internal_advanced(
219
219
  vnc_mode: VNCMode,
220
220
  extra_files: list[Path] | None,
221
221
  upload_timeout: int,
222
+ wait_timeout: int | None,
222
223
  all: bool,
223
224
  debug: bool,
224
225
  artifacts: bool,
@@ -264,6 +265,8 @@ async def scan_internal_advanced(
264
265
  task = next(t for t in progress.tasks if t.id == task_id)
265
266
 
266
267
  wait_time = sandbox_options.analysis_duration * 4 + (300 if sandbox_options.analysis_duration < 80 else 120)
268
+ if wait_timeout is not None:
269
+ wait_time = wait_timeout
267
270
 
268
271
  try:
269
272
  scan_result = await sandbox.create_advanced_scan(
File without changes
File without changes
File without changes
File without changes