assemblyline-v4-service 4.6.1.dev248__py3-none-any.whl → 4.7.0.dev31__py3-none-any.whl

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.
@@ -417,22 +417,22 @@ class SandboxMachineMetadata:
417
417
 
418
418
  def __init__(
419
419
  self,
420
- # The IP of the machine used for analysis.
420
+ # The IP address of the analysis machine.
421
421
  ip: Optional[str] = None,
422
422
 
423
- # The hypervisor of the machine used for analysis.
423
+ # The hypervisor used by the analysis machine (e.g., VMware, KVM).
424
424
  hypervisor: Optional[str] = None,
425
425
 
426
- # The name of the machine used for analysis.
426
+ # The hostname of the machine used for analysis.
427
427
  hostname: Optional[str] = None,
428
428
 
429
- # The platform of the machine used for analysis.
429
+ # The platform or operating system name (e.g., Windows, Linux, macOS).
430
430
  platform: Optional[str] = None,
431
431
 
432
- # The version of the operating system of the machine used for analysis.
432
+ # The version of the operating system.
433
433
  version: Optional[str] = None,
434
434
 
435
- # The architecture of the machine used for analysis.
435
+ # The architecture of the operating system (e.g., x86, x64, ARM).
436
436
  architecture: Optional[str] = None,
437
437
  ):
438
438
  self.ip = ip
@@ -453,96 +453,157 @@ class SandboxMachineMetadata:
453
453
  "architecture": self.architecture,
454
454
  }
455
455
 
456
+ LookupType = Literal[
457
+ "A", "AAAA", "AFSDB", "APL", "CAA", "CDNSKEY", "CDS", "CERT", "CNAME", "CSYNC",
458
+ "DHCID", "DLV", "DNAME", "DNSKEY", "DS", "EUI48", "EUI64", "HINFO", "HIP",
459
+ "HTTPS", "IPSECKEY", "KEY", "KX", "LOC", "MX", "NAPTR", "NS", "NSEC", "NSEC3",
460
+ "NSEC3PARAM", "OPENPGPKEY", "PTR", "RRSIG", "RP", "SIG", "SMIMEA", "SOA",
461
+ "SRV", "SSHFP", "SVCB", "TA", "TKEY", "TLSA", "TSIG", "TXT", "URI", "ZONEMD"
462
+ ]
463
+
464
+ RequestMethod = Literal[
465
+ "GET", "POST", "PUT", "DELETE", "HEAD", "CONNECT", "OPTIONS", "TRACE", "PATCH",
466
+ "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "COPY", "LOCK",
467
+ "MKCOL", "MOVE", "NOTIFY", "POLL", "PROPFIND", "PROPPATCH", "SEARCH",
468
+ "SUBSCRIBE", "UNLOCK", "UNSUBSCRIBE", "X-MS-ENUMATTS"
469
+ ]
470
+
471
+ ConnectionType = Literal["http", "dns", "tls", "smtp"]
472
+ ConnectionDirection = Literal["outbound", "inbound", "unknown"]
473
+ SignatureType = Literal["CUCKOO", "YARA", "SIGMA", "SURICATA"]
474
+
475
+ class SandboxMachineMetadata:
476
+ """Information about the sandbox machine used during analysis."""
477
+
478
+ def __init__(
479
+ self,
480
+ # The IP address of the machine used for analysis.
481
+ ip: Optional[str] = None,
482
+
483
+ # The hypervisor type of the machine used for analysis.
484
+ hypervisor: Optional[str] = None,
485
+
486
+ # The hostname of the machine used for analysis.
487
+ hostname: Optional[str] = None,
488
+
489
+ # The operating system platform of the machine (e.g., "Windows", "Linux").
490
+ platform: Optional[str] = None,
491
+
492
+ # The version of the operating system.
493
+ version: Optional[str] = None,
494
+
495
+ # The system architecture of the machine (e.g., "x64", "arm64").
496
+ architecture: Optional[str] = None,
497
+ ):
498
+ self.ip = ip
499
+ self.hypervisor = hypervisor
500
+ self.hostname = hostname
501
+ self.platform = platform
502
+ self.version = version
503
+ self.architecture = architecture
504
+
505
+ def as_primitives(self) -> Dict[str, Any]:
506
+ return {
507
+ "ip": self.ip,
508
+ "hypervisor": self.hypervisor,
509
+ "hostname": self.hostname,
510
+ "platform": self.platform,
511
+ "version": self.version,
512
+ "architecture": self.architecture,
513
+ }
514
+
456
515
 
457
516
  class SandboxAnalysisMetadata:
458
- """Metadata regarding the sandbox analysis task."""
517
+ """Metadata describing the context and configuration of a sandbox analysis."""
459
518
 
460
519
  def __init__(
461
520
  self,
462
- # The ID used for identifying the analysis task.
463
- task_id: Optional[str] = None,
521
+ # The unique identifier of the analysis task.
522
+ task_id: Optional[int] = None,
464
523
 
465
- # The start time of the analysis (ISO format).
524
+ # The timestamp when the analysis started (ISO 8601 format).
466
525
  start_time: str = "",
467
526
 
468
- # The end time of the analysis (ISO format).
527
+ # The timestamp when the analysis ended (ISO 8601 format).
469
528
  end_time: Optional[str] = None,
470
529
 
471
- # The routing used in the sandbox setup. (e.g., Spoofed, Internet, Tor, VPN)
530
+ # The network routing used during analysis (e.g., "Spoofed", "Internet", "Tor", "VPN").
472
531
  routing: Optional[str] = None,
473
532
 
474
- # The resolution used for the analysis.
533
+ # The screen resolution or window size used for the sandbox environment.
475
534
  window_size: Optional[str] = None,
535
+
536
+ # Metadata describing the machine on which the analysis ran.
537
+ machine_metadata: Optional[SandboxMachineMetadata] = None,
476
538
  ):
477
539
  self.task_id = task_id
478
540
  self.start_time = start_time
479
541
  self.end_time = end_time
480
542
  self.routing = routing
481
543
  self.window_size = window_size
544
+ self.machine_metadata = machine_metadata
482
545
 
483
- def as_primitives(self) -> Dict:
484
- """Return a JSON-serializable representation."""
546
+ def as_primitives(self) -> Dict[str, Any]:
485
547
  return {
486
548
  "task_id": self.task_id,
487
549
  "start_time": self.start_time,
488
550
  "end_time": self.end_time,
489
551
  "routing": self.routing,
490
552
  "window_size": self.window_size,
553
+ "machine_metadata": (
554
+ self.machine_metadata.as_primitives() if self.machine_metadata else None
555
+ ),
491
556
  }
492
557
 
493
558
 
494
559
  class SandboxProcessItem:
495
- """Represents a process observed during sandbox execution."""
560
+ """Information about a process observed during sandbox execution."""
496
561
 
497
562
  def __init__(
498
563
  self,
499
-
500
- # The image of the process. Default: "<unknown_image>".
564
+ # The executable image name of the process. Default: "<unknown_image>".
501
565
  image: str,
502
566
 
503
- # The time of creation for the process. (ISO date format)
567
+ # The timestamp when the process started (ISO 8601 format).
504
568
  start_time: str,
505
569
 
506
- # The process ID of the parent process.
570
+ # Name of the sources who identified this information
571
+ sources: Optional[List[str]],
572
+
573
+ # The parent process ID (PPID).
507
574
  ppid: Optional[int] = None,
508
575
 
509
- # The process ID.
576
+ # The process ID (PID).
510
577
  pid: Optional[int] = None,
511
578
 
512
- # The command line that the process ran.
579
+ # The full command line used to start the process.
513
580
  command_line: Optional[str] = None,
514
581
 
515
- # The time of termination for the process. (ISO date format)
582
+ # The timestamp when the process terminated (ISO 8601 format).
516
583
  end_time: Optional[str] = None,
517
584
 
518
- # The integrity level of the process.
585
+ # The integrity level of the process (e.g., "High", "Medium", "Low").
519
586
  integrity_level: Optional[str] = None,
520
587
 
521
- # The hash of the file run.
588
+ # The hash of the executable file for the process (e.g., SHA256).
522
589
  image_hash: Optional[str] = None,
523
590
 
524
- # The original name of the file.
591
+ # The original file name as embedded in the binary metadata.
525
592
  original_file_name: Optional[str] = None,
526
593
 
527
- # Whether this process was safelisted.
594
+ # Indicates whether this process was safelisted (whitelisted).
528
595
  safelisted: Optional[bool] = False,
529
596
 
530
- # Number of files this process interacted with
531
- file_count: int = 0,
597
+ # The number of file I/O events associated with this process.
598
+ file_count: Optional[int] = 0,
532
599
 
533
- # Number of registries this process interacted with
534
- registry_count: int = 0,
600
+ # The number of registry modification events associated with this process.
601
+ registry_count: Optional[int] = 0,
535
602
  ):
536
- # ----------------------------
537
- # Core process information
538
- # ----------------------------
539
603
  self.image = image or "<unknown_image>"
540
604
  self.start_time = start_time
541
-
542
- # Parent process information
605
+ self.sources = sources or []
543
606
  self.ppid = ppid
544
-
545
- # Current process information
546
607
  self.pid = pid
547
608
  self.command_line = command_line
548
609
  self.end_time = end_time
@@ -550,18 +611,14 @@ class SandboxProcessItem:
550
611
  self.image_hash = image_hash
551
612
  self.original_file_name = original_file_name
552
613
  self.safelisted = safelisted
553
-
554
- # ----------------------------
555
- # Relationships & statistics
556
- # ----------------------------
557
614
  self.file_count = file_count
558
615
  self.registry_count = registry_count
559
616
 
560
- def as_primitives(self) -> Dict:
561
- """Return a JSON-serializable dictionary representation of this process."""
617
+ def as_primitives(self) -> Dict[str, Any]:
562
618
  return {
563
619
  "image": self.image,
564
620
  "start_time": self.start_time,
621
+ "sources": self.sources,
565
622
  "ppid": self.ppid,
566
623
  "pid": self.pid,
567
624
  "command_line": self.command_line,
@@ -575,100 +632,82 @@ class SandboxProcessItem:
575
632
  }
576
633
 
577
634
 
578
- LookupType = Literal[
579
- "A", "AAAA", "AFSDB", "APL", "CAA", "CDNSKEY", "CDS", "CERT", "CNAME", "CSYNC",
580
- "DHCID", "DLV", "DNAME", "DNSKEY", "DS", "EUI48", "EUI64", "HINFO", "HIP",
581
- "HTTPS", "IPSECKEY", "KEY", "KX", "LOC", "MX", "NAPTR", "NS", "NSEC", "NSEC3",
582
- "NSEC3PARAM", "OPENPGPKEY", "PTR", "RRSIG", "RP", "SIG", "SMIMEA", "SOA",
583
- "SRV", "SSHFP", "SVCB", "TA", "TKEY", "TLSA", "TSIG", "TXT", "URI", "ZONEMD"
584
- ]
585
-
586
- RequestMethod = Literal[
587
- "GET", "POST", "PUT", "DELETE", "HEAD", "CONNECT", "OPTIONS", "TRACE", "PATCH",
588
- "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "COPY", "LOCK",
589
- "MKCOL", "MOVE", "NOTIFY", "POLL", "PROPFIND", "PROPPATCH", "SEARCH",
590
- "SUBSCRIBE", "UNLOCK", "UNSUBSCRIBE", "X-MS-ENUMATTS"
591
- ]
592
-
593
- ConnectionType = Literal["http", "dns", "tls", "smtp"]
594
-
595
- ConnectionDirection = Literal["outbound", "inbound", "unknown"]
596
635
 
597
636
 
598
637
  class SandboxNetworkDNS:
599
- """Details for a DNS request."""
638
+ """Details of a DNS query observed during sandbox execution."""
600
639
 
601
640
  def __init__(
602
641
  self,
642
+ # The domain name requested (queried).
603
643
  domain: str,
644
+
645
+ # The DNS lookup type (e.g., "A", "AAAA", "MX").
604
646
  lookup_type: LookupType,
647
+
648
+ # A list of IP addresses returned in the DNS response.
605
649
  resolved_ips: Optional[List[str]] = None,
650
+
651
+ # A list of domain names returned in the DNS response (for CNAMEs, etc.).
606
652
  resolved_domains: Optional[List[str]] = None,
607
653
  ):
608
- # The domain requested.
609
654
  self.domain = domain
610
-
611
- # A list of IPs that were resolved.
655
+ self.lookup_type = lookup_type
612
656
  self.resolved_ips = resolved_ips or []
613
-
614
- # A list of domains that were resolved.
615
657
  self.resolved_domains = resolved_domains or []
616
658
 
617
- # The type of DNS request.
618
- self.lookup_type = lookup_type
619
-
620
- def as_primitives(self) -> Dict:
659
+ def as_primitives(self) -> Dict[str, Any]:
621
660
  return {
622
661
  "domain": self.domain,
662
+ "lookup_type": self.lookup_type,
623
663
  "resolved_ips": self.resolved_ips,
624
664
  "resolved_domains": self.resolved_domains,
625
- "lookup_type": self.lookup_type,
626
665
  }
627
666
 
628
667
 
629
668
  class SandboxNetworkHTTP:
630
- """Details for an HTTP request."""
669
+ """Details of an HTTP request/response observed during sandbox execution."""
631
670
 
632
671
  def __init__(
633
672
  self,
673
+ # The URI requested by the process.
634
674
  request_uri: str,
635
- request_headers: Optional[Dict[str, object]] = None,
675
+
676
+ # Headers included in the HTTP request.
677
+ request_headers: Optional[Dict[str, Any]] = None,
678
+
679
+ # The HTTP request method (e.g., "GET", "POST").
636
680
  request_method: Optional[RequestMethod] = None,
637
- response_headers: Optional[Dict[str, object]] = None,
681
+
682
+ # Headers included in the HTTP response.
683
+ response_headers: Optional[Dict[str, Any]] = None,
684
+
685
+ # The raw body content of the HTTP request.
638
686
  request_body: Optional[str] = None,
687
+
688
+ # The HTTP status code of the response (e.g., 200, 404).
639
689
  response_status_code: Optional[int] = None,
690
+
691
+ # The raw body content of the HTTP response.
640
692
  response_body: Optional[str] = None,
641
- response_content_fileinfo: Optional[Dict] = None,
693
+
694
+ # Metadata about any file contained in the HTTP response body.
695
+ response_content_fileinfo: Optional[Dict[str, Any]] = None,
696
+
697
+ # The MIME type of the HTTP response content.
642
698
  response_content_mimetype: Optional[str] = None,
643
699
  ):
644
- # The URI requested.
645
700
  self.request_uri = request_uri
646
-
647
- # Headers included in the request.
648
701
  self.request_headers = request_headers or {}
649
-
650
- # The method of the request.
651
702
  self.request_method = request_method
652
-
653
- # Headers included in the response.
654
703
  self.response_headers = response_headers or {}
655
-
656
- # The body of the request.
657
704
  self.request_body = request_body
658
-
659
- # The status code of the response.
660
705
  self.response_status_code = response_status_code
661
-
662
- # The body of the response.
663
706
  self.response_body = response_body
664
-
665
- # File information of the response content.
666
707
  self.response_content_fileinfo = response_content_fileinfo
667
-
668
- # MIME type returned by the server.
669
708
  self.response_content_mimetype = response_content_mimetype
670
709
 
671
- def as_primitives(self) -> Dict:
710
+ def as_primitives(self) -> Dict[str, Any]:
672
711
  return {
673
712
  "request_uri": self.request_uri,
674
713
  "request_headers": self.request_headers,
@@ -683,24 +722,24 @@ class SandboxNetworkHTTP:
683
722
 
684
723
 
685
724
  class SandboxNetworkSMTP:
686
- """Details for an SMTP request."""
725
+ """Details of an SMTP email transaction observed during sandbox execution."""
687
726
 
688
727
  def __init__(
689
728
  self,
729
+ # The sender email address in the SMTP transaction.
690
730
  mail_from: str,
731
+
732
+ # A list of recipient email addresses in the SMTP transaction.
691
733
  mail_to: List[str],
692
- attachments: Optional[List[Dict]] = None,
734
+
735
+ # Information about any attachments transmitted via SMTP.
736
+ attachments: Optional[List[Dict[str, Any]]] = None,
693
737
  ):
694
- # Sender of the email.
695
738
  self.mail_from = mail_from
696
-
697
- # Recipients of the email.
698
739
  self.mail_to = mail_to
699
-
700
- # File information about the attachments.
701
740
  self.attachments = attachments or []
702
741
 
703
- def as_primitives(self) -> Dict:
742
+ def as_primitives(self) -> Dict[str, Any]:
704
743
  return {
705
744
  "mail_from": self.mail_from,
706
745
  "mail_to": self.mail_to,
@@ -709,51 +748,55 @@ class SandboxNetworkSMTP:
709
748
 
710
749
 
711
750
  class SandboxNetflowItem:
712
- """Details about a low-level network connection by IP."""
751
+ """Details of a network flow (connection) observed during sandbox execution."""
713
752
 
714
753
  def __init__(
715
754
  self,
716
-
717
- # The destination IP of the connection.
755
+ # The destination IP address of the network connection.
718
756
  destination_ip: Optional[str] = None,
719
757
 
720
- # The destination port of the connection.
758
+ # The destination port number of the connection.
721
759
  destination_port: Optional[int] = None,
722
760
 
723
- # The transport layer protocol (e.g., tcp, udp).
761
+ # The transport layer protocol used (e.g., "tcp", "udp").
724
762
  transport_layer_protocol: Optional[Literal["tcp", "udp"]] = None,
725
763
 
726
- # The direction of the network connection.
727
- direction: Optional[ConnectionDirection] = None,
764
+ # The direction of the network connection (e.g., "inbound", "outbound").
765
+ direction: Optional["ConnectionDirection"] = None,
728
766
 
729
- # PID of the process that spawned the network connection.
730
- pid: Optional[int] = None,
767
+ # The process ID that initiated or owned the network connection.
768
+ process: Optional[int] = None,
769
+
770
+ # Name of the sources who identified this information
771
+ sources: Optional[List[str]] = [],
731
772
 
732
- # The source IP of the connection.
773
+ # The source IP address of the connection.
733
774
  source_ip: Optional[str] = None,
734
775
 
735
- # The source port of the connection.
776
+ # The source port number of the connection.
736
777
  source_port: Optional[int] = None,
737
778
 
738
- time_observed: str = None,
779
+ # The timestamp when the network event was observed (ISO 8601 format).
780
+ time_observed: Optional[str] = None,
739
781
 
740
- # HTTP-specific details of the request.
741
- http_details: Optional[SandboxNetworkHTTP] = None,
782
+ # Detailed HTTP request/response data, if the flow is HTTP-related.
783
+ http_details: Optional["SandboxNetworkHTTP"] = None,
742
784
 
743
- # DNS-specific details of the request.
744
- dns_details: Optional[SandboxNetworkDNS] = None,
785
+ # Detailed DNS query/response data, if the flow is DNS-related.
786
+ dns_details: Optional["SandboxNetworkDNS"] = None,
745
787
 
746
- # SMTP-specific details of the request.
788
+ # Detailed SMTP email data, if the flow is SMTP-related.
747
789
  smtp_details: Optional[SandboxNetworkSMTP] = None,
748
790
 
749
- # Type of connection being made.
750
- connection_type: Optional[ConnectionType] = None,
791
+ # The type or category of the connection (e.g., "download", "upload").
792
+ connection_type: Optional["ConnectionType"] = None,
751
793
  ):
752
794
  self.destination_ip = destination_ip
753
795
  self.destination_port = destination_port
754
796
  self.transport_layer_protocol = transport_layer_protocol
755
797
  self.direction = direction
756
- self.pid = pid
798
+ self.process = process
799
+ self.sources = sources or []
757
800
  self.source_ip = source_ip
758
801
  self.source_port = source_port
759
802
  self.time_observed = time_observed
@@ -762,14 +805,14 @@ class SandboxNetflowItem:
762
805
  self.smtp_details = smtp_details
763
806
  self.connection_type = connection_type
764
807
 
765
- def as_primitives(self) -> Dict:
766
- """Return a JSON-serializable representation."""
808
+ def as_primitives(self) -> Dict[str, Any]:
767
809
  data: Dict[str, Any] = {
768
810
  "destination_ip": self.destination_ip,
769
811
  "destination_port": self.destination_port,
770
812
  "transport_layer_protocol": self.transport_layer_protocol,
771
813
  "direction": self.direction,
772
- "pid": self.pid,
814
+ "process": self.process,
815
+ "sources": self.sources,
773
816
  "source_ip": self.source_ip,
774
817
  "source_port": self.source_port,
775
818
  "time_observed": self.time_observed,
@@ -778,10 +821,8 @@ class SandboxNetflowItem:
778
821
 
779
822
  if self.http_details is not None:
780
823
  data["http_details"] = self.http_details.as_primitives()
781
-
782
824
  if self.dns_details is not None:
783
825
  data["dns_details"] = self.dns_details.as_primitives()
784
-
785
826
  if self.smtp_details is not None:
786
827
  data["smtp_details"] = self.smtp_details.as_primitives()
787
828
 
@@ -789,12 +830,17 @@ class SandboxNetflowItem:
789
830
 
790
831
 
791
832
  class SandboxAttackItem:
792
- """Represents a MITRE ATT&CK technique or pattern."""
833
+ """Describes an ATT&CK technique or tactic detected during sandbox execution."""
793
834
 
794
835
  def __init__(
795
836
  self,
837
+ # The MITRE ATT&CK technique ID (e.g., "T1059.001").
796
838
  attack_id: str,
797
- pattern: str = None,
839
+
840
+ # The name or pattern describing the attack behavior.
841
+ pattern: str,
842
+
843
+ # The list of categories or tactics associated with this attack.
798
844
  categories: List[str] = [],
799
845
  ):
800
846
  self.attack_id = attack_id
@@ -810,63 +856,62 @@ class SandboxAttackItem:
810
856
 
811
857
 
812
858
  class SandboxSignatureItem:
813
- """A signature that was raised during the analysis of the task."""
859
+ """Represents a detection signature triggered during analysis."""
814
860
 
815
861
  def __init__(
816
862
  self,
817
-
818
- # The name of the signature.
863
+ # The name of the detection signature.
819
864
  name: str,
820
865
 
821
- # Type of signature. One of: "CUCKOO", "YARA", "SIGMA", "SURICATA".
822
- type: Literal["CUCKOO", "YARA", "SIGMA", "SURICATA"],
866
+ # The source type of the signature (e.g., "CAPE", "CUCKOO").
867
+ type: Literal["CAPE", "CUCKOO"],
823
868
 
824
- # Classification of signature (e.g., "malicious", "benign").
825
- classification: str,
869
+ # Name of the sources who identified this information
870
+ sources: Optional[List[str]],
826
871
 
827
- # A list of ATT&CK patterns and categories of the signature.
828
- attacks: Optional[List[SandboxAttackItem]] = [],
872
+ # The classification of the signature (e.g., "malicious", "benign").
873
+ classification: str,
829
874
 
830
- # List of actors of the signature.
831
- actors: Optional[List[str]] = [],
875
+ # The list of ATT&CK patterns or related attack metadata linked to this signature.
876
+ attacks: Optional[List[SandboxAttackItem]] = None,
832
877
 
833
- # List of malware families of the signature.
834
- malware_families: Optional[List[str]] = [],
878
+ # The list of threat actors associated with this signature.
879
+ actors: Optional[List[str]] = None,
835
880
 
836
- # ID of the signature.
837
- signature_id: Optional[str] = None,
881
+ # The list of malware families linked to this signature.
882
+ malware_families: Optional[List[str]] = None,
838
883
 
839
- # Optional human-readable message.
840
- message: Optional[str] = None,
884
+ # A human-readable description of what the signature represents.
885
+ description: Optional[str] = None,
841
886
 
842
- # PIDs of the processes that generated the signature.
843
- pids: Optional[List[int]] = [],
887
+ # The list of process IDs (PIDs) that triggered the signature.
888
+ pid: Optional[List[int]] = None,
844
889
 
845
- # Score of the heuristic this signature belongs to
846
- score: int = None,
890
+ # The score or weight associated with the heuristic signature.
891
+ score: Optional[int] = None,
847
892
  ):
848
893
  self.name = name
849
894
  self.type = type
895
+ self.sources = sources or []
850
896
  self.classification = classification
851
- self.attacks = attacks
852
- self.actors = actors
853
- self.malware_families = malware_families
854
- self.signature_id = signature_id
855
- self.message = message
856
- self.pids = pids
897
+ self.attacks = attacks or []
898
+ self.actors = actors or []
899
+ self.malware_families = malware_families or []
900
+ self.description = description
901
+ self.pid = pid or []
857
902
  self.score = score
858
903
 
859
904
  def as_primitives(self) -> Dict[str, Any]:
860
905
  return {
861
906
  "name": self.name,
862
907
  "type": self.type,
908
+ "sources": self.sources,
863
909
  "classification": self.classification,
864
- "attacks": [a.as_primitives() for a in self.attacks] if self.attacks else None,
910
+ "attacks": [a.as_primitives() for a in self.attacks] if self.attacks else [],
865
911
  "actors": self.actors,
866
912
  "malware_families": self.malware_families,
867
- "signature_id": self.signature_id,
868
- "message": self.message,
869
- "pids": self.pids,
913
+ "description": self.description,
914
+ "pid": self.pid,
870
915
  "score": self.score,
871
916
  }
872
917
 
@@ -874,32 +919,33 @@ class SandboxSignatureItem:
874
919
 
875
920
 
876
921
  class SandboxSectionBody(SectionBody):
877
- """
878
- Represents the structured body of a sandbox analysis section.
879
- Collects all sandbox-relevant entities: sandbox metadata, processes, network flows, and signatures.
880
- """
922
+ """The main sandbox analysis body containing all observed data and metadata."""
881
923
 
882
924
  def __init__(self) -> None:
883
925
  super().__init__(BODY_FORMAT.SANDBOX, body={
884
- "sandbox_name": None,
885
- "sandbox_version": None,
886
- "machine_metadata": None,
887
- "analysis_metadata": None,
926
+ "analysis_information": None,
888
927
  "processes": [],
889
- "netflows": [],
928
+ "network_connections": [],
890
929
  "signatures": [],
891
930
  })
892
931
 
893
- def set_sandbox(self, name: str, version: Optional[str], machine_metadata: SandboxMachineMetadata, analysis_metadata: SandboxAnalysisMetadata) -> None:
894
- """Set the sandbox metadata (name, version, machine info, and analysis info)."""
895
- self._data["sandbox_name"] = name
896
- self._data["sandbox_version"] = version
897
- self._data["machine_metadata"] = (
898
- machine_metadata.as_primitives() if machine_metadata else None
899
- )
900
- self._data["analysis_metadata"] = (
901
- analysis_metadata.as_primitives() if analysis_metadata else None
902
- )
932
+ def set_analysis_information(
933
+ self,
934
+ # The name of the sandbox used to perform the analysis.
935
+ sandbox_name: str,
936
+
937
+ # The version of the sandbox software.
938
+ sandbox_version: str,
939
+
940
+ # Metadata about when and how the analysis was executed.
941
+ analysis_metadata: SandboxAnalysisMetadata,
942
+ ) -> None:
943
+ """Set the general analysis information for the sandbox execution."""
944
+ self._data["analysis_information"] = {
945
+ "sandbox_name": sandbox_name,
946
+ "sandbox_version": sandbox_version,
947
+ "analysis_metadata": analysis_metadata.as_primitives(),
948
+ }
903
949
 
904
950
  def add_process(self, process: SandboxProcessItem) -> None:
905
951
  """Add a single process to the sandbox result."""
@@ -908,42 +954,38 @@ class SandboxSectionBody(SectionBody):
908
954
  self._data["processes"].append(process.as_primitives())
909
955
 
910
956
  def add_processes(self, processes: List[SandboxProcessItem]) -> None:
911
- """Add multiple processes at once."""
957
+ """Add multiple processes to the sandbox result."""
912
958
  for proc in processes:
913
959
  self.add_process(proc)
914
960
 
915
- def add_netflow(self, netflow: SandboxNetflowItem) -> None:
916
- """Add a network flow to the sandbox result."""
917
- if not isinstance(netflow, SandboxNetflowItem):
961
+ def add_network_connection(self, connection: SandboxNetflowItem) -> None:
962
+ """Add a single network connection to the sandbox result."""
963
+ if not isinstance(connection, SandboxNetflowItem):
918
964
  raise TypeError("Expected SandboxNetflowItem")
919
- self._data["netflows"].append(netflow.as_primitives())
965
+ self._data["network_connections"].append(connection.as_primitives())
920
966
 
921
- def add_netflows(self, netflows: List[SandboxNetflowItem]) -> None:
922
- """Add multiple network flows at once."""
923
- for nf in netflows:
924
- self.add_netflow(nf)
967
+ def add_network_connections(self, connections: List[SandboxNetflowItem]) -> None:
968
+ """Add multiple network connections to the sandbox result."""
969
+ for conn in connections:
970
+ self.add_network_connection(conn)
925
971
 
926
972
  def add_signature(self, signature: SandboxSignatureItem) -> None:
927
- """Add a detection signature to the sandbox result."""
973
+ """Add a single detection signature to the sandbox result."""
928
974
  if not isinstance(signature, SandboxSignatureItem):
929
975
  raise TypeError("Expected SandboxSignatureItem")
930
976
  self._data["signatures"].append(signature.as_primitives())
931
977
 
932
978
  def add_signatures(self, signatures: List[SandboxSignatureItem]) -> None:
933
- """Add multiple detection signatures at once."""
979
+ """Add multiple detection signatures to the sandbox result."""
934
980
  for sig in signatures:
935
981
  self.add_signature(sig)
936
982
 
937
-
938
983
  def as_primitives(self) -> Dict[str, Any]:
939
984
  """Return a fully JSON-serializable structure."""
940
985
  return {
941
- "sandbox_name": self._data["sandbox_name"],
942
- "sandbox_version": self._data["sandbox_version"],
943
- "machine_metadata": self._data["machine_metadata"],
944
- "analysis_metadata": self._data["analysis_metadata"],
986
+ "analysis_information": self._data["analysis_information"],
945
987
  "processes": self._data["processes"],
946
- "netflows": self._data["netflows"],
988
+ "network_connections": self._data["network_connections"],
947
989
  "signatures": self._data["signatures"],
948
990
  }
949
991
 
@@ -1343,48 +1385,43 @@ class ResultSandboxSection(TypeSpecificResultSection):
1343
1385
  self.section_body: SandboxSectionBody
1344
1386
  super().__init__(title_text, SandboxSectionBody(), **kwargs)
1345
1387
 
1346
- def set_sandbox(
1388
+ def set_analysis_information(
1347
1389
  self,
1348
- name: str,
1349
- version: Optional[str],
1350
- machine_metadata: Optional[SandboxMachineMetadata],
1390
+ sandbox_name: Optional[str],
1391
+ sandbox_version: Optional[str],
1351
1392
  analysis_metadata: Optional[SandboxAnalysisMetadata],
1352
1393
  ) -> None:
1353
- """Set the sandbox metadata (name, version, machine info, and analysis info)."""
1354
- self.section_body.set_sandbox(name, version, machine_metadata, analysis_metadata)
1394
+ """Set the general analysis information for the sandbox execution."""
1395
+ self.section_body.set_analysis_information(
1396
+ sandbox_name,
1397
+ sandbox_version,
1398
+ analysis_metadata,
1399
+ )
1355
1400
 
1356
1401
  def add_process(self, process: SandboxProcessItem) -> None:
1357
1402
  """Add a single process to the sandbox result."""
1358
1403
  self.section_body.add_process(process)
1359
1404
 
1360
1405
  def add_processes(self, processes: List[SandboxProcessItem]) -> None:
1361
- """Add multiple processes at once."""
1406
+ """Add multiple processes to the sandbox result."""
1362
1407
  self.section_body.add_processes(processes)
1363
1408
 
1364
- def add_netflow(self, netflow: SandboxNetflowItem) -> None:
1365
- """Add a single network flow to the sandbox result."""
1366
- self.section_body.add_netflow(netflow)
1409
+ def add_network_connection(self, connection: SandboxNetflowItem) -> None:
1410
+ """Add a single network connection to the sandbox result."""
1411
+ self.section_body.add_network_connection(connection)
1367
1412
 
1368
- def add_netflows(self, netflows: List[SandboxNetflowItem]) -> None:
1369
- """Add multiple network flows at once."""
1370
- self.section_body.add_netflows(netflows)
1413
+ def add_network_connections(self, connections: List[SandboxNetflowItem]) -> None:
1414
+ """Add multiple network connections to the sandbox result."""
1415
+ self.section_body.add_network_connections(connections)
1371
1416
 
1372
1417
  def add_signature(self, signature: SandboxSignatureItem) -> None:
1373
- """Add a detection signature to the sandbox result."""
1418
+ """Add a single detection signature to the sandbox result."""
1374
1419
  self.section_body.add_signature(signature)
1375
1420
 
1376
1421
  def add_signatures(self, signatures: List[SandboxSignatureItem]) -> None:
1377
- """Add multiple detection signatures at once."""
1422
+ """Add multiple detection signatures to the sandbox result."""
1378
1423
  self.section_body.add_signatures(signatures)
1379
1424
 
1380
- def add_heuristic(self, heuristic: SandboxHeuristicItem) -> None:
1381
- """Add a heuristic to the sandbox result."""
1382
- self.section_body.add_heuristic(heuristic)
1383
-
1384
- def add_heuristics(self, heuristics: List[SandboxHeuristicItem]) -> None:
1385
- """Add multiple heuristics at once."""
1386
- self.section_body.add_heuristics(heuristics)
1387
-
1388
1425
 
1389
1426
  class ResultTableSection(TypeSpecificResultSection):
1390
1427
  def __init__(self, title_text: Union[str, List], **kwargs):