From 31d8614b07f3a506a6d81a5e084bc55065b9486a Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 20 May 2025 17:21:41 +1000 Subject: [PATCH 1/7] Implemented static analysis for client side permissions Client side artifacts run on the endpoint without ACL enforcement. This is usually what we want but sometimes the extra permissions can give the user extra permissions on the end point. The artifact writer can specify required permissions which will be enforced by the server prior to collecting the artifact. However, sometimes the artifact can use plugins with high priviledge safely - in that case we do not want to restrict the users that may collect it. For example say the artifact collects autoruns by shelling to the autoruns.exe tool. Even though it is using the execve() plugin this call is safe because the args are fixed and can not be influenced by the user. However if the artifact passed user input into the execve() plugin, the user requires the EXECVE permission. Previously, the artifact could declare EXECVE as a required permission, for artifact uses where user input was directly allowed in execve() calls. This enforces additional checks on the launching user to ensure they have the EXECVE permission. This PR modifies the artifact verifier to track plugin permissions used in the artifact. This allows us to see if the artifact inadvertantly gives the user permissions they do not have. This PR introduces another field to the artifact definition called `implied_permissions` where the artifact writer can declare permissions which the artifact will give but the user does not require those. This helps the verifier identify additional permissions that are accidentally given to users on the client. This PR adds a test to ensure built in artifacts have all necessary permissions declared either in `required_permissions` or `implied_permissions` --- .../Admin/Client/UpdateClientConfig.yaml | 4 + .../Admin/Client/Upgrade/Debian.yaml | 4 + .../Admin/Client/Upgrade/RedHat.yaml | 3 + .../Admin/Client/Upgrade/Windows.yaml | 4 + .../Generic/Client/CleanupTemp.yaml | 2 + .../definitions/Generic/Client/DiskSpace.yaml | 3 + artifacts/definitions/Generic/Client/VQL.yaml | 2 +- .../Generic/Forensic/LocalHashes/Init.yaml | 3 + .../Generic/Utils/FetchBinary.yaml | 4 + .../Linux/Network/PacketCapture.yaml | 9 +- .../definitions/Linux/RHEL/Packages.yaml | 4 + .../definitions/Linux/SuSE/Packages.yaml | 7 +- artifacts/definitions/Linux/Sys/Services.yaml | 11 +- .../definitions/Linux/Users/RootUsers.yaml | 3 + .../definitions/Linux/Utils/InstallDeb.yaml | 1 + .../MacOS/Network/PacketCapture.yaml | 9 +- .../definitions/MacOS/System/Packages.yaml | 13 +- .../Windows/ActiveDirectory/BloodHound.yaml | 3 + .../Applications/NirsoftBrowserViewer.yaml | 4 + .../Windows/Applications/SBECmd.yaml | 4 + .../Windows/Forensics/BulkExtractor.yaml | 3 + .../Windows/Memory/Acquisition.yaml | 3 + .../Windows/Network/PacketCapture.yaml | 4 + .../Windows/Remediation/Sinkhole.yaml | 3 + .../definitions/Windows/Sys/Interfaces.yaml | 3 + .../Windows/Sysinternals/Autoruns.yaml | 3 + .../Windows/System/AuditPolicy.yaml | 9 +- .../definitions/Windows/System/VBScript.yaml | 29 +- artifacts/proto/artifact.pb.go | 369 ++++++++++-------- artifacts/proto/artifact.proto | 22 ++ .../testdata/server/testcases/pst.out.yaml | 54 +-- .../testdata/server/testcases/verify.in.yaml | 5 + .../testdata/server/testcases/verify.out.yaml | 19 + bin/verify.go | 30 +- docs/references/vql.yaml | 2 +- go.mod | 6 +- go.sum | 12 +- services/launcher/verifier.go | 158 ++++++-- services/launcher/verifier_test.go | 3 +- services/repository/plugin_test.go | 66 +--- services/sanity/lockdown.go | 10 +- vql/golang/verify.go | 84 ++++ 42 files changed, 619 insertions(+), 375 deletions(-) create mode 100644 artifacts/testdata/server/testcases/verify.in.yaml create mode 100644 artifacts/testdata/server/testcases/verify.out.yaml create mode 100644 vql/golang/verify.go diff --git a/artifacts/definitions/Admin/Client/UpdateClientConfig.yaml b/artifacts/definitions/Admin/Client/UpdateClientConfig.yaml index 8c4580c998..f8e53ed64a 100644 --- a/artifacts/definitions/Admin/Client/UpdateClientConfig.yaml +++ b/artifacts/definitions/Admin/Client/UpdateClientConfig.yaml @@ -25,6 +25,10 @@ parameters: default: Y description: Should the client rekey its client ID. +required_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - query: | diff --git a/artifacts/definitions/Admin/Client/Upgrade/Debian.yaml b/artifacts/definitions/Admin/Client/Upgrade/Debian.yaml index d5a7621e14..3601f44929 100644 --- a/artifacts/definitions/Admin/Client/Upgrade/Debian.yaml +++ b/artifacts/definitions/Admin/Client/Upgrade/Debian.yaml @@ -24,6 +24,10 @@ parameters: description: | The name of the service to restart after the upgrade. +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS =~ 'linux' diff --git a/artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml b/artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml index a958bd4ec7..35293130c9 100644 --- a/artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml +++ b/artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml @@ -24,6 +24,9 @@ parameters: description: | The name of the service to restart after the upgrade. +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS From info() where OS =~ 'linux' diff --git a/artifacts/definitions/Admin/Client/Upgrade/Windows.yaml b/artifacts/definitions/Admin/Client/Upgrade/Windows.yaml index 119621075e..11fb974840 100644 --- a/artifacts/definitions/Admin/Client/Upgrade/Windows.yaml +++ b/artifacts/definitions/Admin/Client/Upgrade/Windows.yaml @@ -22,6 +22,10 @@ parameters: overwhelm the server so we stagger the download over this many seconds. +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS = 'windows' diff --git a/artifacts/definitions/Generic/Client/CleanupTemp.yaml b/artifacts/definitions/Generic/Client/CleanupTemp.yaml index b223411a24..17906e2ba9 100644 --- a/artifacts/definitions/Generic/Client/CleanupTemp.yaml +++ b/artifacts/definitions/Generic/Client/CleanupTemp.yaml @@ -13,6 +13,8 @@ parameters: - name: ReadllyDoIt type: bool +required_permissions: + - FILESYSTEM_WRITE sources: - query: | diff --git a/artifacts/definitions/Generic/Client/DiskSpace.yaml b/artifacts/definitions/Generic/Client/DiskSpace.yaml index 6638b88de3..69f859bd9f 100644 --- a/artifacts/definitions/Generic/Client/DiskSpace.yaml +++ b/artifacts/definitions/Generic/Client/DiskSpace.yaml @@ -6,6 +6,9 @@ description: | 1. On Linux and MacOS we call `df -h`. 2. On Windows we use WMI +implied_permissions: + - EXECVE + sources: - query: | LET NonWindows = SELECT * FROM foreach(row={ diff --git a/artifacts/definitions/Generic/Client/VQL.yaml b/artifacts/definitions/Generic/Client/VQL.yaml index add421ef99..84e1dd4c7d 100644 --- a/artifacts/definitions/Generic/Client/VQL.yaml +++ b/artifacts/definitions/Generic/Client/VQL.yaml @@ -3,7 +3,7 @@ description: | Run arbitrary VQL on the endpoint. required_permissions: - - EXECVE + - IMPERSONATION parameters: - name: Command diff --git a/artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml b/artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml index 8d8cd2930d..acb83295c3 100644 --- a/artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml +++ b/artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml @@ -8,6 +8,9 @@ parameters: description: Name of the local hash database default: hashdb.sqlite +implied_permissions: + - FILESYSTEM_WRITE + sources: - query: | LET SQL = " diff --git a/artifacts/definitions/Generic/Utils/FetchBinary.yaml b/artifacts/definitions/Generic/Utils/FetchBinary.yaml index 3bf1dc3c58..73299edc7c 100644 --- a/artifacts/definitions/Generic/Utils/FetchBinary.yaml +++ b/artifacts/definitions/Generic/Utils/FetchBinary.yaml @@ -42,6 +42,10 @@ parameters: - name: Version description: The version of the tool to fetch +implied_permissions: + - SERVER_ADMIN + - FILESYSTEM_WRITE + sources: - query: | -- The following VQL is particularly ancient because it is diff --git a/artifacts/definitions/Linux/Network/PacketCapture.yaml b/artifacts/definitions/Linux/Network/PacketCapture.yaml index ef76f4de89..0b121275c4 100755 --- a/artifacts/definitions/Linux/Network/PacketCapture.yaml +++ b/artifacts/definitions/Linux/Network/PacketCapture.yaml @@ -6,18 +6,21 @@ description: | The `Duration` parameter is used to define how long (in seconds) the capture should be. Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`. A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired. - + Read more about BPF expressions here: https://biot.com/capstats/bpf.html required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + parameters: - name: Duration type: integer description: Duration (in seconds) of PCAP to be recorded. default: 10 - + - name: Interface type: string default: any @@ -25,7 +28,7 @@ parameters: - name: BPF type: string default: - + precondition: SELECT * FROM info() where OS = 'linux' diff --git a/artifacts/definitions/Linux/RHEL/Packages.yaml b/artifacts/definitions/Linux/RHEL/Packages.yaml index 9e6e802efc..4b32f3080f 100644 --- a/artifacts/definitions/Linux/RHEL/Packages.yaml +++ b/artifacts/definitions/Linux/RHEL/Packages.yaml @@ -1,6 +1,10 @@ name: Linux.RHEL.Packages description: | Parse packages installed from dnf or yum + +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() where OS = 'linux' diff --git a/artifacts/definitions/Linux/SuSE/Packages.yaml b/artifacts/definitions/Linux/SuSE/Packages.yaml index ad40361635..89fc2b7655 100644 --- a/artifacts/definitions/Linux/SuSE/Packages.yaml +++ b/artifacts/definitions/Linux/SuSE/Packages.yaml @@ -3,6 +3,9 @@ author: Hilko Bengen description: | Parse list of installed packages from zypper output +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() WHERE OS = 'linux' @@ -12,11 +15,11 @@ sources: FROM execve( length=1000000, argv=["zypper", "--xmlout", "search", "--installed-only", "--details", "--type=package"]) - + LET xml = parse_xml( file=str(str=zypper_output.Stdout), accessor="data") - + SELECT * FROM foreach( row=xml.stream.`search-result`.`solvable-list`.solvable, diff --git a/artifacts/definitions/Linux/Sys/Services.yaml b/artifacts/definitions/Linux/Sys/Services.yaml index c547ea81fb..525f47c0ad 100644 --- a/artifacts/definitions/Linux/Sys/Services.yaml +++ b/artifacts/definitions/Linux/Sys/Services.yaml @@ -1,5 +1,8 @@ name: Linux.Sys.Services -description: Parse services from systemctl +description: Parse services from systemctl + +implied_permissions: + - EXECVE sources: - precondition: | @@ -7,10 +10,8 @@ sources: queries: - | LET services = SELECT Stdout FROM execve(argv=['systemctl', 'list-units', '--type=service']) - + LET all_services = SELECT grok(grok="%{NOTSPACE:Unit}%{SPACE}%{NOTSPACE:Load}%{SPACE}%{NOTSPACE:Active}%{SPACE}%{NOTSPACE:Sub}%{SPACE}%{GREEDYDATA:Description}", data=Line) AS Parsed FROM parse_lines(accessor="data", filename=services.Stdout) - + SELECT * FROM foreach(row=all_services, column="Parsed") WHERE Unit =~ ".service" - - \ No newline at end of file diff --git a/artifacts/definitions/Linux/Users/RootUsers.yaml b/artifacts/definitions/Linux/Users/RootUsers.yaml index 8dc7ab163a..18ea7dea71 100644 --- a/artifacts/definitions/Linux/Users/RootUsers.yaml +++ b/artifacts/definitions/Linux/Users/RootUsers.yaml @@ -7,6 +7,9 @@ author: George-Andrei Iosif (@iosifache) type: CLIENT +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS diff --git a/artifacts/definitions/Linux/Utils/InstallDeb.yaml b/artifacts/definitions/Linux/Utils/InstallDeb.yaml index bd6f059042..5b5e042b24 100644 --- a/artifacts/definitions/Linux/Utils/InstallDeb.yaml +++ b/artifacts/definitions/Linux/Utils/InstallDeb.yaml @@ -31,6 +31,7 @@ type: CLIENT required_permissions: - EXECVE + - FILESYSTEM_WRITE reference: - https://manpages.debian.org/bookworm/debconf-doc/debconf-devel.7.en.html#Type diff --git a/artifacts/definitions/MacOS/Network/PacketCapture.yaml b/artifacts/definitions/MacOS/Network/PacketCapture.yaml index 5bfb0a4ab9..e6a3ec2761 100755 --- a/artifacts/definitions/MacOS/Network/PacketCapture.yaml +++ b/artifacts/definitions/MacOS/Network/PacketCapture.yaml @@ -6,18 +6,21 @@ description: | The `Duration` parameter is used to define how long (in seconds) the capture should be. Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`. A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired. - + Read more about BPF expressions here: https://biot.com/capstats/bpf.html required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + parameters: - name: Duration type: integer description: Duration (in seconds) of PCAP to be recorded. default: 10 - + - name: Interface type: string default: any @@ -25,7 +28,7 @@ parameters: - name: BPF type: string default: - + precondition: SELECT * FROM info() where OS = 'darwin' diff --git a/artifacts/definitions/MacOS/System/Packages.yaml b/artifacts/definitions/MacOS/System/Packages.yaml index 37809e36c8..0acf6a5e16 100644 --- a/artifacts/definitions/MacOS/System/Packages.yaml +++ b/artifacts/definitions/MacOS/System/Packages.yaml @@ -1,24 +1,29 @@ name: MacOS.System.Packages description: | Parse packages installed on Macs + parameters: - name: Length description: Size (in bytes) of output that will be returned type: int default: "100000000" + +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() where OS = 'darwin' query: | - LET packages = SELECT parse_json(data=Stdout) AS Json + LET packages = SELECT parse_json(data=Stdout) AS Json FROM execve(argv=[ "system_profiler", "-json", "SPApplicationsDataType" ], length=Length) SELECT _name AS Name, - get(field="version") AS Version, - path AS Path, - lastModified AS LastModified, + get(field="version") AS Version, + path AS Path, + lastModified AS LastModified, obtained_from AS ObtainedFrom, get(field="signed_by") AS SignedBy, arch_kind AS _Architecture diff --git a/artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml b/artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml index 5d01cc2e9e..4d9bcb9eb9 100644 --- a/artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml +++ b/artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml @@ -23,6 +23,9 @@ reference: required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + tools: - name: SharpHound url: https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe diff --git a/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml b/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml index d13fbde5ba..25b4b506b6 100644 --- a/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml +++ b/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml @@ -38,6 +38,10 @@ parameters: default: LOCAL description: Default timezone for parsing timestamps +#implied_permissions: +# - EXECVE +# - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS = 'windows' diff --git a/artifacts/definitions/Windows/Applications/SBECmd.yaml b/artifacts/definitions/Windows/Applications/SBECmd.yaml index 8e5330e08e..907c9bf299 100644 --- a/artifacts/definitions/Windows/Applications/SBECmd.yaml +++ b/artifacts/definitions/Windows/Applications/SBECmd.yaml @@ -34,6 +34,10 @@ tools: precondition: SELECT OS From info() where OS = 'windows' +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + parameters: - name: userRegex default: . diff --git a/artifacts/definitions/Windows/Forensics/BulkExtractor.yaml b/artifacts/definitions/Windows/Forensics/BulkExtractor.yaml index ad45faf597..e302e39f44 100644 --- a/artifacts/definitions/Windows/Forensics/BulkExtractor.yaml +++ b/artifacts/definitions/Windows/Forensics/BulkExtractor.yaml @@ -45,6 +45,9 @@ author: Matt Green - @mgreen27 required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + tools: - name: Bulk_Extractor_Binary url: https://github.com/Velocidex/Tools/raw/main/BulkExtractor/bulk_extractor.exe diff --git a/artifacts/definitions/Windows/Memory/Acquisition.yaml b/artifacts/definitions/Windows/Memory/Acquisition.yaml index ed0474f781..b73c7d108a 100755 --- a/artifacts/definitions/Windows/Memory/Acquisition.yaml +++ b/artifacts/definitions/Windows/Memory/Acquisition.yaml @@ -20,6 +20,9 @@ description: | go-winpmem.exe expand image.compressed image.raw ``` +implied_permissions: + - FILESYSTEM_WRITE + precondition: | SELECT OS FROM info() WHERE OS = 'windows' diff --git a/artifacts/definitions/Windows/Network/PacketCapture.yaml b/artifacts/definitions/Windows/Network/PacketCapture.yaml index f8eb544339..b06cf68746 100644 --- a/artifacts/definitions/Windows/Network/PacketCapture.yaml +++ b/artifacts/definitions/Windows/Network/PacketCapture.yaml @@ -15,6 +15,10 @@ tools: - name: etl2pcapng url: https://github.com/microsoft/etl2pcapng/releases/download/v1.4.0/etl2pcapng.zip +implied_permissions: + - FILESYSTEM_WRITE + - EXECVE + parameters: - name: StartTrace type: bool diff --git a/artifacts/definitions/Windows/Remediation/Sinkhole.yaml b/artifacts/definitions/Windows/Remediation/Sinkhole.yaml index 1ed7f73620..d46d5cf0e0 100644 --- a/artifacts/definitions/Windows/Remediation/Sinkhole.yaml +++ b/artifacts/definitions/Windows/Remediation/Sinkhole.yaml @@ -20,6 +20,9 @@ author: Matt Green - @mgreen27 required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + type: CLIENT parameters: diff --git a/artifacts/definitions/Windows/Sys/Interfaces.yaml b/artifacts/definitions/Windows/Sys/Interfaces.yaml index 8e77114d7d..1fa3234889 100644 --- a/artifacts/definitions/Windows/Sys/Interfaces.yaml +++ b/artifacts/definitions/Windows/Sys/Interfaces.yaml @@ -3,6 +3,9 @@ description: | Report information about the systems interfaces. This artifact simply parses the output from ipconfig /all. +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS from info() where OS = "windows" diff --git a/artifacts/definitions/Windows/Sysinternals/Autoruns.yaml b/artifacts/definitions/Windows/Sysinternals/Autoruns.yaml index 27a975ee1e..d98c3cc296 100644 --- a/artifacts/definitions/Windows/Sysinternals/Autoruns.yaml +++ b/artifacts/definitions/Windows/Sysinternals/Autoruns.yaml @@ -15,6 +15,9 @@ tools: precondition: SELECT OS From info() where OS = 'windows' +implied_permissions: + - EXECVE + parameters: - name: All type: bool diff --git a/artifacts/definitions/Windows/System/AuditPolicy.yaml b/artifacts/definitions/Windows/System/AuditPolicy.yaml index 8ec193ab57..44770cadda 100644 --- a/artifacts/definitions/Windows/System/AuditPolicy.yaml +++ b/artifacts/definitions/Windows/System/AuditPolicy.yaml @@ -1,9 +1,9 @@ name: Windows.System.AuditPolicy description: | - Artifact using auditpol to retrieve the logging settings + Artifact using auditpol to retrieve the logging settings defined in the Windows Audit Policy. - + Use this artifact to determine what Windows event logs are audited and if there are any discrepancies across the environment. @@ -11,6 +11,9 @@ type: CLIENT author: Zach Stanford - @svch0st +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS From info() where OS = 'windows' @@ -18,7 +21,7 @@ sources: query: | LET output = SELECT * FROM execve( argv=["auditpol.exe","/get","/category:*","/r"]) - + SELECT * FROM foreach( row=output, query={ diff --git a/artifacts/definitions/Windows/System/VBScript.yaml b/artifacts/definitions/Windows/System/VBScript.yaml index 02dc962443..dfc44f522a 100644 --- a/artifacts/definitions/Windows/System/VBScript.yaml +++ b/artifacts/definitions/Windows/System/VBScript.yaml @@ -2,30 +2,33 @@ name: Windows.System.VBScript author: Matt Green - @mgreen27 description: | This artifact allows running VBScript through cscript.exe. - - This is a very powerful artifact since it allows for arbitrary command execution - on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions - (specifically the EXECVE permission). Typically it is only available with the + + This is a very powerful artifact since it allows for arbitrary command execution + on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions + (specifically the EXECVE permission). Typically it is only available with the administrator role. - - Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately - formatted scripts. Pasting scripts direct from word or webpages may lead to - formatting issues when unicode characters are substituted. Copy script into + + Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately + formatted scripts. Pasting scripts direct from word or webpages may lead to + formatting issues when unicode characters are substituted. Copy script into a notepad, save as ASCII then try again. - + required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + precondition: SELECT OS From info() where OS = 'windows' parameters: - name: Script default: Wscript.Echo "Hello world!" - + sources: - query: | LET temp_script <= tempfile(extension='.vbs', data=str(str=Script)) - - SELECT Stdout - FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n') \ No newline at end of file + + SELECT Stdout + FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n') diff --git a/artifacts/proto/artifact.pb.go b/artifacts/proto/artifact.pb.go index e34305b225..1e49c437af 100644 --- a/artifacts/proto/artifact.pb.go +++ b/artifacts/proto/artifact.pb.go @@ -515,6 +515,27 @@ type Artifact struct { Reference []string `protobuf:"bytes,5,rep,name=reference,proto3" json:"reference,omitempty"` References []string `protobuf:"bytes,23,rep,name=references,proto3" json:"references,omitempty"` RequiredPermissions []string `protobuf:"bytes,13,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` + // A list of permissions implied by this artifact. This is used by + // the artifact writer to declare what additional permissions the + // artifact provides over the permissions provided by the user. + // + // On the client, artifacts do not run with ACL enforced, + // therefore they can do anything, including actions which the + // user launching the artifact does not have. For example, the + // user may have the investigator role which does not have + // EXECVE. However, when launching this artifact on the client, + // the artifact will be able to run actions requiring the EXEVE + // permission (because there is no ACL enforcement on the client). + // + // Therefore we say this artifact implies the user has EXECVE - + // this is safe if the aritfact takes steps to ensure the user + // does not have arbitrary control over what to execute (for + // example, if the artifact launches a tool with restricted + // command line args). + // + // This field is only used to ensure the static analysis engine + // that the implied permission is properly controlled. + ImpliedPermissions []string `protobuf:"bytes,28,rep,name=implied_permissions,json=impliedPermissions,proto3" json:"implied_permissions,omitempty"` // If this is specified, we run this artifact as the named user, // with that user's ACL token. This is similar to the Unix suid // mechanism or the Windows impersonation mechanism in that it @@ -640,6 +661,13 @@ func (x *Artifact) GetRequiredPermissions() []string { return nil } +func (x *Artifact) GetImpliedPermissions() []string { + if x != nil { + return x.ImpliedPermissions + } + return nil +} + func (x *Artifact) GetImpersonate() string { if x != nil { return x.Impersonate @@ -1427,7 +1455,7 @@ var file_artifact_proto_rawDesc = []byte{ 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x22, 0x94, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x78, 0x74, 0x2e, 0x22, 0xc5, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0xb1, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x9c, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x95, 0x01, 0x12, 0x92, 0x01, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, @@ -1465,174 +1493,177 @@ var file_artifact_proto_rawDesc = []byte{ 0x65, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, - 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12, - 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, - 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, - 0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, - 0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69, 0x6e, - 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x0c, - 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x0a, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x32, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x0a, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x54, - 0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, - 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x45, - 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53, 0x45, - 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54, 0x45, - 0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65, 0x72, - 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x67, - 0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a, 0x12, - 0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, - 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c, 0x20, - 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x77, - 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, - 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, - 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x73, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, - 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, - 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x34, - 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x10, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, 0x72, - 0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, 0x1a, - 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, - 0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x75, - 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c, 0x69, - 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, - 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65, 0x72, - 0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4, 0x01, - 0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x77, - 0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a, 0x12, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x67, - 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x12, - 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, - 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x65, - 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, - 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, - 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcb, - 0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, - 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c, - 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, 0x70, - 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69, - 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, - 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, - 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, - 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, - 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, - 0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, - 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x42, 0x37, 0x5a, 0x35, - 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, - 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, + 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, + 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, + 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, + 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x32, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x54, 0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54, + 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, + 0x67, 0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a, + 0x12, 0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, + 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, + 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x34, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, + 0x72, 0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, + 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, + 0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65, + 0x72, 0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4, + 0x01, 0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, + 0x77, 0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a, + 0x12, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, + 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, + 0x74, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, + 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xcb, 0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, + 0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, + 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, + 0x70, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, + 0x69, 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x52, 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, + 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, + 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x57, 0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, + 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, + 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x42, 0x37, 0x5a, + 0x35, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, + 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/artifacts/proto/artifact.proto b/artifacts/proto/artifact.proto index 139e78507b..f0f40ebb93 100644 --- a/artifacts/proto/artifact.proto +++ b/artifacts/proto/artifact.proto @@ -150,6 +150,28 @@ message Artifact { description: "A list of required permissions to collect this artifact." }]; + // A list of permissions implied by this artifact. This is used by + // the artifact writer to declare what additional permissions the + // artifact provides over the permissions provided by the user. + // + // On the client, artifacts do not run with ACL enforced, + // therefore they can do anything, including actions which the + // user launching the artifact does not have. For example, the + // user may have the investigator role which does not have + // EXECVE. However, when launching this artifact on the client, + // the artifact will be able to run actions requiring the EXEVE + // permission (because there is no ACL enforcement on the client). + // + // Therefore we say this artifact implies the user has EXECVE - + // this is safe if the aritfact takes steps to ensure the user + // does not have arbitrary control over what to execute (for + // example, if the artifact launches a tool with restricted + // command line args). + // + // This field is only used to ensure the static analysis engine + // that the implied permission is properly controlled. + repeated string implied_permissions = 28; + // If this is specified, we run this artifact as the named user, // with that user's ACL token. This is similar to the Unix suid // mechanism or the Windows impersonation mechanism in that it diff --git a/artifacts/testdata/server/testcases/pst.out.yaml b/artifacts/testdata/server/testcases/pst.out.yaml index eb51d7eb46..cc19a42f38 100644 --- a/artifacts/testdata/server/testcases/pst.out.yaml +++ b/artifacts/testdata/server/testcases/pst.out.yaml @@ -1,53 +1 @@ -SELECT * FROM Artifact.Windows.Forensics.Pst( PSTGlob=srcDir + "/artifacts/testdata/files/pst/Outlook.pst", AttachmentYaraRule=YaraRule, SubjectRegex="Multiple", PathRegex="Sent")[ - { - "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items", - "Sender": "saqib.razzaq@xp.local", - "Receiver": "", - "Subject": "\u0001\u0001Multiple attachments", - "Message": "This message contains multiple attachments\r\n\r\n \r\n\r\n", - "Delivered": "2011-06-21T23:51:00Z", - "Attachments": [ - { - "Name": "text file.txt", - "Size": 29, - "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33253" - }, - { - "Name": "Sunset.jpg", - "Size": 71189, - "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33285" - }, - { - "Name": "Blue hills.jpg", - "Size": 28521, - "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33317" - } - ], - "Uploads": null, - "YaraHit": [ - { - "String": { - "Name": "$a", - "Offset": 3349, - "HexData": [ - "00000000 4a 50 45 47 |JPEG|", - "" - ], - "Data": "SlBFRw==" - } - }, - { - "String": { - "Name": "$a", - "Offset": 2377, - "HexData": [ - "00000000 4a 50 45 47 |JPEG|", - "" - ], - "Data": "SlBFRw==" - } - } - ], - "_Source": "Windows.Forensics.Pst" - } -] \ No newline at end of file +SELECT * FROM Artifact.Windows.Forensics.Pst( PSTGlob=srcDir + "/artifacts/testdata/files/pst/Outlook.pst", AttachmentYaraRule=YaraRule, SubjectRegex="Multiple", PathRegex="Sent")[] \ No newline at end of file diff --git a/artifacts/testdata/server/testcases/verify.in.yaml b/artifacts/testdata/server/testcases/verify.in.yaml new file mode 100644 index 0000000000..9f2a188a2c --- /dev/null +++ b/artifacts/testdata/server/testcases/verify.in.yaml @@ -0,0 +1,5 @@ +Queries: + - SELECT count() AS Count , + verify(artifact=name) AS V + FROM artifact_definitions() + WHERE type=~'client' AND built_in AND V.Warnings diff --git a/artifacts/testdata/server/testcases/verify.out.yaml b/artifacts/testdata/server/testcases/verify.out.yaml new file mode 100644 index 0000000000..0d170a66b1 --- /dev/null +++ b/artifacts/testdata/server/testcases/verify.out.yaml @@ -0,0 +1,19 @@ +SELECT count() AS Count , verify(artifact=name) AS V FROM artifact_definitions() WHERE type=~'client' AND built_in AND V.Warnings[ + { + "Count": 1, + "V": { + "Artifact": "Windows.Applications.NirsoftBrowserViewer", + "Permissions": [ + "EXECVE", + "FILESYSTEM_READ", + "FILESYSTEM_WRITE", + "MACHINE_STATE" + ], + "Errors": null, + "Warnings": [ + "\u003cyellow\u003eSuggestion\u003c/\u003e: Add EXECVE to artifact's required_permissions or implied_permissions fields", + "\u003cyellow\u003eSuggestion\u003c/\u003e: Add FILESYSTEM_WRITE to artifact's required_permissions or implied_permissions fields" + ] + } + } +] \ No newline at end of file diff --git a/bin/verify.go b/bin/verify.go index ff9c41d474..a09e4b8cab 100644 --- a/bin/verify.go +++ b/bin/verify.go @@ -47,26 +47,27 @@ func doVerify() error { logger := logging.GetLogger(config_obj, &logging.ToolComponent) // Report all errors and keep going as much as possible. - returned_errs := make(map[string]error) - artifacts := make(map[string]*artifacts_proto.Artifact) + states := make(map[string]*launcher.AnalysisState) repository, err := manager.GetGlobalRepository(config_obj) if err != nil { return err } + for _, artifact_path := range *verify_args { - returned_errs[artifact_path] = nil + state := launcher.NewAnalysisState(artifact_path) + states[artifact_path] = state fd, err := os.Open(artifact_path) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } data, err := ioutil.ReadAll(fd) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } @@ -76,24 +77,29 @@ func doVerify() error { AllowOverridingAlias: true, }) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } artifacts[artifact_path] = a } - for artifact_path, a := range artifacts { + for artifact_path, artifact := range artifacts { + state, _ := states[artifact_path] launcher.VerifyArtifact(ctx, config_obj, - artifact_path, a, returned_errs) + repository, artifact, state) } var ret error - for artifact_path, err := range returned_errs { - if err != nil { + for artifact_path, state := range states { + if len(state.Errors) == 0 { + logger.Info("Verified %v: OK", artifact_path) + } + for _, err := range state.Errors { logger.Error("%v: %v", artifact_path, err) ret = err - } else { - logger.Info("Verified %v: OK", artifact_path) + } + for _, msg := range state.Warnings { + logger.Info("%v: %v", artifact_path, msg) } } diff --git a/docs/references/vql.yaml b/docs/references/vql.yaml index 71ab36dc82..8996ef43e6 100644 --- a/docs/references/vql.yaml +++ b/docs/references/vql.yaml @@ -8868,7 +8868,7 @@ 2. The `enrichment` field specifies a VQL lambda which will be used to build an enrichment object after a match is made. This - is used to additional infomation for the analyst to assess. + is used to additional information for the analyst to assess. 3. The `vql` modifier can be used to specify a VQL lambda that will be used in a detection clause. The lambda will receive the diff --git a/go.mod b/go.mod index 27976f4ff6..e1c105aa55 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( golang.org/x/mod v0.21.0 golang.org/x/net v0.38.0 golang.org/x/sys v0.32.0 - golang.org/x/text v0.24.0 + golang.org/x/text v0.25.0 golang.org/x/time v0.5.0 google.golang.org/api v0.169.0 google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect @@ -92,7 +92,7 @@ require ( www.velocidex.com/golang/go-prefetch v0.0.0-20240910051453-2385582c1c22 www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 - www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048 + www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709 ) require ( @@ -281,7 +281,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/sync v0.13.0 // indirect + golang.org/x/sync v0.14.0 // indirect golang.org/x/term v0.30.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect kernel.org/pub/linux/libs/security/libcap/cap v1.2.71 // indirect diff --git a/go.sum b/go.sum index a48deceb91..bc0f53f4d2 100644 --- a/go.sum +++ b/go.sum @@ -818,8 +818,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -877,8 +877,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= @@ -1007,7 +1007,7 @@ www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 h1:qJlm0T61 www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959/go.mod h1:wjOPwI3Vy6TP0AhF6NjjXV/to93E5A1tjA04liHvf5E= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 h1:BMX/37sYwX+8JhHt+YNbPfbx7dXG1w1L1mXonNBtjt0= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU= -www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048 h1:EEtilwfOb8pfaZ2cbavThTZVXQ1lbPABVjXwaQHb3lM= -www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY= +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709 h1:FD1zc0go4SJW/FFkYV5LvYNs2nNJ9YHoLRpq+YXT9uQ= +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY= www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c h1:rL/It+Ig+mvIhmy9vl5gg5b6CX2J12x0v2SXIT2RoWE= www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c/go.mod h1:tjaJNlBWbvH4cEMrEu678CFR2hrtcdyPINIpRxrOh4U= diff --git a/services/launcher/verifier.go b/services/launcher/verifier.go index 94d0757bae..c327d04796 100644 --- a/services/launcher/verifier.go +++ b/services/launcher/verifier.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + api_proto "www.velocidex.com/golang/velociraptor/api/proto" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/services" @@ -17,18 +18,102 @@ var ( api_description = &ApiDescription{} ) +// Contains the result of the static analysis. +type AnalysisState struct { + Artifact string + Permissions []string + Errors []error + Warnings []string +} + +func (self *AnalysisState) SetError(err error) { + self.Errors = append(self.Errors, err) +} + +func (self *AnalysisState) AnalyseCall( + callsite vfilter.CallSite, desc CallDesciptor) { + self.Permissions = utils.Sort(utils.DeduplicateStringSlice( + append(self.Permissions, desc.Permissions...))) +} + +func (self *AnalysisState) AnalyseArtifactRequiredPermissions( + artifact *artifacts_proto.Artifact) { + switch strings.ToUpper(artifact.Type) { + case "", "CLIENT": + default: + return + } + + // When a user runs an artifact on a client they implicitly have + // these permissions. + implied_permissions := []string{ + "FILESYSTEM_READ", "MACHINE_STATE", + + // Used by http_client on the client side. + "COLLECT_SERVER", + } + + // They also receive permissins required by the artifact because + // this will be enforced on the server. + implied_permissions = append(implied_permissions, + artifact.RequiredPermissions...) + + // The artifact writer can also declare which permission are + // safely controlled. + implied_permissions = append(implied_permissions, + artifact.ImpliedPermissions...) + + // Now go over all the permissions used by the artifact an warn + // about all permissions that are not required + for _, perm := range self.Permissions { + if !utils.InString(implied_permissions, perm) { + self.Warnings = append(self.Warnings, + fmt.Sprintf("Suggestion: Add %v to artifact's required_permissions or implied_permissions fields", perm)) + } + } +} + +func NewAnalysisState(artifact string) *AnalysisState { + return &AnalysisState{ + Artifact: artifact, + } +} + type Required bool +type CallDesciptor struct { + ArgsRequired map[string]Required + Permissions []string +} + +func (self *CallDesciptor) SetPermissions(api *api_proto.Completion) { + if api.Metadata != nil { + perms, pres := api.Metadata["permissions"] + if pres { + self.Permissions = strings.Split(perms, ",") + } + } +} + +func NewCallDesciptor(api *api_proto.Completion) CallDesciptor { + res := &CallDesciptor{ + ArgsRequired: make(map[string]Required), + } + + res.SetPermissions(api) + return *res +} + type ApiDescription struct { - functions map[string]map[string]Required - plugins map[string]map[string]Required + functions map[string]CallDesciptor + plugins map[string]CallDesciptor } func (self *ApiDescription) init() error { // Initialize if needed if self.functions == nil || self.plugins == nil { - self.functions = make(map[string]map[string]Required) - self.plugins = make(map[string]map[string]Required) + self.functions = make(map[string]CallDesciptor) + self.plugins = make(map[string]CallDesciptor) apis, err := utils.LoadApiDescription() if err != nil { @@ -37,21 +122,24 @@ func (self *ApiDescription) init() error { for _, api := range apis { if api.Type == "Function" { - desc := make(map[string]Required) + desc := NewCallDesciptor(api) + // Ignore ** kwargs type of call. - desc["**"] = Required(false) + desc.ArgsRequired["**"] = Required(false) for _, arg := range api.Args { - desc[arg.Name] = Required(arg.Required) + desc.ArgsRequired[arg.Name] = Required(arg.Required) } if !api.FreeFormArgs { self.functions[api.Name] = desc } } if api.Type == "Plugin" { - desc := make(map[string]Required) - desc["**"] = Required(false) + desc := NewCallDesciptor(api) + + // Ignore ** kwargs type of call. + desc.ArgsRequired["**"] = Required(false) for _, arg := range api.Args { - desc[arg.Name] = Required(arg.Required) + desc.ArgsRequired[arg.Name] = Required(arg.Required) } if !api.FreeFormArgs { self.plugins[api.Name] = desc @@ -96,7 +184,8 @@ func (self *ApiDescription) verifyArtifact( func (self *ApiDescription) VerifyCallSite( ctx context.Context, config_obj *config_proto.Config, repository services.Repository, - callsite vfilter.CallSite) (res []error) { + callsite vfilter.CallSite, + state *AnalysisState) (res []error) { err := self.init() if err != nil { @@ -112,8 +201,10 @@ func (self *ApiDescription) VerifyCallSite( if callsite.Type == "plugin" { desc, pres := self.plugins[callsite.Name] if pres { + state.AnalyseCall(callsite, desc) + for _, arg := range callsite.Args { - _, pres := desc[arg] + _, pres := desc.ArgsRequired[arg] if !pres { res = append(res, fmt.Errorf( "Invalid arg %v for plugin %v()", @@ -122,7 +213,7 @@ func (self *ApiDescription) VerifyCallSite( } // Now check if any of the required args are missing - for arg, required := range desc { + for arg, required := range desc.ArgsRequired { if bool(required) && !utils.InString(callsite.Args, arg) { res = append(res, fmt.Errorf( "While calling plugin %v(), required arg %v is not provided", @@ -135,8 +226,10 @@ func (self *ApiDescription) VerifyCallSite( if callsite.Type == "function" { desc, pres := self.functions[callsite.Name] if pres { + state.AnalyseCall(callsite, desc) + for _, arg := range callsite.Args { - _, pres := desc[arg] + _, pres := desc.ArgsRequired[arg] if !pres { res = append(res, fmt.Errorf( "Invalid arg %v for function %v()", @@ -145,7 +238,7 @@ func (self *ApiDescription) VerifyCallSite( } // Now check if any of the required args are missing - for arg, required := range desc { + for arg, required := range desc.ArgsRequired { if bool(required) && !utils.InString(callsite.Args, arg) { res = append(res, fmt.Errorf( "While calling vql function %v(), required arg %v is not called", @@ -161,7 +254,8 @@ func (self *ApiDescription) VerifyCallSite( // Run additional validation on the VQL to ensure it is valid. func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, - query string, repository services.Repository) (res []error) { + query string, repository services.Repository, + state *AnalysisState) (res []error) { scope := vql_subsystem.MakeScope() @@ -177,7 +271,7 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, for _, cs := range visitor.CallSites { res = append(res, api_description.VerifyCallSite( - ctx, config_obj, repository, cs)...) + ctx, config_obj, repository, cs, state)...) } } @@ -186,24 +280,14 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, func VerifyArtifact( ctx context.Context, config_obj *config_proto.Config, - artifact_path string, + repository services.Repository, artifact *artifacts_proto.Artifact, - returned_errs map[string]error) { - - manager, err := services.GetRepositoryManager(config_obj) - if err != nil { - return - } - - repository, err := manager.GetGlobalRepository(config_obj) - if err != nil { - return - } + state *AnalysisState) { if artifact.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, - artifact.Precondition, repository) { - returned_errs[artifact_path] = err + artifact.Precondition, repository, state) { + state.SetError(err) } } @@ -214,21 +298,23 @@ func VerifyArtifact( err := GetQueryDependencies(ctx, config_obj, repository, s.Query, 0, dependency) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } // Now check for broken callsites for _, err := range VerifyVQL(ctx, config_obj, - s.Query, repository) { - returned_errs[artifact_path] = err + s.Query, repository, state) { + state.SetError(err) } } if s.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, - s.Precondition, repository) { - returned_errs[artifact_path] = err + s.Precondition, repository, state) { + state.SetError(err) } } } + + state.AnalyseArtifactRequiredPermissions(artifact) } diff --git a/services/launcher/verifier_test.go b/services/launcher/verifier_test.go index 893090e885..b496b217b4 100644 --- a/services/launcher/verifier_test.go +++ b/services/launcher/verifier_test.go @@ -43,8 +43,9 @@ func (self *LauncherTestSuite) TestVerifyVQL() { assert.NoError(self.T(), err) for _, tc := range verifier_test_cases { + state := launcher.NewAnalysisState("") errs := launcher.VerifyVQL(self.Ctx, - self.ConfigObj, tc.query, repository) + self.ConfigObj, tc.query, repository, state) if len(errs) > 0 { if tc.error_regex == "" { self.T().Fatalf("%v: Expected no error but got %v", diff --git a/services/repository/plugin_test.go b/services/repository/plugin_test.go index 9bb84cb58e..875b021ede 100644 --- a/services/repository/plugin_test.go +++ b/services/repository/plugin_test.go @@ -74,10 +74,8 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { names, err := repository.List(self.Ctx, ConfigObj) assert.NoError(self.T(), err) - // Additinal verifications - returned_errs := make(map[string]error) - for _, artifact_name := range names { + state := launcher.NewAnalysisState(artifact_name) artifact, pres := repository.Get(self.Ctx, ConfigObj, artifact_name) assert.True(self.T(), pres) @@ -87,15 +85,14 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { assert.NoError(self.T(), err, "Error compiling "+artifact_name) launcher.VerifyArtifact( - self.Ctx, self.ConfigObj, artifact_name, artifact, returned_errs) - } - } + self.Ctx, self.ConfigObj, artifact_name, artifact, state) - for artifact_name, err := range returned_errs { - fmt.Printf("Error with %v: %v\n", artifact_name, err) + for _, err := range state.Errors { + fmt.Printf("Error with %v: %v\n", artifact_name, err) + } + assert.True(self.T(), len(state.Errors) == 0) + } } - - assert.True(self.T(), len(returned_errs) == 0) } var ( @@ -347,55 +344,6 @@ func (self *PluginTestSuite) TestClientPluginMultipleSourcesAndPrecondtionsEvent } -var ( - memory_leak_test = ` -name: ArtifactWithMemoryLeak -sources: -- query: | - LET X <= "Hello World" * 1000000 - - SELECT X FROM scope() -` -) - -func (self *PluginTestSuite) TestPluginMemoryLeak() { - repository := self.LoadArtifacts(memory_leak_test) - builder := services.ScopeBuilder{ - Config: self.ConfigObj, - ACLManager: acl_managers.NullACLManager{}, - Repository: repository, - Logger: logging.NewPlainLogger( - self.ConfigObj, &logging.FrontendComponent), - Env: ordereddict.NewDict(), - } - - manager, _ := services.GetRepositoryManager(self.ConfigObj) - scope := manager.BuildScope(builder) - defer scope.Close() - - queries := []string{ - `SELECT * FROM foreach( - row={ - SELECT * FROM range(end=10000) - }, query={ - SELECT * FROM Artifact.ArtifactWithMemoryLeak() - WHERE FALSE - })`, - } - - results := ordereddict.NewDict() - for _, query := range queries { - rows := []vfilter.Row{} - vql, err := vfilter.Parse(query) - assert.NoError(self.T(), err) - - for row := range vql.Eval(self.Ctx, scope) { - rows = append(rows, row) - } - results.Set(query, rows) - } -} - func TestArtifactPlugin(t *testing.T) { suite.Run(t, &PluginTestSuite{}) } diff --git a/services/sanity/lockdown.go b/services/sanity/lockdown.go index 33c8953a54..1247083fe6 100644 --- a/services/sanity/lockdown.go +++ b/services/sanity/lockdown.go @@ -17,7 +17,12 @@ func (self SanityChecks) CheckForLockdown( } lockdown_token := &acl_proto.ApiClientACL{ - ArtifactWriter: true, + ArtifactWriter: true, + + // Labeling clients can move them between label groups which + // may cause new artifacts to be collected automatically + // (e.g. Quarantine). + LabelClients: true, ServerArtifactWriter: true, CollectClient: true, CollectServer: true, @@ -28,6 +33,9 @@ func (self SanityChecks) CheckForLockdown( FilesystemRead: true, MachineState: true, CollectBasic: true, + + Impersonation: true, + OrgAdmin: true, } if config_obj.Defaults != nil && diff --git a/vql/golang/verify.go b/vql/golang/verify.go new file mode 100644 index 0000000000..08a299a398 --- /dev/null +++ b/vql/golang/verify.go @@ -0,0 +1,84 @@ +package golang + +import ( + "context" + + "github.com/Velocidex/ordereddict" + "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/services/launcher" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/vfilter" + "www.velocidex.com/golang/vfilter/arg_parser" +) + +type VerifyFunctionArgs struct { + Artifact string `vfilter:"required,field=artifact,doc=The artifact to verify. This can be an artifact source in yaml or json or the name of an artifact"` +} + +func init() { + vql_subsystem.RegisterFunction( + vfilter.GenericFunction{ + FunctionName: "verify", + Doc: `verify an artifact + +This function will verify the artifact and flag any potential errors or warnings. +`, + Metadata: vql_subsystem.VQLMetadata().Build(), + ArgType: &VerifyFunctionArgs{}, + Function: func( + ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) vfilter.Any { + + arg := &VerifyFunctionArgs{} + err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) + if err != nil { + scope.Log("verify: %v", err) + return vfilter.Null{} + } + + config_obj, ok := vql_subsystem.GetServerConfig(scope) + if !ok { + scope.Log("verify: Must run on the server") + return vfilter.Null{} + } + + manager, err := services.GetRepositoryManager(config_obj) + if err != nil { + return err + } + + repository, err := manager.GetGlobalRepository(config_obj) + if err != nil { + return err + } + + state := launcher.NewAnalysisState(arg.Artifact) + + artifact, pres := repository.Get(ctx, config_obj, arg.Artifact) + if !pres { + local_repository := manager.NewRepository() + local_repository.SetParent(repository, config_obj) + + artifact, err = local_repository.LoadYaml(arg.Artifact, + services.ArtifactOptions{ + ValidateArtifact: true, + ArtifactIsBuiltIn: true, + AllowOverridingAlias: true, + }) + if err != nil { + state.SetError(err) + return state + } + + repository = local_repository + } + + // Verify the artifact + launcher.VerifyArtifact( + ctx, config_obj, repository, artifact, state) + + return state + }, + }) +} From fa1399d65baec0d68dc26ca3339abb635a0a607e Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 20 May 2025 18:07:33 +1000 Subject: [PATCH 2/7] Fixed test --- services/repository/plugin_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/repository/plugin_test.go b/services/repository/plugin_test.go index 875b021ede..2ef201bfe6 100644 --- a/services/repository/plugin_test.go +++ b/services/repository/plugin_test.go @@ -70,6 +70,7 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { assert.NoError(self.T(), err) new_repository := manager.NewRepository() + new_repository.SetParent(repository, ConfigObj) names, err := repository.List(self.Ctx, ConfigObj) assert.NoError(self.T(), err) @@ -85,7 +86,7 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { assert.NoError(self.T(), err, "Error compiling "+artifact_name) launcher.VerifyArtifact( - self.Ctx, self.ConfigObj, artifact_name, artifact, state) + self.Ctx, self.ConfigObj, new_repository, artifact, state) for _, err := range state.Errors { fmt.Printf("Error with %v: %v\n", artifact_name, err) From 53ee09f8c903af87e774f42499862430b7f008aa Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 19 May 2025 07:52:49 +0000 Subject: [PATCH 3/7] fix: upgrade webpack from 5.99.6 to 5.99.7 Snyk has created this PR to upgrade webpack from 5.99.6 to 5.99.7. See this package in npm: webpack See this project in Snyk: https://app.snyk.io/org/scudette/project/76f4d127-566b-42ef-86f4-bdcbc92b90b4?utm_source=github&utm_medium=referral&page=upgrade-pr --- gui/velociraptor/package-lock.json | 36 ++++++++++++++++-------------- gui/velociraptor/package.json | 2 +- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/gui/velociraptor/package-lock.json b/gui/velociraptor/package-lock.json index c49fb538d2..fdd73c05c3 100644 --- a/gui/velociraptor/package-lock.json +++ b/gui/velociraptor/package-lock.json @@ -15,10 +15,10 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", - "ace-builds": "^1.40.0", + "ace-builds": "1.40.0", "axios": ">=1.8.4", "axios-retry": "3.9.1", - "bootstrap": "^5.3.5", + "bootstrap": "5.3.5", "classnames": "^2.5.1", "csv-parse": "4.16.3", "csv-stringify": "5.6.5", @@ -54,7 +54,7 @@ "recharts": "^2.15.3", "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "^5.99.6" + "webpack": "^5.99.7" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -8581,9 +8581,9 @@ } }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -9535,13 +9535,14 @@ } }, "node_modules/webpack": { - "version": "5.99.6", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz", - "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==", + "version": "5.99.7", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz", + "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==", "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", @@ -9558,7 +9559,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", @@ -15734,9 +15735,9 @@ } }, "schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "requires": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16415,12 +16416,13 @@ } }, "webpack": { - "version": "5.99.6", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz", - "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==", + "version": "5.99.7", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz", + "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==", "requires": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", @@ -16437,7 +16439,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", diff --git a/gui/velociraptor/package.json b/gui/velociraptor/package.json index ad5b25b6eb..2a0b558b5a 100644 --- a/gui/velociraptor/package.json +++ b/gui/velociraptor/package.json @@ -49,7 +49,7 @@ "recharts": "^2.15.3", "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "5.99.6" + "webpack": "5.99.7" }, "homepage": ".", "scripts": { From a515319075d53af62d0e195f44671e32bc01a7e0 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 19 May 2025 07:52:44 +0000 Subject: [PATCH 4/7] fix: upgrade axios from 1.8.4 to 1.9.0 Snyk has created this PR to upgrade axios from 1.8.4 to 1.9.0. See this package in npm: axios See this project in Snyk: https://app.snyk.io/org/scudette/project/76f4d127-566b-42ef-86f4-bdcbc92b90b4?utm_source=github&utm_medium=referral&page=upgrade-pr --- gui/velociraptor/package-lock.json | 14 +++++++------- gui/velociraptor/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gui/velociraptor/package-lock.json b/gui/velociraptor/package-lock.json index fdd73c05c3..53deffcfee 100644 --- a/gui/velociraptor/package-lock.json +++ b/gui/velociraptor/package-lock.json @@ -16,7 +16,7 @@ "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", "ace-builds": "1.40.0", - "axios": ">=1.8.4", + "axios": "^1.9.0", "axios-retry": "3.9.1", "bootstrap": "5.3.5", "classnames": "^2.5.1", @@ -3982,9 +3982,9 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -12378,9 +12378,9 @@ "dev": true }, "axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/gui/velociraptor/package.json b/gui/velociraptor/package.json index 2a0b558b5a..98e3bed3fb 100644 --- a/gui/velociraptor/package.json +++ b/gui/velociraptor/package.json @@ -10,7 +10,7 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", - "axios": ">=1.8.4", + "axios": ">=1.9.0", "ace-builds": "1.40.0", "axios-retry": "3.9.1", "bootstrap": "5.3.5", From bd217507aae679bb5a6348de85d7a450fe7e4665 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 19 May 2025 07:52:40 +0000 Subject: [PATCH 5/7] fix: upgrade ace-builds from 1.40.0 to 1.40.1 Snyk has created this PR to upgrade ace-builds from 1.40.0 to 1.40.1. See this package in npm: ace-builds See this project in Snyk: https://app.snyk.io/org/scudette/project/76f4d127-566b-42ef-86f4-bdcbc92b90b4?utm_source=github&utm_medium=referral&page=upgrade-pr --- gui/velociraptor/package-lock.json | 14 +++++++------- gui/velociraptor/package.json | 5 +++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/gui/velociraptor/package-lock.json b/gui/velociraptor/package-lock.json index 53deffcfee..e518907670 100644 --- a/gui/velociraptor/package-lock.json +++ b/gui/velociraptor/package-lock.json @@ -15,7 +15,7 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", - "ace-builds": "1.40.0", + "ace-builds": "1.40.1", "axios": "^1.9.0", "axios-retry": "3.9.1", "bootstrap": "5.3.5", @@ -3736,9 +3736,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/ace-builds": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz", - "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz", + "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw==", "license": "BSD-3-Clause" }, "node_modules/acorn": { @@ -12202,9 +12202,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "ace-builds": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz", - "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==" + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz", + "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw==" }, "acorn": { "version": "8.14.0", diff --git a/gui/velociraptor/package.json b/gui/velociraptor/package.json index 98e3bed3fb..a95ea2bebd 100644 --- a/gui/velociraptor/package.json +++ b/gui/velociraptor/package.json @@ -10,8 +10,13 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", +<<<<<<< HEAD "axios": ">=1.9.0", "ace-builds": "1.40.0", +======= + "axios": ">=1.8.4", + "ace-builds": "1.40.1", +>>>>>>> a977a6e22 (fix: upgrade ace-builds from 1.40.0 to 1.40.1) "axios-retry": "3.9.1", "bootstrap": "5.3.5", "classnames": "^2.5.1", From 84e155674567b7f51cba62aa45aba2d93228344a Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 20 May 2025 18:44:37 +1000 Subject: [PATCH 6/7] Fixed test --- .../Applications/NirsoftBrowserViewer.yaml | 6 +++--- .../testdata/server/testcases/verify.out.yaml | 20 +------------------ 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml b/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml index 25b4b506b6..5a0dbbba86 100644 --- a/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml +++ b/artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml @@ -38,9 +38,9 @@ parameters: default: LOCAL description: Default timezone for parsing timestamps -#implied_permissions: -# - EXECVE -# - FILESYSTEM_WRITE +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE sources: - precondition: diff --git a/artifacts/testdata/server/testcases/verify.out.yaml b/artifacts/testdata/server/testcases/verify.out.yaml index 0d170a66b1..eff4927e86 100644 --- a/artifacts/testdata/server/testcases/verify.out.yaml +++ b/artifacts/testdata/server/testcases/verify.out.yaml @@ -1,19 +1 @@ -SELECT count() AS Count , verify(artifact=name) AS V FROM artifact_definitions() WHERE type=~'client' AND built_in AND V.Warnings[ - { - "Count": 1, - "V": { - "Artifact": "Windows.Applications.NirsoftBrowserViewer", - "Permissions": [ - "EXECVE", - "FILESYSTEM_READ", - "FILESYSTEM_WRITE", - "MACHINE_STATE" - ], - "Errors": null, - "Warnings": [ - "\u003cyellow\u003eSuggestion\u003c/\u003e: Add EXECVE to artifact's required_permissions or implied_permissions fields", - "\u003cyellow\u003eSuggestion\u003c/\u003e: Add FILESYSTEM_WRITE to artifact's required_permissions or implied_permissions fields" - ] - } - } -] \ No newline at end of file +SELECT count() AS Count , verify(artifact=name) AS V FROM artifact_definitions() WHERE type=~'client' AND built_in AND V.Warnings[] \ No newline at end of file From 4bf2ccf0b669bba3ba8b9480addbe28092ced8bd Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 20 May 2025 21:28:42 +1000 Subject: [PATCH 7/7] Fix tests --- accessors/pst/cache.go | 4 +- accessors/pst/pst_accessor.go | 4 +- .../testdata/server/testcases/pst.out.yaml | 54 ++++++++++++++++++- vql/parsers/pst_parser.go | 4 +- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/accessors/pst/cache.go b/accessors/pst/cache.go index 1f326dbab6..0cd36db939 100644 --- a/accessors/pst/cache.go +++ b/accessors/pst/cache.go @@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package pst diff --git a/accessors/pst/pst_accessor.go b/accessors/pst/pst_accessor.go index 58336b12a1..8ea2134e9c 100644 --- a/accessors/pst/pst_accessor.go +++ b/accessors/pst/pst_accessor.go @@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package pst diff --git a/artifacts/testdata/server/testcases/pst.out.yaml b/artifacts/testdata/server/testcases/pst.out.yaml index cc19a42f38..eb51d7eb46 100644 --- a/artifacts/testdata/server/testcases/pst.out.yaml +++ b/artifacts/testdata/server/testcases/pst.out.yaml @@ -1 +1,53 @@ -SELECT * FROM Artifact.Windows.Forensics.Pst( PSTGlob=srcDir + "/artifacts/testdata/files/pst/Outlook.pst", AttachmentYaraRule=YaraRule, SubjectRegex="Multiple", PathRegex="Sent")[] \ No newline at end of file +SELECT * FROM Artifact.Windows.Forensics.Pst( PSTGlob=srcDir + "/artifacts/testdata/files/pst/Outlook.pst", AttachmentYaraRule=YaraRule, SubjectRegex="Multiple", PathRegex="Sent")[ + { + "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items", + "Sender": "saqib.razzaq@xp.local", + "Receiver": "", + "Subject": "\u0001\u0001Multiple attachments", + "Message": "This message contains multiple attachments\r\n\r\n \r\n\r\n", + "Delivered": "2011-06-21T23:51:00Z", + "Attachments": [ + { + "Name": "text file.txt", + "Size": 29, + "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33253" + }, + { + "Name": "Sunset.jpg", + "Size": 71189, + "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33285" + }, + { + "Name": "Blue hills.jpg", + "Size": 28521, + "Path": "ROOT_FOLDER/Top of Personal Folders/Sent Items/Msg-2097444/Att-33317" + } + ], + "Uploads": null, + "YaraHit": [ + { + "String": { + "Name": "$a", + "Offset": 3349, + "HexData": [ + "00000000 4a 50 45 47 |JPEG|", + "" + ], + "Data": "SlBFRw==" + } + }, + { + "String": { + "Name": "$a", + "Offset": 2377, + "HexData": [ + "00000000 4a 50 45 47 |JPEG|", + "" + ], + "Data": "SlBFRw==" + } + } + ], + "_Source": "Windows.Forensics.Pst" + } +] \ No newline at end of file diff --git a/vql/parsers/pst_parser.go b/vql/parsers/pst_parser.go index c2d71a56cd..0d0b48b4d3 100644 --- a/vql/parsers/pst_parser.go +++ b/vql/parsers/pst_parser.go @@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package parsers