Skip to content
Please update to the latest release 0.77.2 to address Multiple CVEs.
Windows.Network.NetstatEnriched

Windows.Network.NetstatEnriched

NetstatEnriched adds data enrichment to the Netstat artifact and provides extensive filtering options.

Examples include: Process name and path, Authenticode information or network connection details.

WARNING: KillProcess - attempts to kill the processes returned. DumpProcess - dumps the process as a sparse file for post-processing.

Please only use these switches after scoping as there are no guardrails on shooting yourself in the foot.


name: Windows.Network.NetstatEnriched
author: "Matt Green - @mgreen27"
description: |
  NetstatEnriched adds data enrichment to the Netstat artifact and
  provides extensive filtering options.

  Examples include: Process name and path, Authenticode information or
  network connection details.

  WARNING:
  KillProcess - attempts to kill the processes returned.
  DumpProcess - dumps the process as a sparse file for post-processing.

  Please only use these switches after scoping as there are no
  guardrails on shooting yourself in the foot.

required_permissions:
  - EXECVE

precondition: SELECT OS From info() where OS = 'windows'

parameters:
  - name: IPRegex
    description: "regex search over IP address fields."
    default:  .
    type: regex
  - name: PortRegex
    description: "regex search over port fields."
    default: .
    type: regex
  - name: Family
    description: "IP version family selection"
    type: choices
    default: ALL
    choices:
       - ALL
       - IPv4
       - IPv6
  - name: FamilyMap
    type: hidden
    default: |
      Choice,Regex
      ALL,"."
      IPv4,"^IPv4$"
      IPv6,"^IPv6$"

  - name: Type
    description: "Transport protocol type selection"
    type: choices
    default: ALL
    choices:
       - ALL
       - TCP
       - UDP
  - name: TypeMap
    type: hidden
    default: |
      Choice,Regex
      ALL,"."
      TCP,"^TCP$"
      UDP,"^UDP$"

  - name: Status
    description: "TCP status selection"
    type: choices
    default: ALL
    choices:
       - ALL
       - ESTABLISHED
       - LISTENING
       - OTHER
  - name: StatusMap
    type: hidden
    default: |
      Choice,Regex
      ALL,"."
      ESTABLISHED,"^ESTAB$"
      LISTENING,"^LISTEN$"
      OTHER,"CLOS|SENT|RCVD|LAST|WAIT|DELETE"

  - name: ProcessNameRegex
    description: "regex search over source process name"
    default: ^(malware\.exe|.*)$
    type: regex
  - name: ProcessPathRegex
    description: "regex search over source process path"
    default: .
    type: regex
  - name: CommandLineRegex
    description: "regex search over source process commandline"
    default: .
    type: regex
  - name: HashRegex
    description: "regex search over source process hash"
    default: .
    type: regex
  - name: UsernameRegex
    description: "regex search over source process user context"
    default: .
    type: regex
  - name: AuthenticodeSubjectRegex
    description: "regex search over source Authenticode Subject"
    default: .
    type: regex
  - name: AuthenticodeIssuerRegex
    description: "regex search over source Authenticode Issuer"
    default: .
    type: regex
  - name: AuthenticodeVerified
    description: "Authenticode signature selection"
    type: choices
    default: ALL
    choices:
       - ALL
       - TRUSTED
       - UNSIGNED
       - NOT TRUSTED
  - name: AuthenticodeVerifiedMap
    type: hidden
    default: |
      Choice,Regex
      ALL,"."
      TRUSTED,"^trusted$"
      UNSIGNED,"^unsigned$"
      NOT TRUSTED,"unsigned|disallowed|untrusted|error"
  - name: DumpProcess
    description: "WARNING: If selected will attempt to dump process from all results."
    type: bool
  - name: KillProcess
    description: "WARNING: If selected will attempt to kill process from all results."
    type: bool
  - name: DISABLE_DANGEROUS_API_CALLS
    type: bool
    description: |
      Enable this to disable potentially flakey APIs which may cause
      crashes.

sources:
  - name: Netstat
    query: |
      LET VerifiedRegex <= SELECT Regex
            FROM parse_csv(filename=AuthenticodeVerifiedMap, accessor="data")
            WHERE Choice=AuthenticodeVerified LIMIT 1
      LET StatusRegex <= SELECT Regex
            FROM parse_csv(filename=StatusMap, accessor="data")
            WHERE Choice=Status LIMIT 1
      LET FamilyRegex <= SELECT Regex
            FROM parse_csv(filename=FamilyMap, accessor="data")
            WHERE Choice=Family LIMIT 1
      LET TypeRegex <= SELECT Regex
            FROM parse_csv(filename=TypeMap, accessor="data")
            WHERE Choice=Type LIMIT 1

      LET process <= SELECT Pid as PsId,
            Ppid,
            Name,
            CommandLine,
            Exe,
            Hash,
            Authenticode,
            Username
        FROM Artifact.Windows.System.Pslist(
            DISABLE_DANGEROUS_API_CALLS=DISABLE_DANGEROUS_API_CALLS)
        WHERE Name =~ ProcessNameRegex
            AND Exe =~ ProcessPathRegex
            AND CommandLine =~ CommandLineRegex

      LET results = SELECT Pid,
                { SELECT Ppid FROM process WHERE PsId = Pid } as Ppid,
                { SELECT Name FROM process WHERE PsId = Pid } as Name,
                { SELECT Exe FROM process WHERE PsId = Pid } as Path,
                { SELECT CommandLine FROM process WHERE PsId = Pid } as CommandLine,
                { SELECT Hash FROM process WHERE PsId = Pid } as Hash,
                { SELECT Username FROM process WHERE PsId = Pid } as Username,
                { SELECT Authenticode FROM process WHERE PsId = Pid } as Authenticode,
                FamilyString as Family,
                TypeString as Type,
                Status,
                Laddr.IP as Laddr,
                Laddr.Port as Lport,
                Raddr.IP as Raddr,
                Raddr.Port as Rport,
                Timestamp
            FROM netstat()
            WHERE
                Name =~ ProcessNameRegex
                AND Path =~ ProcessPathRegex
                and CommandLine =~ CommandLineRegex
                and Username =~ UsernameRegex
                and ( Hash.MD5 =~ HashRegex
                  or Hash.SHA1 =~ HashRegex
                  or Hash.SHA256 =~ HashRegex
                  or not Hash )
                and ( Authenticode.IssuerName =~ AuthenticodeIssuerRegex or not Authenticode )
                and ( Authenticode.SubjectName =~ AuthenticodeSubjectRegex or not Authenticode )
                and ( Authenticode.Trusted =~ VerifiedRegex.Regex[0] or not Authenticode )
                and Status =~ StatusRegex.Regex[0]
                and Family =~ FamilyRegex.Regex[0]
                and Type =~ TypeRegex.Regex[0]
                and ( format(format="%v", args=Laddr) =~ IPRegex
                    or format(format="%v", args=Raddr) =~ IPRegex )
                and ( format(format="%v", args=Lport) =~ PortRegex
                    or format(format="%v", args=Rport) =~ PortRegex )

      LET Regions(Pid) = SELECT dict(Offset=Address, Length=Size) AS Sparse
        FROM vad(pid=Pid)
        WHERE Protection =~ "r"
      LET dump = SELECT *,
            upload(accessor="sparse",
                    file=pathspec(
                    Path=serialize(item=Regions(Pid=Pid).Sparse),
                    DelegateAccessor="process",
                    DelegatePath=format(format="/%d", args=Pid)),
                     name=pathspec(Path=format(format="%d.dd", args=Pid))) AS ProcessMemory
        FROM results
      LET kill = SELECT *, pskill(pid=Pid) AS KillProcess
        FROM results
      LET dumpandkill = SELECT *, pskill(pid=Pid) AS KillProcess
        FROM dump

      SELECT * FROM switch(
            a = {
                SELECT *, if(condition= KillProcess=Null,then='Success',else=KillProcess) AS KillProcess
                FROM if(condition= DumpProcess AND KillProcess, then= dumpandkill )},
            b = { SELECT * FROM if(condition= DumpProcess, then= dump )},
            c = {
                SELECT *, if(condition= KillProcess=Null,then='Success',else=KillProcess) AS KillProcess
                FROM if(condition= KillProcess, then= kill)
            },
            catch = results
        )